-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
every translation in jsx incorrectly flagged as unused #34
Comments
Experiencing the same issue in my project. const { collectUnusedTranslations } = require('i18n-unused');
const { sync: globSync } = require('glob');
const dictionaries = globSync('./src/i18n/dictionaries/*.json', {realpath: true});
const sources = globSync('./src/**/*.+(tsx|ts|jsx|js|es6)', {realpath: true});
const handleTranslations = async () => {
const unusedTranslations = await collectUnusedTranslations(
dictionaries,
sources,
{}
);
return unusedTranslations;
}
handleTranslations().then(result => { console.log('unused:', result) }); |
Same to me but with .tsx |
I had this issue and mostly fixed it with the translationKeyMatcher config:
|
Seems like the default value for It's looking for I tried the one provided in the comment above - but, it struggles with several cases: When there isn't a closing bracket on the same line, they won't get recognisedt('myKey', {
someToken: 123
}) If the key used is dynamic, they aren't recognisedt(somePredicate ? 'keyTrue' : 'keyFalse') If keys are substrings of each other, they won't get flaggedFor example, given: {
"keyA": "x",
"keyAB": "x",
} And code of: t('keyAB') The tool won't flag that If other functions match the same structure, they are also capturede.g. matchViewport('someString') // matcher sees `t('someString')` here and marks it as a used key I've added a custom
Some gotchas to note as this is very basic...
I've also had to refactor some of my keys to support these gotchas: - t(predicate ? 'key1' : 'key2')
+ predicate ? t('key1') : t('key2') Making sure my keys aren't substrings - "myControl": "value",
+ "myControlLabel": "value",
"myControlTooltip": "tooltip", |
Having the exactly same issue in a React+TS project |
after a good chat with my friend chatGPT, we (they) came up with this: translationKeyMatcher:
// this regex was generated by chatGPT, and has the following features:
// * only match for `t()` and `tToDocLanguage()` calls
// * preceded by a space, opening parenthesis, or opening curly brace
// * also match for `i18nKey` prop in JSX
// * captures double quotes, single quotes, and backticks
// * works with optional chaining e.g. `t?.()`
// * works with multiline strings e.g. `t(\n"key")`
/(?<=[\s{(])(?:t|tToDocLanguage)\??\.?\(\s*["'`]?([\s\S]+?)["'`]?\s*\)|i18nKey="([\s\S]+?)"/g, we have a custom function used in the codebase, works really well for us, only downside is it doesn't match on dynamic strings (e.g. here's some test code to verify it works as expected for your use case: const regex = /(?<=[\s{(])(?:t|tToDocLanguage)\??\.?\(\s*["'`]?([\s\S]+?)["'`]?\s*\)|i18nKey="([\s\S]+?)"/g;
const text = `
t("1.basic.doublequotes.string")
t?.("2.basic.doublequotes.string.with.optional.chaining")
t('3.basic.singlequotes.string')
t?.('4.basic.singlequotes.string.with.optional.chaining')
t(\`5.basic.backtick.string\`)
t?.(\`6.basic.backtick.string.with.optional.chaining\`)
const multilineString = \`abc \${t(
"7.multiline.string",
)}\`;
tToDocLanguage("8.custom.func.beginning.with.t")
<Element i18nKey="9.i18nKey.string">
`;
const matches = [...text.matchAll(regex)];
const keys = matches.map(match => match[1] || match[2]);
// output each key on a new line
keys.forEach(key => console.log(key));
// outputs:
// '1.basic.doublequotes.string'
// '2.basic.doublequotes.string.with.optional.chaining'
// '3.basic.singlequotes.string'
// '4.basic.singlequotes.string.with.optional.chaining'
// '5.basic.backtick.string'
// '6.basic.backtick.string.with.optional.chaining'
// '7.multiline.string",'
// '8.custom.func.beginning.with.t'
// '9.i18nKey.string' hope that helps some folks! |
I've adjusted the regex a bit to also include /t\(\s*["'`]?([\s\S]+?)["'`]?\s*(?:\)|,)|i18nKey="([\s\S]+?)"/gi Now this would be matched correctly as well t(`translation.key`, { variable: x }) |
i18next-react project setup:
translation files
(reduced for brevity)
example file that uses translations
i have installed
i18n-unused
as dev dependency and runyarn i18n-unused display-unused
this prints almost all translations as unused. what i noticed is that it works with translations that are in javascript (like
useEffect
, or other pure javascript contexts), but it does not seem to work injsx
at all.The text was updated successfully, but these errors were encountered: