forked from ph1p/i18next-scanner-webpack
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
119 lines (103 loc) · 3.71 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
const scanner = require('i18next-scanner');
const vfs = require('vinyl-fs');
const path = require('path');
const isModule = filePath => !path.isAbsolute(filePath) && !filePath.startsWith('/') && !filePath.startsWith('./');
const removeDuplicatedFromArray = arr => Array.from(new Set(arr).values());
class i18nextWebpackPlugin {
constructor(config) {
this.extensions = ['.js', '.jsx', '.vue'];
this.i18nConfig = config;
if (this.i18nConfig.options.func) {
if (!this.i18nConfig.options.func.list) {
this.i18nConfig.options.func.list = ['i18next.t', 'i18n.t'];
}
// Prevent "Unable to parse Trans component with the content" error
if (!this.i18nConfig.options.trans) {
this.i18nConfig.options.trans = {
component: 'Trans',
i18nKey: 'i18nKey',
defaultsKey: 'defaults',
extensions: ['.jsx'],
fallbackKey: false
};
}
if (this.i18nConfig.options.func.extensions) {
this.extensions = this.i18nConfig.options.func.extensions.slice();
} else {
this.i18nConfig.options.func.extensions = this.extensions.slice();
}
}
if (this.i18nConfig.options.attr) {
if (this.i18nConfig.options.attr.extensions) {
this.extensions = this.extensions.concat(this.i18nConfig.options.attr.extensions);
}
}
// Remove leading dot
this.extensions = this.extensions.map(ext => ext.replace(/^\./, ''));
if (!this.i18nConfig.options.resource) {
this.i18nConfig.options.resource = {
loadPath: '{{lng}}/{{ns}}.json',
savePath: '{{lng}}/{{ns}}.json'
};
}
}
apply(compiler) {
// entry
const entry = compiler.options.entry;
// check source directory
if (!this.i18nConfig.src) {
const entry = compiler.options.entry;
if (typeof entry === 'string') {
this.i18nConfig.src = [path.dirname(entry)];
} else if (typeof entry === 'object') {
// filter relative paths
let entries = [];
Object.keys(entry).forEach(e => {
const currentEntry = entry[e];
let paths = [];
if (Array.isArray(currentEntry)) {
paths = currentEntry.filter(e => !isModule(e)).map(e => path.dirname(e));
} else {
if (!isModule(currentEntry)) {
paths.push(path.dirname(currentEntry));
}
}
entries = entries.concat(paths);
});
this.i18nConfig.src = removeDuplicatedFromArray(entries);
}
}
// check dest directory
if (!this.i18nConfig.dest) {
this.i18nConfig.dest = path.join(__dirname.split('node_modules')[0], 'locales');
}
compiler.hooks.emit.tapAsync('i18nextWebpackPlugin', (compilation, callback) => {
if (!this.i18nConfig) {
console.error('i18next-scanner:', 'i18n object is missing');
return;
}
if (!this.i18nConfig.src || this.i18nConfig.src.length === 0) {
console.error('i18next-scanner:', 'src path is missing');
return;
}
if (!this.i18nConfig.dest) {
console.error('i18next-scanner:', 'dest path is missing');
return;
}
const commaSeperatedExtensions = this.extensions.map(ext => ext.replace(/^\./, '')).join(',');
vfs
.src(
this.i18nConfig.src.map(e =>
path.join(
e,
`**/*.${this.extensions.length === 1 ? commaSeperatedExtensions : `{${commaSeperatedExtensions}}`}`
)
)
)
.pipe(scanner(this.i18nConfig.options, this.i18nConfig.transform, this.i18nConfig.flush))
.pipe(vfs.dest(this.i18nConfig.dest))
.on('end', () => callback());
});
}
}
module.exports = i18nextWebpackPlugin;