NextJS: next-translate and yaml loader - internationalization

Is it possible to use next-translate in combination with a YAML loader? For example, I'd like to use yaml-loader.
I tried it myself with no luck:
// file: next.config.js
const nextTranslate = require('next-translate')
module.exports = nextTranslate({
i18n: {
locales: ['en', 'es', 'it'],
defaultLocale: 'en'
},
loadLocaleFrom: (lang, ns) =>
require(`./locales/${lang}/${ns}`).then((m) => m.default),
webpack: function (config) {
config.module.rules.push({
test: /\.ya?ml$/,
use: 'yaml-loader'
})
return config
}
})
the previous next.config.js configuration throws the following error:
Module parse failed: Unexpected token (1:8)
File was processed with these loaders:
* ./node_modules/yaml-loader/index.js
You may need an additional loader to handle the result of these loaders.

These are the steps to use YAML files instead of JSON files with next-translate:
Install yaml-loader:
yarn add yaml-loader --dev
Configure webpack to use yaml-loader. This is my next.config.js file:
const nextTranslate = require('next-translate')
module.exports = nextTranslate({
webpack: function (config) {
config.module.rules.push({
test: /\.ya?ml$/,
type: 'json',
use: 'yaml-loader'
})
return config
}
})
Do not use i18n.json. Instead use i18n.js. In my case I have two pages: home (/) and teachers:
module.exports = {
locales: ['en', 'es', 'it'],
defaultLocale: 'en',
pages: {
'*': ['common'],
'/': ['home'],
'/teachers': ['teachers']
},
// Transform YAML files to JSON objects
loadLocaleFrom: (lang, ns) => {
return import(`./locales/${lang}/${ns}.yaml`).then((m) => m.default)
}
}
And that's all! You can now use the human-friendly YAML format, instead of the machine-friendly JSON format.

just like what #Cequiel described, the solution is using webpack config in the next.config.js, but I have compatibility issues while using yaml-loader(0.6.0) together with next.js (12.1.0 which defaultly using webpack 5), I used js-yaml-loader (^1.2.2) works well.

Related

How to combine withPlugins with internatioinalization config in a next.config.js file

I have the following code in my next.config.js
const withPlugins = require('next-compose-plugins');
const optimizedImages = require('next-optimized-images');
module.exports = withPlugins([optimizedImages], { target: 'serverless' });
and now I need to add the following config to the file, combining with the plugin
i18n: {
locales: ["en", "es"],
defaultLocale: "en",
},
I have tried the following,
const nextConfig = {
i18n: {
locales: ["en", "es"],
defaultLocale: "en",
},
};
module.exports = withPlugins([
[optimizedImages, {
target: 'serverless'
},
],
nextConfig,
])
and restarted the server, but I have not been successful ...
What version of Next.JS are you using? I faced the same problem and it was fixed by updating to +10.0.0.
You can see on the i18n documentation on Next that this is the minimum version.
Next.js has built-in support for internationalized (i18n) routing since v10.0.0. You can provide a list of locales, the default locale, and domain-specific locales and Next.js will automatically handle the routing.
More info: https://nextjs.org/docs/advanced-features/i18n-routing

Export my CSS vars with my module using rollup?

