webpack-gc-i18n-plugin 1.1.5 → 1.1.6

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.
@@ -7,6 +7,8 @@ require('crypto-js');
7
7
  var OpenCC = require('opencc-js');
8
8
  var types = require('@babel/types');
9
9
  require('lodash');
10
+ var path = require('node:path');
11
+ var fs = require('node:fs');
10
12
  var babel = require('@babel/core');
11
13
  var generate = require('@babel/generator');
12
14
 
@@ -539,6 +541,49 @@ function convertToTemplateLiteral(strArray, option) {
539
541
  return deepScanCall;
540
542
  }
541
543
 
544
+ /**
545
+ * @description: 读取国际化JSON文件
546
+ * @return {*}
547
+ */
548
+ function getLangTranslateJSONFile() {
549
+ const filePath = path.join(option.globalPath, 'index.json');
550
+ try {
551
+ const content = fs.readFileSync(filePath, 'utf-8');
552
+ return content;
553
+ } catch (error) {
554
+ if (error.code === 'ENOENT') {
555
+ console.log('❌读取JSON配置文件异常,文件不存在');
556
+ } else {
557
+ console.log('❌读取JSON配置文件异常,无法读取文件');
558
+ }
559
+ return JSON.stringify({});
560
+ }
561
+ }
562
+
563
+ /**
564
+ * @description: 基于langKey获取JSON配置文件中对应语言对象
565
+ * @param {string} key
566
+ * @return {*}
567
+ */
568
+ function getLangObjByJSONFileWithLangKey(key) {
569
+ let insertJSONObj = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined;
570
+ // 获取翻译配置对象,优先使用传入的配置,否则从本地文件读取
571
+ const JSONObj = insertJSONObj || JSON.parse(getLangTranslateJSONFile());
572
+
573
+ // 初始化语言映射对象,用于存储不同语言的hash: value映射
574
+ const langObj = {};
575
+
576
+ // 遍历hash,提取hash对应语言key的值,并写入到langObj
577
+ Object.keys(JSONObj).forEach(langCode => {
578
+ langObj[langCode] = JSONObj[langCode][key];
579
+ });
580
+
581
+ // 返回当前语言的hash: value映射对象
582
+ // 例如: 'zh-cn' > {'hash1': '你好', 'hash2': '世界'}
583
+ // 'en' > {'hash1': 'hello', 'hash2': 'world'}
584
+ return langObj;
585
+ }
586
+
542
587
  /*
543
588
  * @Author: xiaoshanwen
544
589
  * @Date: 2023-10-30 18:23:03
@@ -547,11 +592,32 @@ function convertToTemplateLiteral(strArray, option) {
547
592
  */
548
593
 
549
594
  let langObj = {};
