vite-gc-i18n-plugin 1.1.2 → 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 +161 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +161 -28
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
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(
|
|
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
|
// 创建一个新的正则表达式,用于分割字符串
|
|
@@ -2169,7 +2180,8 @@ async function upload(json) {
|
|
|
2169
2180
|
data
|
|
2170
2181
|
}, {
|
|
2171
2182
|
headers: {
|
|
2172
|
-
'Content-Type': 'application/json'
|
|
2183
|
+
'Content-Type': 'application/json',
|
|
2184
|
+
Authorization: '728635D658AE11F18F33000C29A621CA'
|
|
2173
2185
|
}
|
|
2174
2186
|
});
|
|
2175
2187
|
if (res.status === 200 && res.data.result === 0) {
|
|
@@ -2294,8 +2306,17 @@ function TemplateLiteral (insertOption) {
|
|
|
2294
2306
|
};
|
|
2295
2307
|
}
|
|
2296
2308
|
function handleTemplateLiteralWithExpressions(node, path) {
|
|
2297
|
-
|
|
2298
|
-
|
|
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)) {
|
|
2299
2320
|
return false;
|
|
2300
2321
|
}
|
|
2301
2322
|
const fullValue = node.quasis.reduce((result, quasi, index) => {
|
|
@@ -2307,9 +2328,13 @@ function handleTemplateLiteralWithExpressions(node, path) {
|
|
|
2307
2328
|
console.log('转换异常');
|
|
2308
2329
|
}
|
|
2309
2330
|
}
|
|
2310
|
-
return result + value + (index < node.expressions.length ?
|
|
2331
|
+
return result + value + (index < node.expressions.length ? formatExpressionPlaceholder(expressionLabels[index]) : '');
|
|
2311
2332
|
}, '');
|
|
2312
2333
|
if (!fullValue || !hasOriginSymbols(fullValue) || !exports.option.excludedPattern.length || checkAgainstRegexArray(fullValue, [...exports.option.excludedPattern])) {
|
|
2334
|
+
if (hasOptimizedExpression) {
|
|
2335
|
+
path.skip();
|
|
2336
|
+
return true;
|
|
2337
|
+
}
|
|
2313
2338
|
return false;
|
|
2314
2339
|
}
|
|
2315
2340
|
const {
|
|
@@ -2317,22 +2342,12 @@ function handleTemplateLiteralWithExpressions(node, path) {
|
|
|
2317
2342
|
valStr
|
|
2318
2343
|
} = normalizeTranslateValue(fullValue);
|
|
2319
2344
|
const id = generateId(valStr);
|
|
2320
|
-
const translateNode = createTranslateNode(path, id, valStr,
|
|
2345
|
+
const translateNode = createTranslateNode(path, id, valStr, expressionLabels, node.expressions);
|
|
2321
2346
|
path.replaceWith(translateNode);
|
|
2322
|
-
path.skip();
|
|
2323
2347
|
setLangObj(id, trimmedValue);
|
|
2324
2348
|
return true;
|
|
2325
2349
|
}
|
|
2326
2350
|
function getExpressionPlaceholder(expression) {
|
|
2327
|
-
if (types.isIdentifier(expression)) {
|
|
2328
|
-
return expression.name;
|
|
2329
|
-
}
|
|
2330
|
-
if (types.isMemberExpression(expression)) {
|
|
2331
|
-
const objectName = getExpressionPlaceholder(expression.object);
|
|
2332
|
-
const propertyName = expression.computed ? getExpressionPlaceholder(expression.property) : types.isIdentifier(expression.property) ? expression.property.name : '';
|
|
2333
|
-
const value = [objectName, propertyName].filter(Boolean).join('.');
|
|
2334
|
-
return cleanVueRuntimePrefix(value);
|
|
2335
|
-
}
|
|
2336
2351
|
if (types.isStringLiteral(expression) || types.isNumericLiteral(expression)) {
|
|
2337
2352
|
return String(expression.value);
|
|
2338
2353
|
}
|
|
@@ -2343,21 +2358,142 @@ function getExpressionPlaceholder(expression) {
|
|
|
2343
2358
|
return getExpressionPlaceholder(expression.expression);
|
|
2344
2359
|
}
|
|
2345
2360
|
const generateCode = generate__namespace.default?.default || generate__namespace.default || generate__namespace;
|
|
2346
|
-
return
|
|
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;
|
|
2347
2463
|
}
|
|
2348
2464
|
function createTranslateNode(path, id, valStr) {
|
|
2349
2465
|
let placeholders = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : [];
|
|
2350
2466
|
let expressions = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : [];
|
|
2351
|
-
const
|
|
2352
|
-
if (placeholders.length) {
|
|
2353
|
-
args.push(types.objectExpression(placeholders.map((placeholder, index) => types.objectProperty(types.stringLiteral(placeholder), types.cloneNode(expressions[index])))));
|
|
2354
|
-
}
|
|
2355
|
-
const translateCall = types.callExpression(types.identifier(exports.option.translateKey), args);
|
|
2467
|
+
const translateCall = createTranslateCall(id, valStr, placeholders, expressions);
|
|
2356
2468
|
if (!isVueTemplateRender(path)) {
|
|
2357
2469
|
return translateCall;
|
|
2358
2470
|
}
|
|
2359
2471
|
return types.sequenceExpression([createVueTemplateLanguageDependency(), translateCall]);
|
|
2360
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
|
+
}
|
|
2361
2497
|
function isVueTemplateRender(path) {
|
|
2362
2498
|
return Boolean(path.scope?.getBinding('_vm'));
|
|
2363
2499
|
}
|
|
@@ -2371,9 +2507,6 @@ function createVueTemplateLanguageDependency() {
|
|
|
2371
2507
|
const i18nLocale = types.logicalExpression('&&', types.cloneNode(i18n), types.memberExpression(types.cloneNode(i18n), types.identifier('locale')));
|
|
2372
2508
|
return types.logicalExpression('||', storeLanguage, i18nLocale);
|
|
2373
2509
|
}
|
|
2374
|
-
function cleanVueRuntimePrefix(value) {
|
|
2375
|
-
return value.replace(/^(?:\$setup|_ctx|_vm|this)\./, '').replace(/([^\w$.])(?:\$setup|_ctx|_vm|this)\./g, '$1');
|
|
2376
|
-
}
|
|
2377
2510
|
|
|
2378
2511
|
// 处理模板元素
|
|
2379
2512
|
function handleTemplateElement(node, insertOption) {
|