vue-i18n-extract-plugin 1.0.56 → 1.0.57
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/lib/options.js +1 -0
- package/lib/visitors.js +34 -12
- package/lib/vite-plugin-i18n.js +56 -32
- package/lib/vite-plugin-import-i18n.js +12 -33
- package/package.json +1 -1
- package/types/vite-plugin-i18n.d.ts +2 -0
package/README.md
CHANGED
|
@@ -55,6 +55,7 @@ const defaultOptions = {
|
|
|
55
55
|
autoTranslate: true, // 提取完成后是否自动翻译
|
|
56
56
|
cleanTranslate: true, // 是否清理无用的翻译内容
|
|
57
57
|
keepRaw: false, // 开启后只做转换不生成hash值,即:"测试" -> $t("测试"), 开启rewrite时生效
|
|
58
|
+
keepDefaultMsg: false, // 保留默认消息,即:"测试" -> $t("hashedKey", "测试")
|
|
58
59
|
enabled: true, // 是否启用插件
|
|
59
60
|
outputJsonFileInPlugin: true, // 是否在插件中输出 JSON 文件
|
|
60
61
|
outputJsonFileDebounceTimeInPlugin: 2000, // 输出 JSON 文件的防抖时间
|
package/lib/options.js
CHANGED
|
@@ -9,6 +9,7 @@ const defaultOptions = {
|
|
|
9
9
|
autoTranslate: true, // 提取完成后是否自动翻译
|
|
10
10
|
cleanTranslate: true, // 是否清理无用的翻译内容
|
|
11
11
|
keepRaw: false, // 开启后只做转换不生成hash值,即:"测试" -> $t("测试"), 开启rewrite时生效
|
|
12
|
+
keepDefaultMsg: false, // 保留默认消息,即:"测试" -> $t("hashedKey", "测试")
|
|
12
13
|
enabled: true, // 是否启用插件
|
|
13
14
|
outputJsonFileInPlugin: true, // 是否在插件中输出 JSON 文件
|
|
14
15
|
outputJsonFileDebounceTimeInPlugin: 2000, // 输出 JSON 文件的防抖时间
|
package/lib/visitors.js
CHANGED
|
@@ -168,6 +168,10 @@ function createI18nVisitor(option, i18nMap) {
|
|
|
168
168
|
|
|
169
169
|
const newArg = t.stringLiteral(generateText(keyText, hashed, option));
|
|
170
170
|
path.node.arguments[0] = newArg;
|
|
171
|
+
|
|
172
|
+
if (option.keepDefaultMsg) {
|
|
173
|
+
path.node.arguments.push(t.stringLiteral(keyText));
|
|
174
|
+
}
|
|
171
175
|
},
|
|
172
176
|
|
|
173
177
|
StringLiteral(path) {
|
|
@@ -227,7 +231,10 @@ function createI18nVisitor(option, i18nMap) {
|
|
|
227
231
|
t.identifier("_ctx"),
|
|
228
232
|
t.identifier(option.translateKey)
|
|
229
233
|
),
|
|
230
|
-
[
|
|
234
|
+
[
|
|
235
|
+
t.stringLiteral(generateText(value, hashed, option)),
|
|
236
|
+
option.keepDefaultMsg ? t.stringLiteral(value) : null
|
|
237
|
+
].filter(Boolean)
|
|
231
238
|
);
|
|
232
239
|
|
|
233
240
|
// 判断是否createTextVNode或MemberExpression(如 Vue.createTextVNode)
|
|
@@ -253,9 +260,13 @@ function createI18nVisitor(option, i18nMap) {
|
|
|
253
260
|
const hasCreateVNode = transformDirectiveIfNeeded(path, parentPath);
|
|
254
261
|
if (!hasCreateVNode) {
|
|
255
262
|
// 生成 $t("hashed")
|
|
256
|
-
callExpression = t.callExpression(
|
|
257
|
-
t.
|
|
258
|
-
|
|
263
|
+
callExpression = t.callExpression(
|
|
264
|
+
t.identifier(option.translateKey),
|
|
265
|
+
[
|
|
266
|
+
t.stringLiteral(generateText(value, hashed, option)),
|
|
267
|
+
option.keepDefaultMsg ? t.stringLiteral(value) : null
|
|
268
|
+
].filter(Boolean)
|
|
269
|
+
);
|
|
259
270
|
}
|
|
260
271
|
}
|
|
261
272
|
|
|
@@ -302,7 +313,10 @@ function createI18nVisitor(option, i18nMap) {
|
|
|
302
313
|
}
|
|
303
314
|
|
|
304
315
|
// 替换为字符类型翻译节点
|
|
305
|
-
const tCallExpression =
|
|
316
|
+
const tCallExpression = option.keepDefaultMsg
|
|
317
|
+
? `${option.translateKey}('${generateText(value, hashed, option)}', ${JSON.stringify(value)})`
|
|
318
|
+
: `${option.translateKey}('${generateText(value, hashed, option)}')`;
|
|
319
|
+
|
|
306
320
|
node.value.raw = node.value.cooked = `\${${tCallExpression}}`;
|
|
307
321
|
},
|
|
308
322
|
JSXText(path) {
|
|
@@ -325,9 +339,13 @@ function createI18nVisitor(option, i18nMap) {
|
|
|
325
339
|
// 替换为表达式 {$t("hashed")}
|
|
326
340
|
path.replaceWith(
|
|
327
341
|
t.jsxExpressionContainer(
|
|
328
|
-
t.callExpression(
|
|
329
|
-
t.
|
|
330
|
-
|
|
342
|
+
t.callExpression(
|
|
343
|
+
t.identifier(option.translateKey),
|
|
344
|
+
[
|
|
345
|
+
t.stringLiteral(generateText(text, hashed, option)),
|
|
346
|
+
option.keepDefaultMsg ? t.stringLiteral(text) : null
|
|
347
|
+
].filter(Boolean)
|
|
348
|
+
)
|
|
331
349
|
)
|
|
332
350
|
);
|
|
333
351
|
},
|
|
@@ -352,9 +370,13 @@ function createI18nVisitor(option, i18nMap) {
|
|
|
352
370
|
|
|
353
371
|
path.replaceWith(
|
|
354
372
|
t.jsxExpressionContainer(
|
|
355
|
-
t.callExpression(
|
|
356
|
-
t.
|
|
357
|
-
|
|
373
|
+
t.callExpression(
|
|
374
|
+
t.identifier(option.translateKey),
|
|
375
|
+
[
|
|
376
|
+
t.stringLiteral(generateText(value, hashed, option)),
|
|
377
|
+
option.keepDefaultMsg ? t.stringLiteral(value) : null
|
|
378
|
+
].filter(Boolean)
|
|
379
|
+
)
|
|
358
380
|
)
|
|
359
381
|
);
|
|
360
382
|
}
|
|
@@ -418,7 +440,7 @@ function createI18nVisitor(option, i18nMap) {
|
|
|
418
440
|
}
|
|
419
441
|
}
|
|
420
442
|
|
|
421
|
-
if (!option.keepRaw) {
|
|
443
|
+
if (!option.keepDefaultMsg && !option.keepRaw) {
|
|
422
444
|
// 移除 defaultMsg
|
|
423
445
|
openingElement.attributes = openingElement.attributes.filter(
|
|
424
446
|
attr =>
|
package/lib/vite-plugin-i18n.js
CHANGED
|
@@ -1,15 +1,52 @@
|
|
|
1
|
+
const { createFilter } = require("@rollup/pluginutils");
|
|
1
2
|
const { transformAsync } = require("@babel/core");
|
|
2
3
|
const { createI18nPlugin } = require("./visitors");
|
|
3
|
-
const {
|
|
4
|
+
const {
|
|
5
|
+
relativeCWDPath,
|
|
6
|
+
resolveFilterPath,
|
|
7
|
+
fixFolderPath
|
|
8
|
+
} = require("./utils");
|
|
4
9
|
const { defaultOptions } = require("./options");
|
|
5
10
|
const { globalI18nMap, handleFinalI18nMap } = require("./extract");
|
|
6
11
|
|
|
12
|
+
function createFilterFn(option) {
|
|
13
|
+
const {
|
|
14
|
+
i18nPkgImportPath: importPath,
|
|
15
|
+
allowedExtensions: extensions,
|
|
16
|
+
includePath,
|
|
17
|
+
excludedPath
|
|
18
|
+
} = option;
|
|
19
|
+
|
|
20
|
+
return createFilter(
|
|
21
|
+
extensions
|
|
22
|
+
.map(ext => includePath.map(p => `${fixFolderPath(p)}**/*${ext}`))
|
|
23
|
+
.flat(),
|
|
24
|
+
[
|
|
25
|
+
"node_modules/**",
|
|
26
|
+
importPath.endsWith("/")
|
|
27
|
+
? [
|
|
28
|
+
resolveFilterPath(importPath + "index.ts"),
|
|
29
|
+
resolveFilterPath(importPath + "index.js")
|
|
30
|
+
]
|
|
31
|
+
: [
|
|
32
|
+
resolveFilterPath(importPath + "/index.ts"),
|
|
33
|
+
resolveFilterPath(importPath + "/index.js"),
|
|
34
|
+
resolveFilterPath(importPath + ".ts"),
|
|
35
|
+
resolveFilterPath(importPath + ".js")
|
|
36
|
+
],
|
|
37
|
+
excludedPath.map(resolveFilterPath)
|
|
38
|
+
].flat()
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
7
42
|
function vitePluginI18n(option) {
|
|
8
43
|
option = { ...defaultOptions, ...option };
|
|
9
44
|
|
|
10
45
|
let config;
|
|
11
46
|
let timer;
|
|
12
47
|
|
|
48
|
+
const filter = createFilterFn(option);
|
|
49
|
+
|
|
13
50
|
return {
|
|
14
51
|
name: "vite-plugin-i18n-hash",
|
|
15
52
|
enforce: "post",
|
|
@@ -41,39 +78,24 @@ function vitePluginI18n(option) {
|
|
|
41
78
|
config = resolvedConfig;
|
|
42
79
|
},
|
|
43
80
|
async transform(code, path) {
|
|
44
|
-
if (!option.enabled) return;
|
|
81
|
+
if (!option.enabled || !filter(path)) return;
|
|
45
82
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
return code;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
return transformAsync(code, {
|
|
61
|
-
configFile: false,
|
|
62
|
-
plugins: [createI18nPlugin(option, globalI18nMap)]
|
|
83
|
+
return transformAsync(code, {
|
|
84
|
+
configFile: false,
|
|
85
|
+
plugins: [createI18nPlugin(option, globalI18nMap)]
|
|
86
|
+
})
|
|
87
|
+
.then(result => {
|
|
88
|
+
if (option.outputJsonFileInPlugin && config?.command === "serve") {
|
|
89
|
+
clearTimeout(timer);
|
|
90
|
+
timer = setTimeout(() => {
|
|
91
|
+
handleFinalI18nMap(globalI18nMap, option, true);
|
|
92
|
+
}, option.outputJsonFileDebounceTimeInPlugin);
|
|
93
|
+
}
|
|
94
|
+
return result?.code;
|
|
63
95
|
})
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
timer = setTimeout(() => {
|
|
68
|
-
handleFinalI18nMap(globalI18nMap, option, true);
|
|
69
|
-
}, option.outputJsonFileDebounceTimeInPlugin);
|
|
70
|
-
}
|
|
71
|
-
return result?.code;
|
|
72
|
-
})
|
|
73
|
-
.catch(e => {
|
|
74
|
-
console.error(e);
|
|
75
|
-
});
|
|
76
|
-
}
|
|
96
|
+
.catch(e => {
|
|
97
|
+
console.error(e);
|
|
98
|
+
});
|
|
77
99
|
},
|
|
78
100
|
buildEnd() {},
|
|
79
101
|
closeBundle() {
|
|
@@ -83,6 +105,8 @@ function vitePluginI18n(option) {
|
|
|
83
105
|
};
|
|
84
106
|
}
|
|
85
107
|
|
|
108
|
+
exports.createFilterFn = createFilterFn;
|
|
109
|
+
|
|
86
110
|
module.exports = vitePluginI18n;
|
|
87
111
|
|
|
88
112
|
/* import { defineConfig } from 'vite'
|
|
@@ -1,45 +1,24 @@
|
|
|
1
|
-
const { createFilter } = require("@rollup/pluginutils");
|
|
2
1
|
const { i18nImportTransform } = require("./import-i18n-transform");
|
|
2
|
+
const { createFilterFn } = require("./vite-plugin-i18n");
|
|
3
3
|
const { defaultOptions } = require("./options");
|
|
4
|
-
const { resolveFilterPath, fixFolderPath } = require("./utils");
|
|
5
4
|
|
|
6
|
-
function vitePluginImportI18n(
|
|
7
|
-
|
|
8
|
-
translateKey: importName,
|
|
9
|
-
i18nPkgImportPath: importPath,
|
|
10
|
-
allowedExtensions: extensions,
|
|
11
|
-
includePath,
|
|
12
|
-
excludedPath,
|
|
13
|
-
enabled
|
|
14
|
-
} = { ...defaultOptions, ...options };
|
|
5
|
+
function vitePluginImportI18n(option) {
|
|
6
|
+
option = { ...defaultOptions, ...option };
|
|
15
7
|
|
|
16
|
-
const filter =
|
|
17
|
-
extensions
|
|
18
|
-
.map(ext => includePath.map(p => `${fixFolderPath(p)}**/*${ext}`))
|
|
19
|
-
.flat(),
|
|
20
|
-
[
|
|
21
|
-
"node_modules/**",
|
|
22
|
-
importPath.endsWith("/")
|
|
23
|
-
? [
|
|
24
|
-
resolveFilterPath(importPath + "index.ts"),
|
|
25
|
-
resolveFilterPath(importPath + "index.js")
|
|
26
|
-
]
|
|
27
|
-
: [
|
|
28
|
-
resolveFilterPath(importPath + "/index.ts"),
|
|
29
|
-
resolveFilterPath(importPath + "/index.js"),
|
|
30
|
-
resolveFilterPath(importPath + ".ts"),
|
|
31
|
-
resolveFilterPath(importPath + ".js")
|
|
32
|
-
],
|
|
33
|
-
excludedPath.map(resolveFilterPath)
|
|
34
|
-
].flat()
|
|
35
|
-
);
|
|
8
|
+
const filter = createFilterFn(option);
|
|
36
9
|
|
|
37
10
|
return {
|
|
38
11
|
name: "vite-plugin-import-i18n",
|
|
39
12
|
enforce: "pre",
|
|
40
13
|
async transform(code, path) {
|
|
41
|
-
if (!enabled || !filter(path)) return;
|
|
42
|
-
|
|
14
|
+
if (!option.enabled || !filter(path)) return;
|
|
15
|
+
|
|
16
|
+
return i18nImportTransform(
|
|
17
|
+
code,
|
|
18
|
+
path,
|
|
19
|
+
option.translateKey,
|
|
20
|
+
option.i18nPkgImportPath
|
|
21
|
+
);
|
|
43
22
|
}
|
|
44
23
|
};
|
|
45
24
|
}
|
package/package.json
CHANGED