@chaoswise/intl 2.1.1 → 2.1.3
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/bin/scripts/addLocale.js
CHANGED
|
@@ -4,6 +4,7 @@ const transformAst = require('./util/transformAst');
|
|
|
4
4
|
const getWordsByIds = require('./util/getWordsByIds');
|
|
5
5
|
const log = require('./util/log');
|
|
6
6
|
const genXlsx = require('./util/genXlsx');
|
|
7
|
+
const service = require('./service');
|
|
7
8
|
|
|
8
9
|
async function update() {
|
|
9
10
|
log.info('收集全部词条...');
|
|
@@ -15,19 +16,33 @@ async function update() {
|
|
|
15
16
|
// 获取全部词条
|
|
16
17
|
const allWords = await getWordsByIds(_downloadIds, conf);
|
|
17
18
|
|
|
19
|
+
// 获取所有语种
|
|
20
|
+
const languageRes = await service.getLanguage();
|
|
21
|
+
if (languageRes.code !== 10000) {
|
|
22
|
+
log.error('请求数据出错:' + languageRes.msg);
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
const languages = languageRes.data;
|
|
26
|
+
const mainLanguage = languages.filter((l) => l.isMain)[0];
|
|
27
|
+
|
|
18
28
|
const localeKeys = Object.keys(allWords);
|
|
19
|
-
const xlsxData = _downloadIds.map(id => {
|
|
29
|
+
const xlsxData = _downloadIds.map((id) => {
|
|
20
30
|
const localeObj = {};
|
|
21
|
-
localeKeys.forEach(key => {
|
|
22
|
-
|
|
31
|
+
localeKeys.forEach((key) => {
|
|
32
|
+
if (mainLanguage && key === mainLanguage.key) {
|
|
33
|
+
localeObj[key] =
|
|
34
|
+
allWords[key][id] || info.defaultKeyWordMap[id] || '待翻译';
|
|
35
|
+
} else {
|
|
36
|
+
localeObj[key] = allWords[key][id] || '待翻译';
|
|
37
|
+
}
|
|
23
38
|
});
|
|
24
39
|
return {
|
|
25
40
|
id,
|
|
26
|
-
...localeObj
|
|
27
|
-
}
|
|
41
|
+
...localeObj,
|
|
42
|
+
};
|
|
28
43
|
});
|
|
29
44
|
|
|
30
|
-
await genXlsx(xlsxData)
|
|
45
|
+
await genXlsx(xlsxData);
|
|
31
46
|
}
|
|
32
47
|
|
|
33
48
|
module.exports = update;
|
|
@@ -29,23 +29,22 @@ module.exports = function (
|
|
|
29
29
|
removeFunctionName,
|
|
30
30
|
},
|
|
31
31
|
returns,
|
|
32
|
-
{ filePath, special }
|
|
32
|
+
{ filePath, special }
|
|
33
33
|
) {
|
|
34
|
-
|
|
35
34
|
const { replaceWords, allWords, downloadIds, specialMethod } = returns;
|
|
36
35
|
const hacked = {};
|
|
37
36
|
|
|
38
37
|
// 在没有replaceWords的情况下,不用log信息,这里统一处理
|
|
39
38
|
const properLog = {};
|
|
40
|
-
Object.keys(log).forEach(fnName => {
|
|
39
|
+
Object.keys(log).forEach((fnName) => {
|
|
41
40
|
properLog[fnName] = (...args) => {
|
|
42
41
|
if (!Object.keys(replaceWords).length) return;
|
|
43
42
|
log[fnName](...args);
|
|
44
|
-
}
|
|
45
|
-
})
|
|
43
|
+
};
|
|
44
|
+
});
|
|
46
45
|
|
|
47
46
|
// 获取完整路劲。例如:path='key',返回'0.key'
|
|
48
|
-
function getFullPath
|
|
47
|
+
function getFullPath(path) {
|
|
49
48
|
if (!path) return path;
|
|
50
49
|
if (typeof path !== 'string') return path;
|
|
51
50
|
if (/^[0-9]/.test(path)) {
|
|
@@ -60,29 +59,27 @@ module.exports = function (
|
|
|
60
59
|
}
|
|
61
60
|
// 插入注释
|
|
62
61
|
function insertFailCommon(node, errorMsg) {
|
|
63
|
-
const comment = node?.leadingComments?.value
|
|
62
|
+
const comment = node?.leadingComments?.value;
|
|
64
63
|
const errMsg = `${commentStr} ${errorMsg}`;
|
|
65
64
|
if (comment && comment.trim() === errMsg.trim()) return;
|
|
66
65
|
t.addComment(node, 'leading', errMsg);
|
|
67
66
|
}
|
|
68
67
|
// 在jsx中插入注释
|
|
69
68
|
function insertFailCommonInJsx(path, errorMsg) {
|
|
70
|
-
const comment = path?.node?.leadingComments?.value
|
|
69
|
+
const comment = path?.node?.leadingComments?.value;
|
|
71
70
|
const errMsg = `${commentStr} ${errorMsg}`;
|
|
72
71
|
if (comment && comment.trim() === errMsg.trim()) return;
|
|
73
72
|
path.insertBefore(
|
|
74
|
-
t.jsxExpressionContainer(
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
)
|
|
85
|
-
)
|
|
73
|
+
t.jsxExpressionContainer({
|
|
74
|
+
type: 'JSXEmptyExpression',
|
|
75
|
+
innerComments: [
|
|
76
|
+
{
|
|
77
|
+
type: 'CommentBlock',
|
|
78
|
+
value: errMsg,
|
|
79
|
+
},
|
|
80
|
+
],
|
|
81
|
+
})
|
|
82
|
+
);
|
|
86
83
|
}
|
|
87
84
|
|
|
88
85
|
// 获取国际化jsx标签中的id或者defaultMessage
|
|
@@ -136,7 +133,9 @@ module.exports = function (
|
|
|
136
133
|
// 获取函数名称 fn/object.fn/object.a.b.c/intl.get().d
|
|
137
134
|
function getFnName(node) {
|
|
138
135
|
let fnName = '';
|
|
139
|
-
while (
|
|
136
|
+
while (
|
|
137
|
+
['CallExpression', 'MemberExpression', 'Identifier'].includes(node?.type)
|
|
138
|
+
) {
|
|
140
139
|
if (node.type === 'CallExpression') {
|
|
141
140
|
let name = getFnName(node.callee);
|
|
142
141
|
fnName = `${name}().` + fnName;
|
|
@@ -149,7 +148,7 @@ module.exports = function (
|
|
|
149
148
|
node = node.object;
|
|
150
149
|
} else if (node.type === 'Identifier') {
|
|
151
150
|
// 这里获取修饰器的函数名称
|
|
152
|
-
fnName = fnName ||
|
|
151
|
+
fnName = fnName || node.name + '.';
|
|
153
152
|
break;
|
|
154
153
|
}
|
|
155
154
|
}
|
|
@@ -166,7 +165,7 @@ module.exports = function (
|
|
|
166
165
|
// 字符串默认是单引号,如果模板字符串中出现单引号,需要转义,把 ' 换成 \'
|
|
167
166
|
// 就算用户自定配置字符串为双引号,也没事,默认会转义双引号,但是默认不会处理单引号,所以自己手动处理
|
|
168
167
|
if (/\'/.test(id)) {
|
|
169
|
-
id = id.replace(/\'/g, '
|
|
168
|
+
id = id.replace(/\'/g, "\\'");
|
|
170
169
|
}
|
|
171
170
|
|
|
172
171
|
return Object.assign(t.StringLiteral(value), {
|
|
@@ -224,7 +223,9 @@ module.exports = function (
|
|
|
224
223
|
.d('{slot0}中文');
|
|
225
224
|
*/
|
|
226
225
|
const keys = Object.keys(obj);
|
|
227
|
-
const datas = dealArgs(
|
|
226
|
+
const datas = dealArgs(
|
|
227
|
+
Object.values(obj).map((item) => item.value || item)
|
|
228
|
+
);
|
|
228
229
|
|
|
229
230
|
return t.ObjectExpression(
|
|
230
231
|
keys.map((k, i) => {
|
|
@@ -232,7 +233,7 @@ module.exports = function (
|
|
|
232
233
|
return t.ObjectProperty(
|
|
233
234
|
t.Identifier(k),
|
|
234
235
|
obj[k].isAstNode ? node : t.Identifier(obj[k])
|
|
235
|
-
)
|
|
236
|
+
);
|
|
236
237
|
})
|
|
237
238
|
);
|
|
238
239
|
}
|
|
@@ -247,7 +248,7 @@ module.exports = function (
|
|
|
247
248
|
function dealArgs(args) {
|
|
248
249
|
if (!Array.isArray(args)) return args;
|
|
249
250
|
const resArgs = []; // 参数处理完,用resArgs保存
|
|
250
|
-
args.forEach(node => {
|
|
251
|
+
args.forEach((node) => {
|
|
251
252
|
// 字符串变量
|
|
252
253
|
if (node.type === 'StringLiteral' && isPrimary(node.value)) {
|
|
253
254
|
resArgs.push(makeReplace(node.value));
|
|
@@ -266,7 +267,7 @@ module.exports = function (
|
|
|
266
267
|
}
|
|
267
268
|
// 字符串模版
|
|
268
269
|
else if (node.type === 'TemplateLiteral') {
|
|
269
|
-
const { needReplace, value, variable
|
|
270
|
+
const { needReplace, value, variable } = dealTemplateLiteralNode(node);
|
|
270
271
|
resArgs.push(
|
|
271
272
|
needReplace
|
|
272
273
|
? makeReplace(value, Object.keys(variable).length ? variable : null)
|
|
@@ -274,20 +275,23 @@ module.exports = function (
|
|
|
274
275
|
);
|
|
275
276
|
}
|
|
276
277
|
// ObjectExpression和ObjectProperty,是为了处理参数存在对象的情况,比如:{x:'中文'}
|
|
277
|
-
else if (node.type === 'ObjectExpression') {
|
|
278
|
+
else if (node.type === 'ObjectExpression') {
|
|
279
|
+
// Object
|
|
278
280
|
node.properties = dealArgs(node.properties);
|
|
279
281
|
resArgs.push(node);
|
|
280
|
-
} else if (node.type === 'ObjectProperty') {
|
|
282
|
+
} else if (node.type === 'ObjectProperty') {
|
|
283
|
+
// Object的属性
|
|
281
284
|
const res = dealArgs([node.value]);
|
|
282
285
|
node.value = res[0];
|
|
283
286
|
resArgs.push(node);
|
|
284
|
-
} else if (node.type === 'ArrayExpression') {
|
|
287
|
+
} else if (node.type === 'ArrayExpression') {
|
|
288
|
+
// Array
|
|
285
289
|
node.elements = dealArgs(node.elements);
|
|
286
290
|
resArgs.push(node);
|
|
287
291
|
} else {
|
|
288
292
|
resArgs.push(node);
|
|
289
293
|
}
|
|
290
|
-
})
|
|
294
|
+
});
|
|
291
295
|
return resArgs;
|
|
292
296
|
}
|
|
293
297
|
|
|
@@ -304,8 +308,10 @@ module.exports = function (
|
|
|
304
308
|
|
|
305
309
|
// 特殊文件处理
|
|
306
310
|
if (special) {
|
|
307
|
-
const str = `${
|
|
308
|
-
|
|
311
|
+
const str = `${
|
|
312
|
+
i18nObject ? `${i18nObject}.` : ''
|
|
313
|
+
}${i18nMethod}("${id}").${i18nDefaultFunctionKey}("${value}")`;
|
|
314
|
+
return hackValue(str, str);
|
|
309
315
|
}
|
|
310
316
|
// 生成新的ast节点
|
|
311
317
|
const v = hackValue(value, id);
|
|
@@ -319,11 +325,14 @@ module.exports = function (
|
|
|
319
325
|
// 如果computed为true,则节点对应于一个computed(a[b])成员表达式,并且属性是一个表达式。
|
|
320
326
|
// 如果computed为false,则节点对应于静态(a.b)成员表达式,属性为标识符或PrivateName。
|
|
321
327
|
i18nObject
|
|
322
|
-
? t.memberExpression(
|
|
328
|
+
? t.memberExpression(
|
|
329
|
+
t.identifier(i18nObject),
|
|
330
|
+
t.identifier(i18nMethod)
|
|
331
|
+
)
|
|
323
332
|
: t.identifier(i18nMethod),
|
|
324
333
|
objExp ? [v, objExp] : [v]
|
|
325
|
-
)
|
|
326
|
-
|
|
334
|
+
),
|
|
335
|
+
t.identifier(i18nDefaultFunctionKey)
|
|
327
336
|
),
|
|
328
337
|
[defaultV]
|
|
329
338
|
);
|
|
@@ -364,10 +373,11 @@ module.exports = function (
|
|
|
364
373
|
}
|
|
365
374
|
|
|
366
375
|
return {
|
|
367
|
-
needReplace:
|
|
376
|
+
needReplace:
|
|
377
|
+
needReplace && value.trim() /*处理模板字符串为空的情况,比如:` `*/,
|
|
368
378
|
value,
|
|
369
379
|
variable,
|
|
370
|
-
}
|
|
380
|
+
};
|
|
371
381
|
}
|
|
372
382
|
// 字符串变量
|
|
373
383
|
function dealStringLiteralNode(node, path) {
|
|
@@ -378,7 +388,9 @@ module.exports = function (
|
|
|
378
388
|
// 组件属性,比如:<Root prop='中文' /> 中的prop
|
|
379
389
|
case 'JSXAttribute':
|
|
380
390
|
// ignoreComponents 可忽略一些组件
|
|
381
|
-
if (
|
|
391
|
+
if (
|
|
392
|
+
!ignoreComponents.includes(path?.parentPath?.parent?.name?.name)
|
|
393
|
+
) {
|
|
382
394
|
needReplace = true;
|
|
383
395
|
}
|
|
384
396
|
break;
|
|
@@ -404,7 +416,7 @@ module.exports = function (
|
|
|
404
416
|
value: null,
|
|
405
417
|
skip: false,
|
|
406
418
|
remove: false,
|
|
407
|
-
}
|
|
419
|
+
};
|
|
408
420
|
if (shouldIgnore(node)) {
|
|
409
421
|
res.skip = true;
|
|
410
422
|
return res;
|
|
@@ -413,11 +425,13 @@ module.exports = function (
|
|
|
413
425
|
const fnName = getFnName(node.callee);
|
|
414
426
|
|
|
415
427
|
// 处理 ignoreMethods
|
|
416
|
-
if (
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
428
|
+
if (
|
|
429
|
+
[
|
|
430
|
+
...(ignoreMethods || []),
|
|
431
|
+
`${i18nObject}.${i18nMethod}`, // intl.get
|
|
432
|
+
`${i18nObject}.${i18nMethod}().${i18nDefaultFunctionKey}`, // intl.get().d
|
|
433
|
+
].includes(fnName)
|
|
434
|
+
) {
|
|
421
435
|
res.skip = true;
|
|
422
436
|
return res;
|
|
423
437
|
}
|
|
@@ -437,11 +451,14 @@ module.exports = function (
|
|
|
437
451
|
const argsAst = node.arguments;
|
|
438
452
|
// 把ast转为js, 再用FormPath.getIn来取最终的值
|
|
439
453
|
const { code: argsCode } = generate(t.arrayExpression(argsAst));
|
|
440
|
-
let chaoswiseIntlId
|
|
441
|
-
var chaoswiseIntlIdData
|
|
454
|
+
let chaoswiseIntlId;
|
|
455
|
+
var chaoswiseIntlIdData;
|
|
442
456
|
try {
|
|
443
457
|
eval('var chaoswiseIntlIdData =' + argsCode);
|
|
444
|
-
chaoswiseIntlId = FormPath.getIn(
|
|
458
|
+
chaoswiseIntlId = FormPath.getIn(
|
|
459
|
+
chaoswiseIntlIdData,
|
|
460
|
+
getFullPath(intlFunctionIdPath)
|
|
461
|
+
);
|
|
445
462
|
} catch (e) {
|
|
446
463
|
// var a = 'id'; f(a) 这样会出错
|
|
447
464
|
// TODO
|
|
@@ -449,7 +466,10 @@ module.exports = function (
|
|
|
449
466
|
|
|
450
467
|
let value = getWord(chaoswiseIntlId);
|
|
451
468
|
if (!value) {
|
|
452
|
-
let defaultValue = FormPath.getIn(
|
|
469
|
+
let defaultValue = FormPath.getIn(
|
|
470
|
+
chaoswiseIntlIdData,
|
|
471
|
+
getFullPath(intlFunctionDefaultWordPath)
|
|
472
|
+
);
|
|
453
473
|
if (typeof defaultValue === 'string' && defaultValue) {
|
|
454
474
|
value = defaultValue;
|
|
455
475
|
} else {
|
|
@@ -461,8 +481,10 @@ module.exports = function (
|
|
|
461
481
|
} else {
|
|
462
482
|
if (!chaoswiseIntlId) {
|
|
463
483
|
errorMsg = `在 ${intlFunctionName}() 中未找到 ${intlFunctionIdPath} 对应的值`;
|
|
464
|
-
properLog.warn(
|
|
465
|
-
|
|
484
|
+
properLog.warn(
|
|
485
|
+
`文件 ${filePath} 中,在 ${intlFunctionName}() 中未找到 ${intlFunctionIdPath} 对应的值`
|
|
486
|
+
);
|
|
487
|
+
} else if (!localWordPath) {
|
|
466
488
|
// 中文json文件未配置
|
|
467
489
|
errorMsg = `国际化中文文件路径 localWordPath 未配置`;
|
|
468
490
|
properLog.warn(errorMsg);
|
|
@@ -474,9 +496,11 @@ module.exports = function (
|
|
|
474
496
|
}
|
|
475
497
|
if (intlFunctionDefaultWordPath && !defaultValue) {
|
|
476
498
|
errorMsg = `在 ${intlFunctionName}() 中未找到 ${intlFunctionDefaultWordPath} 对应的值`;
|
|
477
|
-
properLog.warn(
|
|
499
|
+
properLog.warn(
|
|
500
|
+
`文件 ${filePath} 中,在 ${intlFunctionName} 中未找到 ${intlFunctionDefaultWordPath} 对应的值`
|
|
501
|
+
);
|
|
478
502
|
}
|
|
479
|
-
|
|
503
|
+
|
|
480
504
|
insertFailCommon(node, errorMsg);
|
|
481
505
|
}
|
|
482
506
|
}
|
|
@@ -485,7 +509,7 @@ module.exports = function (
|
|
|
485
509
|
if (!specialMethod.includes(fnName)) {
|
|
486
510
|
specialMethod.push(fnName);
|
|
487
511
|
}
|
|
488
|
-
|
|
512
|
+
|
|
489
513
|
res.needReplace = true;
|
|
490
514
|
res.value = value;
|
|
491
515
|
}
|
|
@@ -523,9 +547,11 @@ module.exports = function (
|
|
|
523
547
|
TemplateLiteral(path) {
|
|
524
548
|
const { node } = path;
|
|
525
549
|
|
|
526
|
-
const { needReplace, value, variable
|
|
550
|
+
const { needReplace, value, variable } = dealTemplateLiteralNode(node);
|
|
527
551
|
if (needReplace) {
|
|
528
|
-
path.replaceWith(
|
|
552
|
+
path.replaceWith(
|
|
553
|
+
makeReplace(value, Object.keys(variable).length ? variable : null)
|
|
554
|
+
);
|
|
529
555
|
path.skip();
|
|
530
556
|
}
|
|
531
557
|
},
|
|
@@ -562,7 +588,7 @@ module.exports = function (
|
|
|
562
588
|
const { node } = path;
|
|
563
589
|
|
|
564
590
|
const { needReplace, value, skip, remove } = dealCallExpressionNode(node);
|
|
565
|
-
|
|
591
|
+
|
|
566
592
|
if (remove) {
|
|
567
593
|
if (node.arguments.length === 1) {
|
|
568
594
|
// 去掉外侧的包裹组件
|
|
@@ -598,14 +624,19 @@ module.exports = function (
|
|
|
598
624
|
|
|
599
625
|
// 如果是配置的国际化jsx标签
|
|
600
626
|
if (!shouldIgnore(node) && intlTag && jsxName === intlTag) {
|
|
601
|
-
|
|
602
|
-
|
|
627
|
+
let id = getJsxTagChaoswiseIntlValue(
|
|
628
|
+
openingElement,
|
|
629
|
+
intlTagIdPath || 'id'
|
|
630
|
+
);
|
|
603
631
|
|
|
604
632
|
let word = getWord(id);
|
|
605
633
|
|
|
606
634
|
if (!word) {
|
|
607
635
|
// 根据id找不到中文,就找jsx标签的默认中文
|
|
608
|
-
let defaultValue = getJsxTagChaoswiseIntlValue(
|
|
636
|
+
let defaultValue = getJsxTagChaoswiseIntlValue(
|
|
637
|
+
openingElement,
|
|
638
|
+
intlTagDefaultWordPath
|
|
639
|
+
);
|
|
609
640
|
if (typeof defaultValue === 'string') {
|
|
610
641
|
word = defaultValue;
|
|
611
642
|
} else {
|
|
@@ -616,8 +647,10 @@ module.exports = function (
|
|
|
616
647
|
} else {
|
|
617
648
|
if (!id) {
|
|
618
649
|
errorMsg = `文件 ${filePath} 中,在<${intlTag} /> 中未找到 ${intlTagIdPath} 对应的值`;
|
|
619
|
-
properLog.warn(
|
|
620
|
-
|
|
650
|
+
properLog.warn(
|
|
651
|
+
`在<${intlTag} /> 中未找到 ${intlTagIdPath} 对应的值`
|
|
652
|
+
);
|
|
653
|
+
} else if (!localWordPath) {
|
|
621
654
|
// 中文json文件未配置
|
|
622
655
|
errorMsg = `国际化中文文件路径 localWordPath 未配置`;
|
|
623
656
|
properLog.warn(errorMsg);
|
|
@@ -629,7 +662,9 @@ module.exports = function (
|
|
|
629
662
|
}
|
|
630
663
|
if (intlTagDefaultWordPath && defaultValue === false) {
|
|
631
664
|
errorMsg = `在<${intlTag} /> 中未找到 ${intlTagDefaultWordPath} 对应的值`;
|
|
632
|
-
properLog.warn(
|
|
665
|
+
properLog.warn(
|
|
666
|
+
`文件 ${filePath} 在 <${intlTag} /> 中未找到 ${intlTagDefaultWordPath} 对应的值`
|
|
667
|
+
);
|
|
633
668
|
}
|
|
634
669
|
|
|
635
670
|
if (['JSXFragment', 'JSXElement'].includes(parentNodeType)) {
|
|
@@ -637,7 +672,6 @@ module.exports = function (
|
|
|
637
672
|
} else {
|
|
638
673
|
insertFailCommon(node, errorMsg);
|
|
639
674
|
}
|
|
640
|
-
|
|
641
675
|
}
|
|
642
676
|
}
|
|
643
677
|
if (word && isPrimary(word)) {
|
|
@@ -679,5 +713,14 @@ module.exports = function (
|
|
|
679
713
|
path.skip();
|
|
680
714
|
}
|
|
681
715
|
},
|
|
716
|
+
// 带标签的模板表达式: 可处理css in js的情况,比如:css.resolve`.test{color:red;}`
|
|
717
|
+
TaggedTemplateExpression(path) {
|
|
718
|
+
const { node } = path;
|
|
719
|
+
|
|
720
|
+
const fnName = getFnName(node.tag);
|
|
721
|
+
if ((ignoreMethods || []).includes(fnName)) {
|
|
722
|
+
path.skip();
|
|
723
|
+
}
|
|
724
|
+
},
|
|
682
725
|
};
|
|
683
|
-
}
|
|
726
|
+
};
|
|
@@ -2,21 +2,14 @@ const t = require('@babel/types');
|
|
|
2
2
|
const specialMatch = require('./specialMatch');
|
|
3
3
|
|
|
4
4
|
module.exports = function f(
|
|
5
|
-
{
|
|
6
|
-
i18nObject,
|
|
7
|
-
i18nMethod,
|
|
8
|
-
importCode,
|
|
9
|
-
ignoreLines,
|
|
10
|
-
i18nDefaultFunctionKey,
|
|
11
|
-
},
|
|
5
|
+
{ i18nObject, i18nMethod, importCode, ignoreLines, i18nDefaultFunctionKey },
|
|
12
6
|
returns,
|
|
13
|
-
{ special }
|
|
7
|
+
{ special }
|
|
14
8
|
) {
|
|
15
|
-
const { replaceWords, downloadIds } = returns;
|
|
9
|
+
const { replaceWords, downloadIds, defaultKeyWordMap } = returns;
|
|
16
10
|
|
|
17
11
|
// XXX: [TRICKY] 防止中文转码为 unicode
|
|
18
12
|
function hackValue(value, id) {
|
|
19
|
-
|
|
20
13
|
return Object.assign(t.StringLiteral(value), {
|
|
21
14
|
extra: {
|
|
22
15
|
raw: `'${id}'`, // id
|
|
@@ -64,7 +57,6 @@ module.exports = function f(
|
|
|
64
57
|
|
|
65
58
|
// 替换字符串为我们使用的国际化API
|
|
66
59
|
function makeReplace(value, variables) {
|
|
67
|
-
|
|
68
60
|
// 存在临时id替换
|
|
69
61
|
returns.hasTouch = true;
|
|
70
62
|
|
|
@@ -90,25 +82,54 @@ module.exports = function f(
|
|
|
90
82
|
|
|
91
83
|
// 函数或方法调用表达式
|
|
92
84
|
function dealCallExpressionNode(node) {
|
|
85
|
+
// 记录当前key对应的默认词条
|
|
86
|
+
if (
|
|
87
|
+
node.callee.type === 'MemberExpression' &&
|
|
88
|
+
node.callee.object.type === 'CallExpression' &&
|
|
89
|
+
node.callee.property.name === i18nDefaultFunctionKey &&
|
|
90
|
+
((node.callee.object.callee.type === 'MemberExpression' &&
|
|
91
|
+
node.callee.object.callee.object.name === i18nObject &&
|
|
92
|
+
node.callee.object.callee.property.name === i18nMethod) ||
|
|
93
|
+
(!i18nObject &&
|
|
94
|
+
node.callee.object.callee.type === 'Identifier' &&
|
|
95
|
+
node.callee.object.callee.name === i18nMethod))
|
|
96
|
+
) {
|
|
97
|
+
if (
|
|
98
|
+
node.arguments.length > 0 &&
|
|
99
|
+
node.callee.object.arguments.length > 0
|
|
100
|
+
) {
|
|
101
|
+
const k = node.callee.object.arguments[0].value;
|
|
102
|
+
const v = node.arguments[0].value;
|
|
103
|
+
|
|
104
|
+
if (k) {
|
|
105
|
+
defaultKeyWordMap[k] = v;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
93
110
|
const res = {
|
|
94
111
|
needReplace: false,
|
|
95
112
|
value: null,
|
|
96
113
|
skip: false,
|
|
97
|
-
|
|
114
|
+
otherArgs: [],
|
|
115
|
+
};
|
|
98
116
|
|
|
99
117
|
if (
|
|
100
118
|
(node.callee.type === 'MemberExpression' &&
|
|
101
119
|
node.callee.object.name === i18nObject &&
|
|
102
120
|
node.callee.property.name === i18nMethod) ||
|
|
103
|
-
(!i18nObject &&
|
|
121
|
+
(!i18nObject &&
|
|
122
|
+
node.callee.type === 'Identifier' &&
|
|
123
|
+
node.callee.name === i18nMethod)
|
|
104
124
|
) {
|
|
105
125
|
// 收集现有的 key
|
|
106
126
|
const args = node.arguments;
|
|
107
|
-
if(!args.length) {
|
|
127
|
+
if (!args.length) {
|
|
108
128
|
return res;
|
|
109
129
|
}
|
|
110
130
|
|
|
111
131
|
let key = args[0].value;
|
|
132
|
+
res.otherArgs = args.slice(1);
|
|
112
133
|
|
|
113
134
|
// intl.t(key)
|
|
114
135
|
// replaceWords { key: id }
|
|
@@ -137,16 +158,21 @@ module.exports = function f(
|
|
|
137
158
|
|
|
138
159
|
if (!shouldIgnore(node) && special) {
|
|
139
160
|
// intl.get('id').d(中文) 获取id和中文
|
|
161
|
+
// TODO: 当前get()方法不支持处理有参数的场景[get('id',{a:1})],如需处理需要同时修改脚手架中的react-router-config-loader
|
|
140
162
|
const { id, defaultValue } = specialMatch(value) || {};
|
|
141
163
|
if (!id) return;
|
|
142
164
|
|
|
165
|
+
defaultKeyWordMap[id] = defaultValue;
|
|
166
|
+
|
|
143
167
|
const finalyId = replaceWords[id];
|
|
144
168
|
if (finalyId) {
|
|
145
169
|
returns.hasTouch = true;
|
|
146
170
|
downloadIds.push(finalyId);
|
|
147
171
|
|
|
148
|
-
const str = `${
|
|
149
|
-
|
|
172
|
+
const str = `${
|
|
173
|
+
i18nObject ? `${i18nObject}.` : ''
|
|
174
|
+
}${i18nMethod}("${finalyId}").${i18nDefaultFunctionKey}("${defaultValue}")`;
|
|
175
|
+
const newStr = hackValue(str, str);
|
|
150
176
|
path.replaceWith(newStr);
|
|
151
177
|
path.skip();
|
|
152
178
|
} else {
|
|
@@ -169,12 +195,13 @@ module.exports = function f(
|
|
|
169
195
|
// 函数或方法调用表达式,比如:a('中午')
|
|
170
196
|
CallExpression(path) {
|
|
171
197
|
const { node } = path;
|
|
172
|
-
|
|
173
198
|
if (!node.ignore) {
|
|
174
|
-
const { needReplace, value, skip } =
|
|
199
|
+
const { needReplace, value, skip, otherArgs } =
|
|
200
|
+
dealCallExpressionNode(node);
|
|
175
201
|
|
|
176
202
|
if (needReplace) {
|
|
177
203
|
const res = makeReplace(value);
|
|
204
|
+
res.arguments = res.arguments.concat(otherArgs);
|
|
178
205
|
path.replaceWith(res);
|
|
179
206
|
|
|
180
207
|
path.node.ignore = true;
|
|
@@ -183,4 +210,4 @@ module.exports = function f(
|
|
|
183
210
|
}
|
|
184
211
|
},
|
|
185
212
|
};
|
|
186
|
-
}
|
|
213
|
+
};
|
|
@@ -82,6 +82,7 @@ module.exports = function (type, files = [], conf = {}, replaceWords) {
|
|
|
82
82
|
const allWords = []; // 收集到的所有词条
|
|
83
83
|
const downloadIds = []; // 需要从平台下载的词条id
|
|
84
84
|
const specialMethod = []; // 替换的国际化特殊方法
|
|
85
|
+
const defaultKeyWordMap = {}; // addLocal指令中使用:记录当前key对应的默认词条
|
|
85
86
|
|
|
86
87
|
// babel配置
|
|
87
88
|
const transformOptions = {
|
|
@@ -129,6 +130,7 @@ module.exports = function (type, files = [], conf = {}, replaceWords) {
|
|
|
129
130
|
replaceWords: replaceWords || {},
|
|
130
131
|
downloadIds,
|
|
131
132
|
specialMethod,
|
|
133
|
+
defaultKeyWordMap,
|
|
132
134
|
hasImport: false, // 是否已经引入通用国际化API,import {init} from ...;
|
|
133
135
|
hasTouch: false, // 是否存在需要替换的词条
|
|
134
136
|
};
|
|
@@ -200,5 +202,6 @@ module.exports = function (type, files = [], conf = {}, replaceWords) {
|
|
|
200
202
|
allWords,
|
|
201
203
|
downloadIds,
|
|
202
204
|
specialMethod,
|
|
205
|
+
defaultKeyWordMap
|
|
203
206
|
};
|
|
204
207
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chaoswise/intl",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.3",
|
|
4
4
|
"author": "cloudwiser",
|
|
5
5
|
"description": "intl",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -84,5 +84,5 @@
|
|
|
84
84
|
"react-dom": "^16.13.1"
|
|
85
85
|
},
|
|
86
86
|
"license": "MIT",
|
|
87
|
-
"gitHead": "
|
|
87
|
+
"gitHead": "422bbd1a0545e50a6e8a6e41240536bbc5274e20"
|
|
88
88
|
}
|