I have a little module that I am sharing across a few projects. It is successfully exporting components, but now I'd like to get my global style vars, like $contoso-primary: #ff0000 to be exported as well so we can start sharing CSS vars in my consuming app, like background-color: $contoso-primary. I'm using the rollup.js, is this possible with this library or with its plugins? If so, what plugin am I looking for? I've tried postcss already but doesn't appear to work unless I'm missing something.
export default {
input: 'src/index.js',
output: [
{
file: pkg.main,
format: 'cjs',
sourcemap: true
},
{
file: pkg.module,
format: 'es',
sourcemap: true
}
],
plugins: [
external(),
postcss({
extract: true
}),
url(),
svgr(),
babel({
exclude: 'node_modules/**'
}),
resolve(),
commonjs()
],
onwarn(warning, warn) {
if (
warning.code === 'CIRCULAR_DEPENDENCY'
&& warning.importer.indexOf('node_modules/semantic-ui-react') > -1
) return;
warn(warning);
}
};
my scss file that has my vars looks something like:
$primary: #177757,
$secondary: #D50000
and in the consuming project I'd like to refer to these in my scss files like:
.button {
background: $primary
}
I can't get an .css file into my dist folder, and the documenation on rollup-plugin-postcss is a little light.
postcss-simple-var this plugin will able to share sass like variables.
plugins: [
postcss({
plugins: [
simplevars()
],
extensions: [ '.css' ],
}),
...
]
for more information read this article.
I was able to make this work by duplicating the variable declarations in both the postcss.config.js and rollup.config.js
Rollup config:
import postcss from "rollup-plugin-postcss";
import postcssSimpleVars from "postcss-simple-vars";
const variables = require("./pathTo/variableConfig.js");
...
const config = {
...
plugins: [
postcss({
postcssSimpleVars({
variables: function () {
return variables;
}
}),
})
]
postCSS config:
const variables = require("./variableConfig.js");
plugins: [
...
require("postcss-simple-vars")({
variables: variables
})
]
variableConfig.js:
const baseDir = "../src/utils/constants";
const { COLORS } = require(`${baseDir}/colors`);
const { MQ } = require(`${baseDir}/mediaQueries`);
const { BREAKPOINTS } = require(`${baseDir}/breakpoints`);
const cssVars = Object.assign(COLORS, MQ, BREAKPOINTS);
module.exports = cssVars;

Laravel mix webpack - Ignore locales when importing Moment.js

I would like to load 2 locales en-gb and fr-ch only from Moment.js , then assign the moment class to the scopewindow to use the library everywhere in my Vuejs components.
Currently, my app.js has this require line:
window.moment = require('moment')
I am suspecting it can be accomplished thanks to the solutions here (adding IgnorePlugin and ContextReplacementPlugin to webpack.config.js):
plugins.push(new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /en-gb|fr-ch/))
module.exports.plugins = plugins;
OR
plugins.push(new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/))
module.exports.plugins = plugins;
Where should you add these pieces of code (webpack.config.js and/or app.js and/or webpack.mix.js) to ignore all other locales when importing momentjs?
mix.webpackConfig({
plugins: [
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
]
})
Source: https://laracasts.com/discuss/channels/elixir/laravel-mix-prevent-momentjs-locales
mix.webpackConfig( webpack => {
plugins: [
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
]
});
this way you dont have to import webpack on the top of your file, which sometimes can cause errors.
and you also can put other necessary options like this
mix.webpackConfig( webpack => {
plugins: [
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
],
resolve: {
extensions: ['.js', '.vue'],
alias: {
'#': __dirname + '/resources',
'#root': __dirname,
'#pages': __dirname + '/resources/js/pages'
},
fallback: { "path": false },
},
});

Configurable redirect URL in DocPad

