
Security News
TypeScript is Porting Its Compiler to Go for 10x Faster Builds
TypeScript is porting its compiler to Go, delivering 10x faster builds, lower memory usage, and improved editor performance for a smoother developer experience.
@gaia-law/i18n-modules
Advanced tools
Modular approach for i18n in Webpack, similar to CSS Modules
CSS Modules for i18n. A webpack plugin that brings support for a modular approach to dictionaries. Especially useful for tools such as Phraseapp. Pairs well with react-polyglot.
In your webpack config:
const I18nModules = require('@gaia-law/i18n-modules');
//...
plugins: [
new I18nModules(),
],
Create an options RC file in your project's root named .i18n-modules-rc.js
with this example content:
module.exports = {
// Optional, your keys will be relative to this folder, usually `./app` or `./client`.
// Path must be either absolute or relative to the process.cwd() or `context` option passed to webpack.
keysRoot: './',
// Optional, how you will be naming your translation modules,
// similar to name.module.css, or in this case name.translations.json
moduleEnding: '.translations.json',
// Usually the same as the location in phraseapp.yml - the path to your dictionary folder or files
// where [locale_code] is to be replaced with the language name.
// Path must be either absolute or relative to the process.cwd() or `context` option passed to webpack.
// Sync binary also uses this option to locate dictionaries.
dictionaryPattern: './dictionaries/[locale_code].json',
// Optional, signals that the original dictionary is to be updated at the end of modules bundling, defaults to `true`.
// Set this to `false` when you don't need to update the original dictionary
// and only wish to use bundled translations, for example for SSR bundle build.
emitFile: true,
// Optional, a function to customize how unique module IDs are generated
// Arguments are:
// keysRoot: string, same as above but rebased to be absolute
// moduleEnding: string, same as above
// filePath: string, an absolute path to the translations module file
// Must return a stable unique string
getId: (keysRoot, moduleEnding, filePath) => idString,
// Optional, an object to customize the format dictionarys are kept in
// Defaults to JSON representation
dictionaryAdapter: {
parse: (buffer) => someObj,
stringify: (obj) => someStr,
}
};
If you don't expect to use the CLI (see below), then instead of creating an RC file you can simply pass an options object as an argument to the plugin. Passed options will be merged with those in the RC file if present and the defaults. This way you can also override RC options by passing extra options directly.
In case you don't need to bundle or update original dictionaries and only need the part that remaps module paths, you can use the module loader directly. In webpack config use it as any other loader:
const { loader: i18nLoader } = require('@gaia-law/i18n-modules');
//...
module: {
rules: [
{
test: /\.translations\.json/,
use: [{
loader: i18nLoader,
options: {
// keysRoot, moduleEnding, getId: same as for the plugin
},
}],
},
]
}
Create a translations module myfile.translations.json
:
{
"de-DE": {
"content": {
"totally": {
"necessary": {
"nesting": "Majestätischer Inhalt"
}
}
},
"title": "Unglaublicher Titel"
},
"en-US": {
"content": {
"totally": {
"necessary": {
"nesting": "Majestic content"
}
}
},
"title": "Amazing title"
}
}
You need to pay attention to the language names in your modules, the plugin only validates that they match a certain pattern, but not the values.
Import translations:
import lang from './myfile.translations';
// Instead of string paths use object lookup
t(lang.title);
// Nesting is fully supported
t(lang.content.totally.necessary.nesting);
When importing your translation modules all of the values will be remapped to lookup strings for your main dictionary.
Load your main dictionary like usual:
import dictionary from '../dictionaries/de-DE';
// Pass the dictionary to your translations library, e.g. i18n-polyglot.
The dictionary will contain it's original content and the generated modules.
keysRoot
(optional) - the keys will be generated relative to this folder. Use this to make generated keys shorter by excluding static parts of the path, e.g. if all your translations are in ./frontend/app/components
pass that as the keysRoot
. Defaults to './'
.moduleEnding
(optional) - the ending that will be used for the translation modules. You can't use :
symbol in file names for these files. It's an OS limitation for MacOS and Windows anyway, but *nix users should be aware. Defaults to '.translations.json'
dictionaryPattern
(required) - the path to your dictionary folder or files. Use [locale_code]
placeholder to get current language name injected into the file name. Try not to name your dictionaries in such a way where part of the name might be confused for a language name. For example this might break the build ./dicts/gr-EAT.[locale_code].json
emitFile
(optional) - determines if the bundled dictionary needs to also be stored on the disk. Set to false
when you prefer to use @gaia-law/i18n-modules
binary to update original dictionaries or don't intend to store module build results anywhere. Defaults to true
.This package comes with a CLI because you might need a way to sync updates from Phraseapp or translations hosting service back into your modules and a simple way to build all languages from modules at once. To use this CLI you must create an RC configuration file.
npx @gaia-law/i18n-modules build
will build all dictionaries from modulesnpx @gaia-law/i18n-modules update
will update all modules from dictionaries. This will not create any new module files from dictionary as this is likely a result of a typo.npx @gaia-law/i18n-modules clean
will remove all generated modules from dictionariesWe support I18N_MODULES_CONTEXT
env variable to set current working directory to something else. It works similarly to webpack's context
option. When set both plugin and @gaia-law/i18n-modules
binary will look for the RC file relative to that context folder. In addition when running the @gaia-law/i18n-modules
binary all relative file paths in the RC file will be relative to that context. I18N_MODULES_CONTEXT
itself accepts paths relative to current working directory, e.g. one could set I18N_MODULES_CONTEXT=./frontend/app
and it would work.
npx @gaia-law/i18n-modules build && phraseapp push
will push all generated modules to phraseappphraseapp pull && npx @gaia-law/i18n-modules update
will update all modules with changes from phraseappi18n-modules
is also added to your npm env. You could add this to your package.json:
"scripts": {
"lang:push": "i18n-modules build && phraseapp push",
"lang:pull": "phraseapp pull && i18n-modules update",
"lang:clean": "i18n-modules clean",
"lang:sync": "npm run lang:push && npm run lang:pull",
}
NextJS builds in dev mode incrementally. That means with default config you will always have merge conflicts in the dictionaries folder. To avoid this only emit full dictionaries during full build.
This is an example implementation of next.config.js
that achieves this:
const { PHASE_DEVELOPMENT_SERVER } = require('next/constants');
const I18nModules = require('@gaia-law/i18n-modules');
const getConfig = (phase) => {
const nextConfig = {
webpack: (config) => {
config.plugins.push(
new I18nModules({ emitFile: phase !== PHASE_DEVELOPMENT_SERVER }),
);
return config;
},
};
return nextConfig;
};
module.exports = getConfig;
This module uses debug internally with label i18n_modules
. To debug use DEBUG=i18n_modules in your env: DEBUG=i18n_modules npx webpack
.
FAQs
Modular approach for i18n in Webpack, similar to CSS Modules
The npm package @gaia-law/i18n-modules receives a total of 0 weekly downloads. As such, @gaia-law/i18n-modules popularity was classified as not popular.
We found that @gaia-law/i18n-modules demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
TypeScript is porting its compiler to Go, delivering 10x faster builds, lower memory usage, and improved editor performance for a smoother developer experience.
Research
Security News
The Socket Research Team has discovered six new malicious npm packages linked to North Korea’s Lazarus Group, designed to steal credentials and deploy backdoors.
Security News
Socket CEO Feross Aboukhadijeh discusses the open web, open source security, and how Socket tackles software supply chain attacks on The Pair Program podcast.