i18n-unused
![npm](https://img.shields.io/npm/dt/i18n-unused?color=green&link=https://www.npmjs.com/package/i18n-unused)
The static analyze tool for finding, marking and removing unused and missing i18n translations in your JavaScript project.
Installation
With npm:
npm install --save-dev i18n-unused
With yarn:
yarn add --dev i18n-unused
Configuration
Add config i18n-unused.config.js
to your root folder:
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.
Configuration options
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 |
Usage
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
Usage in code
collectUnusedTranslations
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,
srcFilesPaths,
{
localeFileParser: (module) => module,
excludeTranslationKey: ['.props.'],
},
);
};
It'll return to you follow collect:
{
translations: [
{
localePath: 'locale_file_path',
keys: ['unused_key'],
count: 1,
},
],
totalCount: 1,
}
collectMissedTranslations
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,
srcFilesPaths,
{
localeFileParser: (module) => module,
excludeTranslationKey: ['.props.'],
translationKeyMatcher: /(?:[$ .](_|t|tc))\(.*?\)/ig,
},
);
};
You'll get the following collection:
{
translations: [
{
filePath: 'src_file_path',
staticKeys: ['missed_key'],
dynamicKeys: ['missed_key'],
staticCount: 1,
dynamicCount: 1,
},
],
totalStaticCount: 1,
totalDynamicCount: 1,
}
generateFilesPaths
Available as async function generateFilesPaths
:
import { generateFilesPaths } from 'i18n-unused';
const handleFilesPaths = async () => {
const filesPaths = await generateFilesPaths(
srcPath,
{
srcExtensions,
fileNameResolver,
},
);
};
Action results
Next actions return unusedTranslations
:
displayUnusedTranslations
removeUnusedTranslations
markUnusedTranslations
Next actions return missedTranslations
:
displayMissedTranslations
What else?
If the tool helped you, please rate it on github, thx. I'll be glad to your PRs =)
License
MIT License. Maxim Vishnevsky