vite-gc-i18n-plugin 1.1.3 → 1.1.4

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/dist/index.cjs CHANGED
@@ -1676,7 +1676,6 @@ async function autoTranslate() {
1676
1676
 
1677
1677
  // 无新内容提前退出
1678
1678
  if (Object.keys(transLangObj).length === 0) {
1679
- console.info('✅ 当前没有需要翻译的新内容');
1680
1679
  return;
1681
1680
  }
1682
1681
 
@@ -1822,8 +1821,10 @@ async function translateChunks(transLangObj, translateKey) {
1822
1821
  const {
1823
1822
  translator
1824
1823
  } = exports.option;
1824
+ const placeholders = [];
1825
+ const protectedValues = Object.values(transLangObj).map(value => protectInterpolationPlaceholders(value, placeholders));
1825
1826
  // 获取分块后的文本列表
1826
- const translationChunks = createTextSplitter(Object.values(transLangObj), translator.option.maxChunkSize);
1827
+ const translationChunks = createTextSplitter(protectedValues, translator.option.maxChunkSize);
1827
1828
  // 并行执行分块翻译
1828
1829
  const translatePromises = [];
1829
1830
  for (let i = 0; i < translationChunks.length; i++) {
@@ -1833,6 +1834,7 @@ async function translateChunks(transLangObj, translateKey) {
1833
1834
  // 等待所有分块完成并合并结果
1834
1835
  const chunkResults = await Promise.all(translatePromises);
1835
1836
  return chunkResults.map(item => {
1837
+ item = restoreInterpolationPlaceholders(item, placeholders);
1836
1838
  // 提取分割逻辑到单独的函数中,提高代码复用性
1837
1839
  const splitTranslation = (text, separatorRegex) => {
1838
1840
  return text.split(separatorRegex).map(v => v.trim());
@@ -1856,6 +1858,17 @@ async function translateChunks(transLangObj, translateKey) {
1856
1858
  }
1857
1859
  }).flat();
1858
1860
  }
1861
+ function protectInterpolationPlaceholders(value, placeholders) {
1862
+ return value.replace(/\$\{[^}]*\}/g, match => {
1863
+ const index = placeholders.push(match) - 1;
1864
+ return `__GC_I18N_PH_${index}__`;
1865
+ });
1866
+ }
1867
+ function restoreInterpolationPlaceholders(value, placeholders) {
1868
+ return value.replace(/__GC_I18N_PH_(\d+)__/g, (match, index) => {
1869
+ return placeholders[Number(index)] || match;
1870
+ });
1871
+ }
1859
1872
  /**
1860
1873
  * @description: 清理多余的翻译配置JSON文件
1861
1874
  * @return {void} 无返回值
@@ -2015,8 +2028,6 @@ function createTextSplitter(values, maxChunkSize) {
2015
2028
  * @returns 处理后的字符串数组
2016
2029
  */
2017
2030
  function splitByRegex(str, separatorRegex) {
2018
- if (str.includes('\n')) console.log(str, separatorRegex);
2019
-
2020
2031
  // 定义标点符号的正则表达式
2021
2032
  const punctuationRegex = /[,。?!《》,..:!?""'';'"、0-9\n\r\t\v\f]/;
2022
2033
  // 创建一个新的正则表达式,用于分割字符串
@@ -2295,8 +2306,17 @@ function TemplateLiteral (insertOption) {
2295
2306
  };
2296
2307
  }
2297
2308
  function handleTemplateLiteralWithExpressions(node, path) {
2298
- const placeholders = node.expressions.map(expression => getExpressionPlaceholder(expression));
2299
- if (placeholders.some(placeholder => !placeholder)) {
2309
+ let hasOptimizedExpression = false;
2310
+ const expressionLabels = node.expressions.map((expression, index) => {
2311
+ const optimizedExpression = optimizeConditionalExpression(expression);
2312
+ if (optimizedExpression) {
2313
+ hasOptimizedExpression = true;
2314
+ node.expressions[index] = optimizedExpression.expression;
2315
+ return optimizedExpression.label;
2316
+ }
2317
+ return getExpressionPlaceholder(expression);
2318
+ });
2319
+ if (expressionLabels.some(placeholder => placeholder === null)) {
2300
2320
  return false;
2301
2321
  }
2302
2322
  const fullValue = node.quasis.reduce((result, quasi, index) => {
@@ -2308,9 +2328,13 @@ function handleTemplateLiteralWithExpressions(node, path) {
2308
2328
  console.log('转换异常');
2309
2329
  }
2310
2330
  }
2311
- return result + value + (index < node.expressions.length ? `\${${placeholders[index]}}` : '');
2331
+ return result + value + (index < node.expressions.length ? formatExpressionPlaceholder(expressionLabels[index]) : '');
2312
2332
  }, '');
2313
2333
  if (!fullValue || !hasOriginSymbols(fullValue) || !exports.option.excludedPattern.length || checkAgainstRegexArray(fullValue, [...exports.option.excludedPattern])) {
2334
+ if (hasOptimizedExpression) {
2335
+ path.skip();
2336
+ return true;
2337
+ }
2314
2338
  return false;
2315
2339
  }
2316
2340
  const {
@@ -2318,22 +2342,12 @@ function handleTemplateLiteralWithExpressions(node, path) {
2318
2342
  valStr
2319
2343
  } = normalizeTranslateValue(fullValue);
2320
2344
  const id = generateId(valStr);
2321
- const translateNode = createTranslateNode(path, id, valStr, placeholders, node.expressions);
2345
+ const translateNode = createTranslateNode(path, id, valStr, expressionLabels, node.expressions);
2322
2346
  path.replaceWith(translateNode);
2323
- path.skip();
2324
2347
  setLangObj(id, trimmedValue);
2325
2348
  return true;
2326
2349
  }
2327
2350
  function getExpressionPlaceholder(expression) {
2328
- if (types.isIdentifier(expression)) {
2329
- return expression.name;
2330
- }
2331
- if (types.isMemberExpression(expression)) {
2332
- const objectName = getExpressionPlaceholder(expression.object);
2333
- const propertyName = expression.computed ? getExpressionPlaceholder(expression.property) : types.isIdentifier(expression.property) ? expression.property.name : '';
2334
- const value = [objectName, propertyName].filter(Boolean).join('.');
2335
- return cleanVueRuntimePrefix(value);
2336
- }
2337
2351
  if (types.isStringLiteral(expression) || types.isNumericLiteral(expression)) {
2338
2352
  return String(expression.value);
2339
2353
  }
@@ -2344,21 +2358,142 @@ function getExpressionPlaceholder(expression) {
2344
2358
  return getExpressionPlaceholder(expression.expression);
2345
2359
  }
2346
2360
  const generateCode = generate__namespace.default?.default || generate__namespace.default || generate__namespace;
2347
- return cleanVueRuntimePrefix(generateCode(expression).code);
2361
+ return generateCode(expression, {
2362
+ comments: false
2363
+ }).code;
2364
+ }
2365
+ function optimizeConditionalExpression(expression) {
2366
+ if (!types.isConditionalExpression(expression)) return null;
2367
+ const consequent = translateConditionalStringBranch(expression.consequent);
2368
+ const alternate = translateConditionalStringBranch(expression.alternate);
2369
+ if (!consequent.changed && !alternate.changed) return null;
2370
+ return {
2371
+ label: getConditionalExpressionLabel(expression),
2372
+ expression: types.conditionalExpression(types.cloneNode(expression.test), consequent.expression, alternate.expression)
2373
+ };
2374
+ }
2375
+ function translateConditionalStringBranch(expression) {
2376
+ if (types.isStringLiteral(expression) && hasOriginSymbols(expression.value)) {
2377
+ return {
2378
+ changed: true,
2379
+ expression: createTrackedTranslateCall(expression.value)
2380
+ };
2381
+ }
2382
+ if (types.isTemplateLiteral(expression)) {
2383
+ const translateCall = createTemplateLiteralTranslateCall(expression);
2384
+ if (translateCall) {
2385
+ return {
2386
+ changed: true,
2387
+ expression: translateCall
2388
+ };
2389
+ }
2390
+ }
2391
+ if (types.isConditionalExpression(expression)) {
2392
+ const optimizedExpression = optimizeConditionalExpression(expression);
2393
+ if (optimizedExpression) {
2394
+ return {
2395
+ changed: true,
2396
+ expression: optimizedExpression.expression
2397
+ };
2398
+ }
2399
+ }
2400
+ return {
2401
+ changed: false,
2402
+ expression: types.cloneNode(expression)
2403
+ };
2404
+ }
2405
+ function createTrackedTranslateCall(value) {
2406
+ const translateCall = createI18nTranslator({
2407
+ value,
2408
+ isExpression: true
2409
+ });
2410
+ const {
2411
+ trimmedValue,
2412
+ valStr
2413
+ } = normalizeTranslateValue(value);
2414
+ const id = generateId(valStr);
2415
+ if (id && trimmedValue) {
2416
+ setLangObj(id, trimmedValue);
2417
+ }
2418
+ return translateCall;
2419
+ }
2420
+ function createTemplateLiteralTranslateCall(node) {
2421
+ const expressions = node.expressions.map(expression => {
2422
+ const optimizedExpression = optimizeConditionalExpression(expression);
2423
+ return optimizedExpression ? optimizedExpression.expression : expression;
2424
+ });
2425
+ const expressionLabels = expressions.map(expression => getExpressionPlaceholder(expression));
2426
+ if (expressionLabels.some(placeholder => placeholder === null)) {
2427
+ return null;
2428
+ }
2429
+ const fullValue = node.quasis.reduce((result, quasi, index) => {
2430
+ let value = quasi.value.raw || quasi.value.cooked || '';
2431
+ if (asianLangs.some(lang => exports.option.originLang.includes(lang) || exports.option.originLang === lang)) {
2432
+ try {
2433
+ value = unicodeToString(value);
2434
+ } catch (error) {
2435
+ console.log('转换异常');
2436
+ }
2437
+ }
2438
+ return result + value + (index < expressions.length ? formatExpressionPlaceholder(expressionLabels[index]) : '');
2439
+ }, '');
2440
+ if (!fullValue || !hasOriginSymbols(fullValue) || !exports.option.excludedPattern.length || checkAgainstRegexArray(fullValue, [...exports.option.excludedPattern])) {
2441
+ return null;
2442
+ }
2443
+ const {
2444
+ trimmedValue,
2445
+ valStr
2446
+ } = normalizeTranslateValue(fullValue);
2447
+ const id = generateId(valStr);
2448
+ if (id && trimmedValue) {
2449
+ setLangObj(id, trimmedValue);
2450
+ }
2451
+ return createTranslateCall(id, valStr, expressionLabels, expressions);
2452
+ }
2453
+ function getConditionalExpressionLabel(expression) {
2454
+ const test = expression.test;
2455
+ if (types.isBinaryExpression(test) || types.isLogicalExpression(test)) {
2456
+ return getExpressionPlaceholder(test.left);
2457
+ }
2458
+ return getExpressionPlaceholder(test);
2459
+ }
2460
+ function formatExpressionPlaceholder(placeholder) {
2461
+ if (placeholder === null) return '';
2462
+ return placeholder.trim() ? `\${${placeholder}}` : placeholder;
2348
2463
  }
2349
2464
  function createTranslateNode(path, id, valStr) {
2350
2465
  let placeholders = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : [];
2351
2466
  let expressions = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : [];
2352
- const args = [types.stringLiteral(id), types.stringLiteral(valStr)];
2353
- if (placeholders.length) {
2354
- args.push(types.objectExpression(placeholders.map((placeholder, index) => types.objectProperty(types.stringLiteral(placeholder), types.cloneNode(expressions[index])))));
2355
- }
2356
- const translateCall = types.callExpression(types.identifier(exports.option.translateKey), args);
2467
+ const translateCall = createTranslateCall(id, valStr, placeholders, expressions);
2357
2468
  if (!isVueTemplateRender(path)) {
2358
2469
  return translateCall;
2359
2470
  }
2360
2471
  return types.sequenceExpression([createVueTemplateLanguageDependency(), translateCall]);
2361
2472
  }
2473
+ function createTranslateCall(id, valStr) {
2474
+ let placeholders = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
2475
+ let expressions = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : [];
2476
+ const args = [types.stringLiteral(id), types.stringLiteral(valStr)];
2477
+ if (placeholders.length) {
2478
+ const placeholderEntries = placeholders.map((placeholder, index) => ({
2479
+ placeholder,
2480
+ expression: expressions[index]
2481
+ })).filter(_ref => {
2482
+ let {
2483
+ placeholder
2484
+ } = _ref;
2485
+ return placeholder && placeholder.trim();
2486
+ });
2487
+ args.push(types.objectExpression(placeholderEntries.map(_ref2 => {
2488
+ let {
2489
+ placeholder,
2490
+ expression
2491
+ } = _ref2;
2492
+ return types.objectProperty(types.stringLiteral(placeholder), types.cloneNode(expression));
2493
+ })));
2494
+ }
2495
+ return types.callExpression(types.identifier(exports.option.translateKey), args);
2496
+ }
2362
2497
  function isVueTemplateRender(path) {
2363
2498
  return Boolean(path.scope?.getBinding('_vm'));
2364
2499
  }
@@ -2372,9 +2507,6 @@ function createVueTemplateLanguageDependency() {
2372
2507
  const i18nLocale = types.logicalExpression('&&', types.cloneNode(i18n), types.memberExpression(types.cloneNode(i18n), types.identifier('locale')));
2373
2508
  return types.logicalExpression('||', storeLanguage, i18nLocale);
2374
2509
  }
2375
- function cleanVueRuntimePrefix(value) {
2376
- return value.replace(/^(?:\$setup|_ctx|_vm|this)\./, '').replace(/([^\w$.])(?:\$setup|_ctx|_vm|this)\./g, '$1');
2377
- }
2378
2510
 
2379
2511
  // 处理模板元素
2380
2512
  function handleTemplateElement(node, insertOption) {