Skip to content

Commit 138825a

Browse files
yocarbocheton
andauthored
feat(parser): Add exception for removing unused keys (#262)
* feat(parser): Add exception filter for removing unused keys * refactor: allow the `removeUnusedKeys` function to be passed in to determine if an unused key should be removed * chore: bump to 4.6.0 * test: enhance test case for the `removeUnusedKeys` option --------- Co-authored-by: cheton <cheton@gmail.com>
1 parent f720314 commit 138825a

File tree

4 files changed

+54
-13
lines changed

4 files changed

+54
-13
lines changed

README.md

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -570,9 +570,30 @@ Set to `true` to turn on debug output.
570570

571571
#### removeUnusedKeys
572572

573-
Type: `Boolean` Default: `false`
573+
Type: `Boolean` or `Function` Default: `false`
574+
575+
Set to `true` to remove unused translation keys from i18n resource files. By default, this is set to `false`.
576+
```js
577+
{ // Default
578+
removeUnusedKeys: false,
579+
}
580+
```
574581

575-
Set to `true` to remove unused translation keys from i18n resource files.
582+
If a function is provided, it will be used to decide whether an unused translation key should be removed.
583+
```js
584+
// Available since 4.6.0
585+
//
586+
// @param {string} lng The language of the unused translation key.
587+
// @param {string} ns The namespace of the unused translation key.
588+
// @param {array} key The translation key in its array form.
589+
// @return {boolean} Returns true if the unused translation key should be removed.
590+
removeUnusedKeys: function(lng, ns, key) {
591+
if (ns === 'resource') {
592+
return true;
593+
}
594+
return false;
595+
}
596+
```
576597

577598
#### sort
578599

@@ -594,7 +615,7 @@ If an `Object` is supplied, you can either specify a list of attributes and exte
594615
}
595616
```
596617

597-
You can set attr to `false` to disable parsing attribute as below:
618+
You can set `attr` to `false` to disable parsing attribute as below:
598619
```js
599620
{
600621
attr: false
@@ -615,7 +636,7 @@ If an `Object` is supplied, you can either specify a list of translation functio
615636
}
616637
```
617638

618-
You can set func to `false` to disable parsing translation function as below:
639+
You can set `func` to `false` to disable parsing translation function as below:
619640
```js
620641
{
621642
func: false
@@ -649,14 +670,14 @@ If an `Object` is supplied, you can specify a list of extensions, or override th
649670
}
650671
```
651672

652-
You can set trans to `false` to disable parsing Trans component as below:
673+
You can set `trans` to `false` to disable parsing Trans component as below:
653674
```js
654675
{
655676
trans: false
656677
}
657678
```
658679

659-
The fallbackKey can either be a boolean value, or a function like so:
680+
The `fallbackKey` can either be a boolean value, or a function like so:
660681
```js
661682
fallbackKey: function(ns, value) {
662683
// Returns a hash value as the fallback key

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "i18next-scanner",
3-
"version": "4.5.0",
3+
"version": "4.6.0",
44
"description": "Scan your code, extract translation keys/values, and merge them into i18n resource files.",
55
"homepage": "https://github.com/i18next/i18next-scanner",
66
"author": "Cheton Wu <cheton@gmail.com>",

src/parser.js

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -786,7 +786,7 @@ class Parser {
786786
}
787787

788788
let resStore = {};
789-
if (this.options.removeUnusedKeys) {
789+
if (!!this.options.removeUnusedKeys) {
790790
// Merge two objects `resStore` and `resScan` deeply, returning a new merged object with the elements from both `resStore` and `resScan`.
791791
const overwriteMerge = (destinationArray, sourceArray, options) => sourceArray;
792792
const resMerged = deepMerge(this.resStore, this.resScan, { arrayMerge: overwriteMerge });
@@ -798,8 +798,15 @@ class Parser {
798798
const unusedKeys = _.differenceWith(resStoreKeys, resScanKeys, _.isEqual);
799799

800800
for (let i = 0; i < unusedKeys.length; ++i) {
801-
_.unset(resMerged[lng][ns], unusedKeys[i]);
802-
this.log(`Removed an unused translation key { ${chalk.red(JSON.stringify(unusedKeys[i]))} from ${chalk.red(JSON.stringify(this.formatResourceLoadPath(lng, ns)))}`);
801+
const unusedKey = unusedKeys[i];
802+
const isRemovable = (typeof this.options.removeUnusedKeys === 'function')
803+
? this.options.removeUnusedKeys(lng, ns, unusedKey)
804+
: !!this.options.removeUnusedKeys;
805+
806+
if (isRemovable) {
807+
_.unset(resMerged[lng][ns], unusedKey);
808+
this.log(`Removed an unused translation key { ${chalk.red(JSON.stringify(unusedKey))} } from ${chalk.red(JSON.stringify(this.formatResourceLoadPath(lng, ns)))}`);
809+
}
803810
}
804811

805812
// Omit empty object

test/transform-stream.test.js

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,12 @@ test('Keep old translations', done => {
402402
// https://github.com/i18next/i18next-scanner/issues/30
403403
test('Remove old translation keys which are already removed from code', done => {
404404
const options = _.merge({}, defaults, {
405-
removeUnusedKeys: true,
405+
removeUnusedKeys: function(lng, ns, key) {
406+
if (ns === 'resource') {
407+
return true;
408+
}
409+
return false;
410+
},
406411
resource: {
407412
loadPath: 'test/fixtures/i18n/{{lng}}/{{ns}}.json',
408413
savePath: 'i18n/{{lng}}/{{ns}}.json'
@@ -420,7 +425,11 @@ test('Remove old translation keys which are already removed from code', done =>
420425
// English - locale.json
421426
if (file.path === 'i18n/en/locale.json') {
422427
const found = JSON.parse(contents);
423-
const wanted = {};
428+
const wanted = {
429+
'language': {
430+
'en-US': 'English',
431+
},
432+
};
424433
expect(found).toEqual(wanted);
425434
}
426435

@@ -441,7 +450,11 @@ test('Remove old translation keys which are already removed from code', done =>
441450
// German - locale.json
442451
if (file.path === 'i18n/de/locale.json') {
443452
const found = JSON.parse(contents);
444-
const wanted = {};
453+
const wanted = {
454+
'language': {
455+
'de-DE': 'German',
456+
},
457+
};
445458
expect(found).toEqual(wanted);
446459
}
447460

0 commit comments

Comments
 (0)