@chaoswise/intl 2.1.1 → 2.1.2
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.
|
@@ -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
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chaoswise/intl",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.2",
|
|
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": "b47f3fd4716247a1c51c0da46b6bafb5a6fff086"
|
|
88
88
|
}
|