550
- function getLangKeyByValue(value) {
551
- return Object.entries(langObj).find(_ref => {
595
+ function normalizeValueForDedupe(value) {
596
+ return String(value || '').trim();
597
+ }
598
+ function findKeyByValue(valueMap, value) {
599
+ const exactKey = Object.entries(valueMap).find(_ref => {
552
600
  let [, oldValue] = _ref;
553
601
  return oldValue === value;
554
602
  })?.[0];
603
+ if (exactKey) return exactKey;
604
+ const normalizedValue = normalizeValueForDedupe(value);
605
+ return Object.entries(valueMap).find(_ref2 => {
606
+ let [, oldValue] = _ref2;
607
+ return normalizeValueForDedupe(oldValue) === normalizedValue;
608
+ })?.[0];
609
+ }
610
+ function getExistingOriginLangObj() {
611
+ try {
612
+ const filePath = path.join(option.globalPath, 'index.json');
613
+ if (!fs.existsSync(filePath)) return {};
614
+ return getLangObjByJSONFileWithLangKey(option.originLang);
615
+ } catch (error) {
616
+ return {};
617
+ }
618
+ }
619
+ function getLangKeyByValue(value) {
620
+ return findKeyByValue(langObj, value) || findKeyByValue(getExistingOriginLangObj(), value);
555
621
  }
556
622
  function resolveLangKey(key, value) {
557
623
  return getLangKeyByValue(value) || key;
@@ -559,14 +625,30 @@ function resolveLangKey(key, value) {
559
625
  function isTemplateValue(value) {
560
626
  return /\$\{[^}]+}/.test(value);
561
627
  }
562
- function getTemplateStaticSegments(value) {
563
- return value.split(/\$\{[^}]+}/g).filter(item => item);
628
+ function hasOriginSymbols$1(value) {
629
+ const originRegex = REGEX_MAP[option.originLang];
630
+ return originRegex ? originRegex.test(value) : false;
631
+ }
632
+ function getTemplateSemanticSplitSegments(value) {
633
+ const segments = value.split(/\$\{[^}]+}/g);
634
+ const result = new Set();
635
+ for (let index = 0; index < segments.length - 1; index++) {
636
+ const beforeValue = segments[index];
637
+ const afterValue = segments[index + 1];
638
+ if (!hasOriginSymbols$1(beforeValue) || !hasOriginSymbols$1(afterValue)) continue;
639
+ [beforeValue, afterValue].forEach(segment => {
640
+ if (segment.trim().length > 1) {
641
+ result.add(segment);
642
+ }
643
+ });
644
+ }
645
+ return [...result];
564
646
  }
565
647
  function isTemplateStaticSegment(value) {
566
- return Object.values(langObj).some(oldValue => isTemplateValue(oldValue) && getTemplateStaticSegments(oldValue).includes(value));
648
+ return Object.values(langObj).some(oldValue => isTemplateValue(oldValue) && getTemplateSemanticSplitSegments(oldValue).includes(value));
567
649
  }
568
650
  function removeTemplateStaticSegments(value) {
569
- const segments = new Set(getTemplateStaticSegments(value));
651
+ const segments = new Set(getTemplateSemanticSplitSegments(value));
570
652
  Object.keys(langObj).forEach(key => {
571
653
  if (segments.has(langObj[key])) {
572
654
  delete langObj[key];
@@ -1040,6 +1122,9 @@ function handleTemplateLiteralWithExpressions(node, path) {
1040
1122
  }
1041
1123
  return false;
1042
1124
  }
1125
+ if (!hasExpressionInsideOriginContent(node)) {
1126
+ return false;
1127
+ }
1043
1128
  const {
1044
1129
  trimmedValue,
1045
1130
  valStr
@@ -1050,6 +1135,24 @@ function handleTemplateLiteralWithExpressions(node, path) {
1050
1135
  setLangObj(id, trimmedValue);
1051
1136
  return true;
1052
1137
  }
1138
+ function hasExpressionInsideOriginContent(node) {
1139
+ return node.expressions.some((_, index) => {
1140
+ const beforeValue = node.quasis.slice(0, index + 1).map(getTemplateElementValue).join('');
1141
+ const afterValue = node.quasis.slice(index + 1).map(getTemplateElementValue).join('');
1142
+ return hasOriginSymbols(beforeValue) && hasOriginSymbols(afterValue);
1143
+ });
1144
+ }
1145
+ function getTemplateElementValue(quasi) {
1146
+ let value = quasi.value.raw || quasi.value.cooked || '';
1147
+ if (asianLangs.some(lang => option.originLang.includes(lang) || option.originLang === lang)) {
1148
+ try {
1149
+ value = unicodeToString(value);
1150
+ } catch (error) {
1151
+ console.log('转换异常');
1152
+ }
1153
+ }
1154
+ return value;
1155
+ }
1053
1156
  function getExpressionPlaceholder(expression) {
1054
1157
  if (types.isStringLiteral(expression) || types.isNumericLiteral(expression)) {
1055
1158
  return String(expression.value);
@@ -1143,6 +1246,9 @@ function createTemplateLiteralTranslateCall(node) {
1143
1246
  if (!fullValue || !hasOriginSymbols(fullValue) || !option.excludedPattern.length || checkAgainstRegexArray(fullValue, [...option.excludedPattern])) {
1144
1247
  return null;
1145
1248
  }
1249
+ if (!hasExpressionInsideOriginContent(node)) {
1250
+ return createTemplateLiteralWithTranslatedQuasis(node, expressions);
1251
+ }
1146
1252
  const {
1147
1253
  trimmedValue,
1148
1254
  valStr
@@ -1153,6 +1259,40 @@ function createTemplateLiteralTranslateCall(node) {
1153
1259
  }
1154
1260
  return createTranslateCall(id, valStr, expressionLabels, expressions);
1155
1261
  }
1262
+ function createTemplateLiteralWithTranslatedQuasis(node, expressions) {
1263
+ const quasis = [];
1264
+ const nextExpressions = [];
1265
+ let pendingText = '';
1266
+ let hasTranslatedQuasi = false;
1267
+ node.quasis.forEach((quasi, index) => {
1268
+ const value = getTemplateElementValue(quasi);
1269
+ if (value && hasOriginSymbols(value) && option.excludedPattern.length && !checkAgainstRegexArray(value, [...option.excludedPattern])) {
1270
+ quasis.push(types.templateElement({
1271
+ raw: pendingText,
1272
+ cooked: pendingText
1273
+ }, false));
1274
+ nextExpressions.push(createTrackedTranslateCall(value));
1275
+ pendingText = '';
1276
+ hasTranslatedQuasi = true;
1277
+ } else {
1278
+ pendingText += value;
1279
+ }
1280
+ if (index < expressions.length) {
1281
+ quasis.push(types.templateElement({
1282
+ raw: pendingText,
1283
+ cooked: pendingText
1284
+ }, false));
1285
+ nextExpressions.push(types.cloneNode(expressions[index]));
1286
+ pendingText = '';
1287
+ }
1288
+ });
1289
+ if (!hasTranslatedQuasi) return null;
1290
+ quasis.push(types.templateElement({
1291
+ raw: pendingText,
1292
+ cooked: pendingText
1293
+ }, true));
1294
+ return types.templateLiteral(quasis, nextExpressions);
1295
+ }
1156
1296
  function getConditionalExpressionLabel(expression) {
1157
1297
  const test = expression.test;
1158
1298
  if (types.isBinaryExpression(test) || types.isLogicalExpression(test)) {