The static analyze tool for finding, marking and removing unused and missing i18n translations in your JavaScript project.
With npm:
npm install --save-dev i18n-unused
With yarn:
yarn add --dev i18n-unused
Add config i18n-unused.config.js
to your root folder:
/** @type {import('i18n-unused').RunOptions} */
module.exports = {
localesPath: 'src/locales',
srcPath: 'src',
};
For ES-Modules (esm) use i18n-unused.config.cjs
. You can also use the .json
with no support for callbacks.
Option name | Description |
Required | Type | Default value |
---|---|---|---|---|
localesPath | path to search for locales | yes | string | - |
localesExtensions | allowed file extensions for locales | no | string[] | if not set localeNameResolver : ['json'] |
localeNameResolver | file name resolver for locales | no | RegExp, (name: string) => boolean | - |
customChecker | function to check if a key is used, if so the key should be removed from translationsKeys | no | fn, (matchedKeys: Set<string>, translationsKeys: string[] => void) | A defined validations will be applied |
localeFileParser | resolve locale imports, for example if you use named imports from locales files, just wrap it to your own resolver | no | (module) => module | fn, return module.default or module |
localeFileLoader | load the locale file manually (e.g. for using your own parser) | no | (filePath) => object | - |
srcPath | path to search for translations | no | string | '' (same as run folder) |
srcExtensions | allowed file extensions for translations | no | string[] | ['js', 'ts', 'jsx', 'tsx', 'vue'] |
ignorePaths | ignored paths, eg: ['src/ignored-folder'] , should start similarly srcPath |
no | string[] | - |
translationKeyMatcher | matcher to search for translation keys in files | no | RegExp | RegExp, match $_ , $t , t , $tc , tc and i18nKey |
excludeKey | doesn't process translations that include passed key(s), for example if you set excludeKey: '.props.' , script will ignore Button.props.value . |
no | string, string[] | - |
ignoreComments | Ignore code comments in src files. | no | boolean | false |
marker | special string to mark unused translations, it'll added via mark-unused |
no | string | '[UNUSED]' |
gitCheck | show git state change tree | no | boolean | false |
context | use i18n context, (eg: plurals) | no | boolean | true |
flatTranslations | use flat translations, (eg: Flat JSON) | no | boolean | false |
translationSeparator | separator for translations using in code | no | string | '.' |
translationContextSeparator | separator for i18n context (see context option) |
no | string | '_' |
translationContextMatcher | matcher to search for context endings | no | RegExp | RegExp, match zero , one , two , few , many , other , male , female , 0 , 1 , 2 , 3 , 4 , 5 , plural , 11 and 100 |
missedTranslationParser | parser for ejecting value from translationKeyMatcher matches |
no | RegExp, (v: string) => string | RegExp, match value inside rounded brackets |
localeJsonStringifyIndent | json indent value for writing json file, either a number of spaces, or a string to indent with. (i.e. 2 , 4 , \t ) |
no | string , number | 2 |
Get help:
i18n-unused -h
Display unused translations:
i18n-unused display-unused
Display unused translations for mashpie/i18n-node:
i18n-unused display-unused --translation-key-matcher '/(?:[$ .](__))\(.*?\)/gi'
Mark unused translations via [UNUSED]
or marker from config (works only with json
for now):
i18n-unused mark-unused
Remove unused translations (works only with json
for now):
i18n-unused remove-unused
Sync translations (works only with json
for now):
i18n-unused sync <source> <target>
Display missed translations:
i18n-unused display-missed
If you use tool in code, you can run async function collectUnusedTranslations
:
import { collectUnusedTranslations } from 'i18n-unused';
const handleTranslations = async () => {
const unusedTranslations = await collectUnusedTranslations(
localesPaths, // paths to locale files
srcFilesPaths, // paths to src files
{
localeFileParser: (module) => module, // optional, resolver for module
excludeTranslationKey: ['.props.'], // optional, special string or sting[] to exclude flat translations
},
);
};
It'll return to you follow collect:
{
translations: [
{
localePath: 'locale_file_path',
keys: ['unused_key'],
count: 1,
},
],
totalCount: 1,
}
If you use tool in code, you can run async function collectMissedTranslations
:
import { collectMissedTranslations } from 'i18n-unused';
const handleTranslations = async () => {
const missedTranslations = await collectMissedTranslations(
localesPaths, // paths to locale files
srcFilesPaths, // paths to src files
{
localeFileParser: (module) => module, // optional, resolver for module
excludeTranslationKey: ['.props.'], // optional, special string or sting[] to exclude flat translations
translationKeyMatcher: /(?:[$ .](_|t|tc))\(.*?\)/ig, // optional, match translation keys in files
},
);
};
You'll get the following collection:
{
translations: [
{
filePath: 'src_file_path',
staticKeys: ['missed_key'], // keys without ${} syntax
dynamicKeys: ['missed_key'], // keys with ${} syntax
staticCount: 1,
dynamicCount: 1,
},
],
totalStaticCount: 1,
totalDynamicCount: 1,
}
Available as async function generateFilesPaths
:
import { generateFilesPaths } from 'i18n-unused';
const handleFilesPaths = async () => {
// return array of full paths to files
const filesPaths = await generateFilesPaths(
srcPath, // path where search files, example: 'src/locales'
{
srcExtensions, // allowed file extensions, example: ['js', 'ts']
fileNameResolver, // resolver for file name, see more info about 'localeNameResolver' option
},
);
};
Next actions return unusedTranslations
:
displayUnusedTranslations
removeUnusedTranslations
markUnusedTranslations
Next actions return missedTranslations
:
displayMissedTranslations
If the tool helped you, please rate it on github, thx. I'll be glad to your PRs =)
MIT License. Maxim Vishnevsky