Skip to content

Commit 5302b06

Browse files
committed
feat: Add support for watching multiple locales dirs, #116
1 parent fc07436 commit 5302b06

File tree

5 files changed

+36
-16
lines changed

5 files changed

+36
-16
lines changed

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@ module.exports = {
3131
...
3232
plugins: [
3333
new I18NextHMRPlugin({
34-
localesDir: path.resolve(__dirname, 'static/locales'),
34+
localesDir: path.resolve(__dirname, 'static/locales'),
35+
localesDirs: [
36+
// use this property for multiple locales directories
37+
]
3538
})
3639
]
3740
};

__tests__/loader.spec.js

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,10 @@ const loader = require('../lib/loader');
22

33
describe('loader', () => {
44
let context;
5-
const options = {
6-
lang: 'en',
7-
ns: 'namespace',
8-
};
5+
const options = ['en/namespace'];
96
const query = {
107
getChangedLang: jest.fn().mockImplementation(() => options),
11-
localesDir: 'locals-dir',
8+
localesDirs: ['locals-dir'],
129
};
1310
const content = `module.exports = '__PLACEHOLDER__';`;
1411

@@ -21,7 +18,16 @@ describe('loader', () => {
2118

2219
it('should add localesDir as context dependency', () => {
2320
loader.apply(context, [content]);
24-
expect(context.addContextDependency).toHaveBeenCalledWith(query.localesDir);
21+
expect(context.addContextDependency).toHaveBeenCalledWith(query.localesDirs[0]);
22+
});
23+
24+
it('should add all locale dirs as context dependency', () => {
25+
query.localesDirs = ['folder1', 'folder2'];
26+
loader.apply(context, [content]);
27+
28+
expect(context.addContextDependency).toHaveBeenCalledTimes(query.localesDirs.length);
29+
expect(context.addContextDependency).toHaveBeenCalledWith(query.localesDirs[0]);
30+
expect(context.addContextDependency).toHaveBeenCalledWith(query.localesDirs[1]);
2531
});
2632

2733
it('should inject an object', () => {

lib/loader.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
module.exports = function (content) {
2-
this.addContextDependency(this.query.localesDir);
2+
this.query.localesDirs.forEach((dir) => this.addContextDependency(dir));
33
return (
44
content.replace(`'__PLACEHOLDER__'`, JSON.stringify(this.query.getChangedLang())) +
55
'//' +

lib/plugin.js

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,15 @@ const pluginName = 'I18nextHMRPlugin';
55

66
const DEFAULT_OPTIONS = {
77
localesDir: '',
8+
localesDirs: [],
89
};
910

1011
class I18nextHMRPlugin {
1112
constructor(options) {
1213
this.options = { ...DEFAULT_OPTIONS, ...options };
14+
this.options.localesDirs = []
15+
.concat(this.options.localesDirs, this.options.localesDir)
16+
.filter(Boolean);
1317
this.lastUpdate = { changedFiles: [] };
1418
}
1519

@@ -19,10 +23,16 @@ class I18nextHMRPlugin {
1923
: false;
2024

2125
compiler.hooks.beforeCompile.tapAsync(pluginName, (params, callback) => {
22-
if (fs.existsSync(this.options.localesDir)) {
26+
const noneExistsDirs = this.options.localesDirs.filter((dir) => !fs.existsSync(dir));
27+
28+
if (noneExistsDirs.length === 0) {
2329
return callback();
2430
}
25-
throw new Error(`i18next-hmr: '${this.options.localesDir}' not found`);
31+
throw new Error(
32+
`i18next-hmr: \n'${noneExistsDirs.join(`',\n'`)}'${
33+
noneExistsDirs.length > 1 ? '\nare' : ''
34+
} not found`
35+
);
2636
});
2737

2838
compiler.hooks.watchRun.tap(pluginName, (compiler) => {
@@ -35,7 +45,9 @@ class I18nextHMRPlugin {
3545
const fileExt = path.extname(file);
3646

3747
return (
38-
file.includes(this.options.localesDir) && !!fileExt && changedTimes[file] > startTime
48+
this.options.localesDirs.some((dir) => file.startsWith(dir)) &&
49+
!!fileExt &&
50+
changedTimes[file] > startTime
3951
);
4052
});
4153

@@ -45,10 +57,9 @@ class I18nextHMRPlugin {
4557

4658
const changedFiles = files.map((file) => {
4759
const fileExt = path.extname(file);
60+
const dir = this.options.localesDirs.find((dir) => file.startsWith(dir));
4861

49-
return path
50-
.relative(this.options.localesDir, file)
51-
.slice(0, -1 * fileExt.length || undefined); // keep all when fileExt.length === 0
62+
return path.relative(dir, file).slice(0, -1 * fileExt.length || undefined); // keep all when fileExt.length === 0
5263
});
5364

5465
this.lastUpdate = { changedFiles };
@@ -66,7 +77,7 @@ class I18nextHMRPlugin {
6677
module.loaders.push({
6778
loader: path.resolve(__dirname, 'loader.js'), // Path to loader
6879
options: {
69-
localesDir: this.options.localesDir,
80+
localesDirs: this.options.localesDirs,
7081
getChangedLang: () => ({ ...this.lastUpdate }),
7182
},
7283
});

plugin.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
export class I18NextHMRPlugin {
22
static addListener(cb: (data: { lang: string; ns: string }) => void): void;
33

4-
constructor(options: { localesDir: string });
4+
constructor(options: { localesDir: string; localesDirs: string[] });
55
}

0 commit comments

Comments
 (0)