I'm using DocPad to generate system documentation. I am including release notes in the format
http://example.com/releases/1.0
http://example.com/releases/1.1
http://example.com/releases/1.2
http://example.com/releases/1.3
I want to include a link which will redirect to the most recent release.
http://example.com/releases/latest
My question: how do I make a link that will redirect to a relative URL based on configuration? I want this to be easily changeable by a non-programmer.
Update: I've added cleanurls into my docpad.js, similar to example below. (see code below). But using "grunt docpad:generate" seems to skip making the redirect (is this an HTML page?). I've a static site. I also confirmed I'm using the latest cleanurls (2.8.1) in my package.json.
Here's my docpad.js
'use strict';
var releases = require('./releases.json'); // list them as a list, backwards: ["1.3", "1.2", "1.1", "1.0"]
var latestRelease = releases.slice(1,2)[0];
module.exports = {
outPath: 'epicenter/docs/',
templateData: {
site: {
swiftype: {
apiKey: 'XXXX',
resultsUrl: '/epicenter/docs/search.html'
},
ga: 'XXXX'
},
},
collections: {
public: function () {
return this.getCollection('documents').findAll({
relativeOutDirPath: /public.*/, isPage: true
});
}
},
plugins: {
cleanurls: {
simpleRedirects: {'/public/releases/latest': '/public/releases/' + latestRelease}
},
lunr: {
resultsTemplate: 'src/partials/teaser.html.eco',
indexes: {
myIndex: {
collection: 'public',
indexFields: [{
name: 'title',
boost: 10
}, {
name: 'body',
boost: 1
}]
}
}
}
}
};
When I run grunt docpad:generate, my pages get generated, but there is an error near the end:
/data/jenkins/workspace/stage-epicenter-docs/docs/docpad/node_modules/docpad-plugin-cleanurls/node_modules/taskgroup/node_modules/ambi/es6/lib/ambi.js:5
export default function ambi (method, ...args) {
^^^^^^
I can't tell if that's the issue preventing this from running but it seems suspicious.
Providing that your configuration is available to the DocPad Configuration File, you can use the redirect abilities of the cleanurls plugin to accomplish this for both dynamic and static environments.
With a docpad.coffee configuration file, it would look something like this:
releases = require('./releases.json') # ['1.0', '1.1', '1.2', '1.3']
latestRelease = releases.slice(-1)[0]
docpadConfig =
plugins:
cleanurls:
simpleRedirects:
'/releases/latest': '/releases/' + latestRelease
module.exports = docpadConfig

How to test browserify project using karma/jasmine

I'm totally new to the concept of testing, and i need one solid example on how to do it in my project:
I have a gulp file goes like this (Not all of it, just the important portions)
gulp.task('bundle', function() {
gulp.src('public/angular-app/main.js')
.pipe(browserify({
debug: true
}))
.pipe(gulp.dest('public/min-js'));
});
This is a slight portion of my main.js:
'use strict';
angular.module('myApp', [
'ui.router',
'ui.bootstrap',
'ngSanitize',
'ngFx',
...
], ['$interpolateProvider',
function($interpolateProvider) {
$interpolateProvider.startSymbol('{{');
$interpolateProvider.endSymbol('}}');
}
])
.config(require('./config/routes'))
.config(require('./config/authInterceptor'))
.run(require('./config/runPhase'))
.run(require('./config/xeditable'))
.controller('homeController', require('./controllers/homeController'))
.controller('modalInstanceCtrl', require('./controllers/modalInstanceCtrl'))
.controller('modalparticipantCtrl',require('./controllers/modalParticipantCtrl'))
.controller('generatorController',require('./controllers/generatorController'))
.controller('navController', require('./controllers/navController'))
.controller('signInController', require('./controllers/signInController'))
.controller('pricingController', require('./controllers/pricingController'))
.controller('howItWorksController',require('./controllers/howItWorks'))
...
Now this is my config file for karma:
module.exports = function(config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['jasmine'],
// list of files / patterns to load in the browser
files: [
'public/vendor/jquery/dist/jquery.js',
'public/vendor/angular/angular.js',
'public/vendor/angular-mocks/angular-mocks.js',
'public/angular-app/**/*.js',
'test/**/*Spec.js'
],
// list of files to exclude
exclude: [
],
When i run karma with karma start this is what i get:
Uncaught reference error:require is not defined
at root/public/angular-app/main.js
So my question is simple, how can i do tests, for example, on my homeController...
//update
So I updated my test file to this:
describe("An Angularjs test suite",function(){
var target, rootScope;
beforeEach(inject(function($rootScope) {
rootScope = $rootScope;
// Mock everything here
spyOn(rootScope, "$on")
}));
beforeEach(inject(function(homeController) {
target = homeController;
}));
it('should have called rootScope.$on', function(){
expect(rootScope.$on).toHaveBeenCalled();
});
});
and my config file to this:
// list of files / patterns to load in the browser
files: [
'public/vendor/jquery/dist/jquery.js',
'public/vendor/angular/angular.js',
'public/vendor/angular-mocks/angular-mocks.js',
'public/min-js/main.js',
'test/**/*Spec.js'
],
// list of files to exclude
exclude: [
],
browserify: {
watch: true,
debug: true
},
preprocessors: {
'test/*': ['browserify']
},
Still nothing works, first he says 'unknown provider homeControllerProvider',
Now if i delete them lines:
beforeEach(inject(function(homeController) {
target = homeController;
}));
it still gives me error, expected spy $on to be called, How do i fix this?
You need to inform Karma to run Browserify before running tests.
You can add this in your Karma config:
{
browserify: {
watch: true,
debug: true
},
preprocessors: {
'test/*': ['browserify']
}
}
Karma config file reference: http://karma-runner.github.io/0.12/config/configuration-file.html
Or have a look at one of of my projects that uses Karma for testing: smild.

Resources