webpack-gc-i18n-plugin 1.0.3 → 1.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/dist/customLoader/index.cjs +1352 -1
- package/dist/customLoader/index.cjs.map +1 -1
- package/dist/customLoader/index.mjs +1329 -1
- package/dist/customLoader/index.mjs.map +1 -1
- package/dist/index.cjs +2801 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +686 -3
- package/dist/index.mjs +2756 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +14 -10
|
@@ -1,2 +1,1353 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var googleTranslateApi = require('@vitalets/google-translate-api');
|
|
4
|
+
var tunnel = require('tunnel');
|
|
5
|
+
require('axios');
|
|
6
|
+
require('crypto-js');
|
|
7
|
+
var OpenCC = require('opencc-js');
|
|
8
|
+
var types = require('@babel/types');
|
|
9
|
+
require('lodash');
|
|
10
|
+
var babel = require('@babel/core');
|
|
11
|
+
var generate = require('@babel/generator');
|
|
12
|
+
|
|
13
|
+
function _interopNamespaceDefault(e) {
|
|
14
|
+
var n = Object.create(null);
|
|
15
|
+
if (e) {
|
|
16
|
+
Object.keys(e).forEach(function (k) {
|
|
17
|
+
if (k !== 'default') {
|
|
18
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
19
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
20
|
+
enumerable: true,
|
|
21
|
+
get: function () { return e[k]; }
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
n.default = e;
|
|
27
|
+
return Object.freeze(n);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
var OpenCC__namespace = /*#__PURE__*/_interopNamespaceDefault(OpenCC);
|
|
31
|
+
var types__namespace = /*#__PURE__*/_interopNamespaceDefault(types);
|
|
32
|
+
var babel__namespace = /*#__PURE__*/_interopNamespaceDefault(babel);
|
|
33
|
+
var generate__namespace = /*#__PURE__*/_interopNamespaceDefault(generate);
|
|
34
|
+
|
|
35
|
+
/******************************************************************************
|
|
36
|
+
Copyright (c) Microsoft Corporation.
|
|
37
|
+
|
|
38
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
39
|
+
purpose with or without fee is hereby granted.
|
|
40
|
+
|
|
41
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
42
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
43
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
44
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
45
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
46
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
47
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
48
|
+
***************************************************************************** */
|
|
49
|
+
/* global Reflect, Promise, SuppressedError, Symbol, Iterator */
|
|
50
|
+
|
|
51
|
+
function __awaiter(thisArg, _arguments, P, generator) {
|
|
52
|
+
function adopt(value) {
|
|
53
|
+
return value instanceof P ? value : new P(function (resolve) {
|
|
54
|
+
resolve(value);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
58
|
+
function fulfilled(value) {
|
|
59
|
+
try {
|
|
60
|
+
step(generator.next(value));
|
|
61
|
+
} catch (e) {
|
|
62
|
+
reject(e);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
function rejected(value) {
|
|
66
|
+
try {
|
|
67
|
+
step(generator["throw"](value));
|
|
68
|
+
} catch (e) {
|
|
69
|
+
reject(e);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function step(result) {
|
|
73
|
+
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
74
|
+
}
|
|
75
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
function __generator(thisArg, body) {
|
|
79
|
+
var _ = {
|
|
80
|
+
label: 0,
|
|
81
|
+
sent: function () {
|
|
82
|
+
if (t[0] & 1) throw t[1];
|
|
83
|
+
return t[1];
|
|
84
|
+
},
|
|
85
|
+
trys: [],
|
|
86
|
+
ops: []
|
|
87
|
+
},
|
|
88
|
+
f,
|
|
89
|
+
y,
|
|
90
|
+
t,
|
|
91
|
+
g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
92
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function () {
|
|
93
|
+
return this;
|
|
94
|
+
}), g;
|
|
95
|
+
function verb(n) {
|
|
96
|
+
return function (v) {
|
|
97
|
+
return step([n, v]);
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
function step(op) {
|
|
101
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
102
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
103
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
104
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
105
|
+
switch (op[0]) {
|
|
106
|
+
case 0:
|
|
107
|
+
case 1:
|
|
108
|
+
t = op;
|
|
109
|
+
break;
|
|
110
|
+
case 4:
|
|
111
|
+
_.label++;
|
|
112
|
+
return {
|
|
113
|
+
value: op[1],
|
|
114
|
+
done: false
|
|
115
|
+
};
|
|
116
|
+
case 5:
|
|
117
|
+
_.label++;
|
|
118
|
+
y = op[1];
|
|
119
|
+
op = [0];
|
|
120
|
+
continue;
|
|
121
|
+
case 7:
|
|
122
|
+
op = _.ops.pop();
|
|
123
|
+
_.trys.pop();
|
|
124
|
+
continue;
|
|
125
|
+
default:
|
|
126
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
|
|
127
|
+
_ = 0;
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
|
|
131
|
+
_.label = op[1];
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
if (op[0] === 6 && _.label < t[1]) {
|
|
135
|
+
_.label = t[1];
|
|
136
|
+
t = op;
|
|
137
|
+
break;
|
|
138
|
+
}
|
|
139
|
+
if (t && _.label < t[2]) {
|
|
140
|
+
_.label = t[2];
|
|
141
|
+
_.ops.push(op);
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
if (t[2]) _.ops.pop();
|
|
145
|
+
_.trys.pop();
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
op = body.call(thisArg, _);
|
|
149
|
+
} catch (e) {
|
|
150
|
+
op = [6, e];
|
|
151
|
+
y = 0;
|
|
152
|
+
} finally {
|
|
153
|
+
f = t = 0;
|
|
154
|
+
}
|
|
155
|
+
if (op[0] & 5) throw op[1];
|
|
156
|
+
return {
|
|
157
|
+
value: op[0] ? op[1] : void 0,
|
|
158
|
+
done: true
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
163
|
+
var e = new Error(message);
|
|
164
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* 间隔执行队列
|
|
169
|
+
*/
|
|
170
|
+
class IntervalQueue {
|
|
171
|
+
/**
|
|
172
|
+
* @param fn 执行函数
|
|
173
|
+
* @param delay 执行间隔
|
|
174
|
+
* @param timeout 超时时间
|
|
175
|
+
*/
|
|
176
|
+
constructor(fn, delay, timeout) {
|
|
177
|
+
this.fn = fn;
|
|
178
|
+
this.delay = delay;
|
|
179
|
+
this.timeout = timeout;
|
|
180
|
+
}
|
|
181
|
+
queue = [];
|
|
182
|
+
async wait() {
|
|
183
|
+
let delay = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.delay;
|
|
184
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
|
185
|
+
}
|
|
186
|
+
isRunning = false;
|
|
187
|
+
async run() {
|
|
188
|
+
if (this.isRunning) return;
|
|
189
|
+
let item;
|
|
190
|
+
while (item = this.queue.shift()) {
|
|
191
|
+
const {
|
|
192
|
+
args,
|
|
193
|
+
resolve,
|
|
194
|
+
reject
|
|
195
|
+
} = item;
|
|
196
|
+
this.isRunning = true;
|
|
197
|
+
try {
|
|
198
|
+
const result = await this.fn(...args);
|
|
199
|
+
resolve(result);
|
|
200
|
+
} catch (e) {
|
|
201
|
+
reject(e);
|
|
202
|
+
}
|
|
203
|
+
await this.wait();
|
|
204
|
+
}
|
|
205
|
+
this.isRunning = false;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* 执行一次fn
|
|
210
|
+
* @param args fn的入参
|
|
211
|
+
* @returns 返回fn的返回值的Promise
|
|
212
|
+
*/
|
|
213
|
+
execute() {
|
|
214
|
+
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
215
|
+
args[_key] = arguments[_key];
|
|
216
|
+
}
|
|
217
|
+
return new Promise((resolve, reject) => {
|
|
218
|
+
this.queue.push({
|
|
219
|
+
args,
|
|
220
|
+
resolve,
|
|
221
|
+
reject
|
|
222
|
+
});
|
|
223
|
+
this.run();
|
|
224
|
+
if (this.timeout) {
|
|
225
|
+
setTimeout(() => {
|
|
226
|
+
reject(new Error('IntervalQueue timeout'));
|
|
227
|
+
}, this.timeout);
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
class Translator {
|
|
234
|
+
constructor(option) {
|
|
235
|
+
this.option = this.getResultOption(option);
|
|
236
|
+
}
|
|
237
|
+
defaultErrorHandler = error => {
|
|
238
|
+
const name = this.option.name;
|
|
239
|
+
console.error(`翻译api${name ? `【${name}】` : ''}请求异常:${this.getErrorMessage(error)}`);
|
|
240
|
+
};
|
|
241
|
+
getResultOption(option) {
|
|
242
|
+
const resultOption = {
|
|
243
|
+
version: 1,
|
|
244
|
+
maxChunkSize: 4500,
|
|
245
|
+
// 目前默认是4500
|
|
246
|
+
interval: 0,
|
|
247
|
+
onError: this.defaultErrorHandler,
|
|
248
|
+
...option
|
|
249
|
+
};
|
|
250
|
+
if (resultOption.interval) {
|
|
251
|
+
const getIntervalFn = (fn, delay) => {
|
|
252
|
+
const queue = new IntervalQueue(fn.bind(null), delay);
|
|
253
|
+
return function () {
|
|
254
|
+
return queue.execute(...arguments);
|
|
255
|
+
};
|
|
256
|
+
};
|
|
257
|
+
resultOption.fetchMethod = getIntervalFn(resultOption.fetchMethod, resultOption.interval);
|
|
258
|
+
}
|
|
259
|
+
return resultOption;
|
|
260
|
+
}
|
|
261
|
+
getErrorMessage(error) {
|
|
262
|
+
if (error instanceof Error) {
|
|
263
|
+
return error.message;
|
|
264
|
+
} else {
|
|
265
|
+
return String(error);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
async translate(text, fromKey, toKey, separator) {
|
|
269
|
+
let result = '';
|
|
270
|
+
try {
|
|
271
|
+
result = await this.option.fetchMethod(text, fromKey, toKey, separator);
|
|
272
|
+
} catch (error) {
|
|
273
|
+
this.option.onError(error, this.defaultErrorHandler);
|
|
274
|
+
}
|
|
275
|
+
return result;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/*
|
|
280
|
+
* @Date: 2025-03-11 17:53:11
|
|
281
|
+
* @LastEditors: xiaoshan
|
|
282
|
+
* @LastEditTime: 2025-03-14 14:21:06
|
|
283
|
+
* @FilePath: /i18n_translation_vite/packages/autoI18nPluginCore/src/translator/google.ts
|
|
284
|
+
*/
|
|
285
|
+
/**
|
|
286
|
+
* 谷歌翻译器
|
|
287
|
+
*
|
|
288
|
+
* 基于@vitalets/google-translate-api,需要翻墙,不稳定,但是免费
|
|
289
|
+
*
|
|
290
|
+
* 使用方式:
|
|
291
|
+
* ```ts
|
|
292
|
+
* vitePluginsAutoI18n({
|
|
293
|
+
...
|
|
294
|
+
translator: translator: new GoogleTranslator({
|
|
295
|
+
proxyOption: {
|
|
296
|
+
// 如果你本地的代理在127.0.0.0:8899
|
|
297
|
+
host: '127.0.0.1',
|
|
298
|
+
port: 8899,
|
|
299
|
+
headers: {
|
|
300
|
+
'User-Agent': 'Node'
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
})
|
|
304
|
+
})
|
|
305
|
+
* ```
|
|
306
|
+
*/
|
|
307
|
+
class GoogleTranslator extends Translator {
|
|
308
|
+
constructor(option) {
|
|
309
|
+
super({
|
|
310
|
+
name: 'Google翻译',
|
|
311
|
+
fetchMethod: async (text, fromKey, toKey) => {
|
|
312
|
+
let data = await googleTranslateApi.translate(text, {
|
|
313
|
+
from: fromKey,
|
|
314
|
+
to: toKey,
|
|
315
|
+
...(option.proxyOption ? {
|
|
316
|
+
fetchOptions: {
|
|
317
|
+
agent: tunnel.httpsOverHttp({
|
|
318
|
+
proxy: option.proxyOption
|
|
319
|
+
})
|
|
320
|
+
}
|
|
321
|
+
} : {}),
|
|
322
|
+
...(option.insertOption || {})
|
|
323
|
+
});
|
|
324
|
+
return data['text'] || '';
|
|
325
|
+
},
|
|
326
|
+
onError: (error, cb) => {
|
|
327
|
+
cb(error);
|
|
328
|
+
if (error instanceof Object && 'code' in error && error.code === 'ETIMEDOUT') {
|
|
329
|
+
console.error('❗ 请求超时,请确保你的网络可以访问google ❗');
|
|
330
|
+
}
|
|
331
|
+
},
|
|
332
|
+
interval: option.interval ?? 1000
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
OpenCC__namespace.Converter({
|
|
338
|
+
from: 'cn',
|
|
339
|
+
to: 'tw'
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
/*
|
|
343
|
+
* @Author: xiaoshanwen
|
|
344
|
+
* @Date: 2024-02-29 14:44:18
|
|
345
|
+
* @LastEditTime: 2024-03-01 11:42:34
|
|
346
|
+
* @FilePath: /i18n_translation_vite/autoI18nPluginCore/src/utils/option.ts
|
|
347
|
+
*/
|
|
348
|
+
|
|
349
|
+
class FunctionFactoryOption {
|
|
350
|
+
static originLang = '';
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/*
|
|
354
|
+
* @Author: xiaoshanwen
|
|
355
|
+
* @Date: 2024-03-11 18:59:10
|
|
356
|
+
* @LastEditTime: 2025-03-16 18:15:25
|
|
357
|
+
* @FilePath: /i18n_translation_vite/packages/autoI18nPluginCore/src/enums/language.ts
|
|
358
|
+
*/
|
|
359
|
+
// 待补充...
|
|
360
|
+
let OriginLangKeyEnum = /*#__PURE__*/function (OriginLangKeyEnum) {
|
|
361
|
+
OriginLangKeyEnum["ZH"] = "zh-cn";
|
|
362
|
+
OriginLangKeyEnum["EN"] = "en";
|
|
363
|
+
OriginLangKeyEnum["JA"] = "ja";
|
|
364
|
+
OriginLangKeyEnum["KO"] = "ko";
|
|
365
|
+
OriginLangKeyEnum["RU"] = "ru";
|
|
366
|
+
return OriginLangKeyEnum;
|
|
367
|
+
}({});
|
|
368
|
+
|
|
369
|
+
/*
|
|
370
|
+
* @Author: xiaoshanwen
|
|
371
|
+
* @Date: 2024-04-06 15:47:14
|
|
372
|
+
* @LastEditTime: 2025-03-16 18:18:28
|
|
373
|
+
* @FilePath: /i18n_translation_vite/packages/autoI18nPluginCore/src/constants/translate.ts
|
|
374
|
+
*/
|
|
375
|
+
const REGEX_MAP = {
|
|
376
|
+
[OriginLangKeyEnum.ZH]: /[\u4e00-\u9fff]/,
|
|
377
|
+
[OriginLangKeyEnum.EN]: /[a-zA-Z]/,
|
|
378
|
+
[OriginLangKeyEnum.JA]: /[\u3040-\u309F\u30A0-\u30FF\u4E00-\u9FFF]/,
|
|
379
|
+
// 日语假名和汉字
|
|
380
|
+
[OriginLangKeyEnum.KO]: /[\uAC00-\uD7A3]/,
|
|
381
|
+
// 韩语字母
|
|
382
|
+
[OriginLangKeyEnum.RU]: /[йцукенгшщзхъфывапролджэячсмитьбюё .-]{1,}/ // 俄语字母
|
|
383
|
+
};
|
|
384
|
+
|
|
385
|
+
/*
|
|
386
|
+
* @Author: xiaoshanwen
|
|
387
|
+
* @Date: 2023-10-11 10:01:43
|
|
388
|
+
* @LastEditTime: 2025-03-28 19:07:17
|
|
389
|
+
* @FilePath: /i18n_translation_vite/packages/autoI18nPluginCore/src/utils/base.ts
|
|
390
|
+
*/
|
|
391
|
+
function getOriginRegex() {
|
|
392
|
+
const originLang = FunctionFactoryOption.originLang;
|
|
393
|
+
return REGEX_MAP[originLang];
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* @description: 是否包含来源语言字符
|
|
398
|
+
* @param {string} code
|
|
399
|
+
* @return {*}
|
|
400
|
+
*/
|
|
401
|
+
function hasOriginSymbols(code) {
|
|
402
|
+
return getOriginRegex().test(code);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* @description: 过滤注释
|
|
407
|
+
* @param {string} code
|
|
408
|
+
* @return {*}
|
|
409
|
+
*/
|
|
410
|
+
const removeComments = function (code) {
|
|
411
|
+
// 使用正则表达式匹配并删除单行注释
|
|
412
|
+
code = code.replace(/\/\/.*?\n/g, '');
|
|
413
|
+
// 使用正则表达式匹配并删除多行注释
|
|
414
|
+
code = code.replace(/\/\*[\s\S]*?\*\//g, '');
|
|
415
|
+
// 使用正则表达式匹配并删除HTML注释
|
|
416
|
+
code = code.replace(/<!--[\s\S]*?-->/g, '');
|
|
417
|
+
return code;
|
|
418
|
+
};
|
|
419
|
+
|
|
420
|
+
/**
|
|
421
|
+
* @description: 用于判断提供的值是否符合正则表达式数组中的任一规则,符合则跳过
|
|
422
|
+
* @param {*} value
|
|
423
|
+
* @param {*} regexArray
|
|
424
|
+
* @return {*}
|
|
425
|
+
*/
|
|
426
|
+
function checkAgainstRegexArray(value, regexArray) {
|
|
427
|
+
for (let i = 0; i < regexArray.length; i++) {
|
|
428
|
+
const regex = typeof regexArray[i] === 'string' ? new RegExp(regexArray[i]) : regexArray[i];
|
|
429
|
+
if (regex.test(value)) {
|
|
430
|
+
return true; // 如果符合任何一个规则,返回 true
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
return false; // 如果所有规则都不符合,返回 false
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* @description: 用于解析抽象语法树中的调用表达式,并提取出调用的名称,如a.b.c() 取 c。
|
|
438
|
+
* @param {any} node
|
|
439
|
+
* @return {*}
|
|
440
|
+
*/
|
|
441
|
+
function extractFunctionName(node) {
|
|
442
|
+
let callName = '';
|
|
443
|
+
function callObjName(callObj, name) {
|
|
444
|
+
name += '.' + callObj.property.name;
|
|
445
|
+
if (types.isMemberExpression(callObj.object)) {
|
|
446
|
+
// isMemberExpression: 是否是成员表达式
|
|
447
|
+
return callObjName(callObj.object, name);
|
|
448
|
+
}
|
|
449
|
+
name = callObj.object.name + name;
|
|
450
|
+
return name;
|
|
451
|
+
}
|
|
452
|
+
if (types.isCallExpression(node)) {
|
|
453
|
+
// isCallExpression: 是否是调用表达式
|
|
454
|
+
if (types.isMemberExpression(node.callee)) {
|
|
455
|
+
callName = callObjName(node.callee, '');
|
|
456
|
+
} else {
|
|
457
|
+
callName = node.callee.name || '';
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
return callName;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
/**
|
|
464
|
+
* @description: 提取文件的中文部分
|
|
465
|
+
* @param {string} fileContent
|
|
466
|
+
* @return {*}
|
|
467
|
+
*/
|
|
468
|
+
const extractCnStrings = fileContent => {
|
|
469
|
+
const regex = /[^\x00-\xff]+/g;
|
|
470
|
+
return extractStrings(fileContent, regex);
|
|
471
|
+
};
|
|
472
|
+
|
|
473
|
+
/**
|
|
474
|
+
* @description: 提取文件指定部分内容
|
|
475
|
+
* @param {string} fileContent
|
|
476
|
+
* @param {any} regex
|
|
477
|
+
* @return {*}
|
|
478
|
+
*/
|
|
479
|
+
function extractStrings(fileContent, regex) {
|
|
480
|
+
const matches = fileContent.match(regex);
|
|
481
|
+
return matches ? matches.filter((item, index) => matches.indexOf(item) === index) : [];
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
/**
|
|
485
|
+
* @description: 生成i8n翻译函数
|
|
486
|
+
* @param {string} value
|
|
487
|
+
* @param {boolean} isExpression
|
|
488
|
+
* @param {string} key
|
|
489
|
+
* @return {*}
|
|
490
|
+
*/
|
|
491
|
+
function createI18nTranslator(createOption) {
|
|
492
|
+
const {
|
|
493
|
+
value,
|
|
494
|
+
isExpression = false,
|
|
495
|
+
key,
|
|
496
|
+
insertOption
|
|
497
|
+
} = createOption;
|
|
498
|
+
|
|
499
|
+
// 从全局配置对象 option 中获取命名空间
|
|
500
|
+
const nameSpace = option.namespace;
|
|
501
|
+
const {
|
|
502
|
+
trimmedValue,
|
|
503
|
+
valStr
|
|
504
|
+
} = normalizeTranslateValue(value);
|
|
505
|
+
// 若 key 存在则使用 key,否则调用 generateId 函数根据 valStr 生成唯一的键
|
|
506
|
+
const generatedKey = key || generateId(valStr);
|
|
507
|
+
// 提取公共配置对象,避免重复代码
|
|
508
|
+
const config = {
|
|
509
|
+
option: option,
|
|
510
|
+
hash: generatedKey,
|
|
511
|
+
value: trimmedValue,
|
|
512
|
+
uncodeValue: valStr,
|
|
513
|
+
namespace: nameSpace
|
|
514
|
+
};
|
|
515
|
+
if (option.translateExtends) {
|
|
516
|
+
const {
|
|
517
|
+
handleCodeCall,
|
|
518
|
+
handleCodeString
|
|
519
|
+
} = option.translateExtends;
|
|
520
|
+
return isExpression ? handleCodeCall(config, insertOption) : handleCodeString(config, insertOption);
|
|
521
|
+
}
|
|
522
|
+
if (isExpression) {
|
|
523
|
+
const valueExp = types.stringLiteral(trimmedValue);
|
|
524
|
+
valueExp.extra = {
|
|
525
|
+
raw: `'${valStr}'`,
|
|
526
|
+
// 防止转码为unicode
|
|
527
|
+
rawValue: trimmedValue
|
|
528
|
+
};
|
|
529
|
+
return option.useValueAsKey ? types.callExpression(types.identifier(option.translateKey), [valueExp]) : types.callExpression(types.identifier(option.translateKey), [types.stringLiteral(generatedKey), valueExp]);
|
|
530
|
+
} else {
|
|
531
|
+
return `${option.translateKey}('${generatedKey}','${valStr}')`;
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
function normalizeTranslateValue(value) {
|
|
535
|
+
const trimmedValue = option.isClearSpace ? value : value.trim();
|
|
536
|
+
const valStr = trimmedValue.replace(/'/g, '"').replace(/(\n)/g, '\\n');
|
|
537
|
+
return {
|
|
538
|
+
trimmedValue,
|
|
539
|
+
valStr
|
|
540
|
+
};
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
/**
|
|
544
|
+
* @description: 生成唯一id
|
|
545
|
+
* @param {string} key
|
|
546
|
+
* @return {*}
|
|
547
|
+
*/
|
|
548
|
+
function generateId(key) {
|
|
549
|
+
let hash = 0;
|
|
550
|
+
for (let i = 0; i < key.length; i++) {
|
|
551
|
+
const charCode = key.charCodeAt(i);
|
|
552
|
+
hash = (hash << 5) - hash + charCode;
|
|
553
|
+
hash = hash & hash;
|
|
554
|
+
}
|
|
555
|
+
const id = Math.abs(hash).toString(36) + key.length.toString(36);
|
|
556
|
+
return id;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
/**
|
|
560
|
+
* @description: unicode转普通字符串
|
|
561
|
+
* @param {string} str
|
|
562
|
+
* @return {*}
|
|
563
|
+
*/
|
|
564
|
+
const unicodeToString = str => {
|
|
565
|
+
return str.replace(/\\u[\dA-Fa-f]{4}/g, match => {
|
|
566
|
+
return String.fromCharCode(parseInt(match.replace(/\\u/g, ''), 16));
|
|
567
|
+
});
|
|
568
|
+
};
|
|
569
|
+
|
|
570
|
+
/**
|
|
571
|
+
* @description: 有道翻译 标识截取
|
|
572
|
+
* @param {string} q
|
|
573
|
+
* @return {*}
|
|
574
|
+
*/
|
|
575
|
+
function truncate(q) {
|
|
576
|
+
// 检查输入字符串的长度
|
|
577
|
+
if (q.length <= 20) {
|
|
578
|
+
// 如果长度小于等于20,直接返回原字符串
|
|
579
|
+
return q;
|
|
580
|
+
} else {
|
|
581
|
+
// 如果长度大于20,截取前10个字符和后10个字符,并在中间插入长度信息
|
|
582
|
+
const len = q.length;
|
|
583
|
+
return q.substring(0, 10) + len + q.substring(len - 10);
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
// 导出一个深拷贝函数,用于克隆对象
|
|
588
|
+
function cloneDeep(value) {
|
|
589
|
+
let cache = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : new WeakMap();
|
|
590
|
+
// 处理基本类型和 null
|
|
591
|
+
if (typeof value !== 'object' || value === null) {
|
|
592
|
+
return value;
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
// 处理循环引用
|
|
596
|
+
if (cache.has(value)) {
|
|
597
|
+
return cache.get(value);
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
// 处理特殊对象类型
|
|
601
|
+
if (value instanceof Date) {
|
|
602
|
+
return new Date(value);
|
|
603
|
+
}
|
|
604
|
+
if (value instanceof RegExp) {
|
|
605
|
+
return new RegExp(value.source, value.flags);
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
// 初始化克隆容器
|
|
609
|
+
const clone = Array.isArray(value) ? [] : {};
|
|
610
|
+
|
|
611
|
+
// 缓存对象防止循环引用
|
|
612
|
+
cache.set(value, clone);
|
|
613
|
+
|
|
614
|
+
// 处理 Symbol 和普通键的枚举
|
|
615
|
+
const keys = [...Object.keys(value), ...Object.getOwnPropertySymbols(value).filter(sym => value.propertyIsEnumerable(sym))];
|
|
616
|
+
|
|
617
|
+
// 递归克隆属性
|
|
618
|
+
for (const key of keys) {
|
|
619
|
+
clone[key] = cloneDeep(value[key], cache);
|
|
620
|
+
}
|
|
621
|
+
return clone;
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
var base = /*#__PURE__*/Object.freeze({
|
|
625
|
+
__proto__: null,
|
|
626
|
+
checkAgainstRegexArray: checkAgainstRegexArray,
|
|
627
|
+
cloneDeep: cloneDeep,
|
|
628
|
+
createI18nTranslator: createI18nTranslator,
|
|
629
|
+
extractCnStrings: extractCnStrings,
|
|
630
|
+
extractFunctionName: extractFunctionName,
|
|
631
|
+
extractStrings: extractStrings,
|
|
632
|
+
generateId: generateId,
|
|
633
|
+
getOriginRegex: getOriginRegex,
|
|
634
|
+
hasOriginSymbols: hasOriginSymbols,
|
|
635
|
+
normalizeTranslateValue: normalizeTranslateValue,
|
|
636
|
+
removeComments: removeComments,
|
|
637
|
+
truncate: truncate,
|
|
638
|
+
unicodeToString: unicodeToString
|
|
639
|
+
});
|
|
640
|
+
|
|
641
|
+
/*
|
|
642
|
+
* @Date: 2025-03-16 14:12:30
|
|
643
|
+
* @LastEditors: xiaoshan
|
|
644
|
+
* @LastEditTime: 2025-03-16 14:13:42
|
|
645
|
+
* @FilePath: /i18n_translation_vite/packages/autoI18nPluginCore/src/enums/option.ts
|
|
646
|
+
*/
|
|
647
|
+
/**
|
|
648
|
+
* 翻译类型枚举
|
|
649
|
+
*/
|
|
650
|
+
let TranslateTypeEnum = /*#__PURE__*/function (TranslateTypeEnum) {
|
|
651
|
+
TranslateTypeEnum["FULL_AUTO"] = "full-auto";
|
|
652
|
+
TranslateTypeEnum["SEMI_AUTO"] = "semi-auto";
|
|
653
|
+
return TranslateTypeEnum;
|
|
654
|
+
}({});
|
|
655
|
+
|
|
656
|
+
/*
|
|
657
|
+
* @Author: xiaoshanwen
|
|
658
|
+
* @Date: 2023-10-26 17:34:47
|
|
659
|
+
* @LastEditTime: 2025-03-31 19:58:37
|
|
660
|
+
* @FilePath: /i18n_translation_vite/packages/autoI18nPluginCore/src/option.ts
|
|
661
|
+
*/
|
|
662
|
+
|
|
663
|
+
/**
|
|
664
|
+
* 默认插件配置选项
|
|
665
|
+
*/
|
|
666
|
+
const DEFAULT_OPTION = {
|
|
667
|
+
appCode: '',
|
|
668
|
+
/** 是否启用插件,默认启用 */
|
|
669
|
+
enabled: true,
|
|
670
|
+
/** 翻译调用函数,默认为 $t */
|
|
671
|
+
translateKey: '$t',
|
|
672
|
+
/** 标记不翻译调用函数列表,避免某些调用被错误翻译 */
|
|
673
|
+
excludedCall: [],
|
|
674
|
+
/** 标记不用翻译的字符串模式数组,默认是匹配文件扩展名 */
|
|
675
|
+
excludedPattern: [/\.\w+$/],
|
|
676
|
+
/** 排查不需要翻译的目录下的文件路径(黑名单), 默认不处理node_modules */
|
|
677
|
+
excludedPath: ['node_modules'],
|
|
678
|
+
/** 指定需要翻译文件的目录路径正则(白名单) */
|
|
679
|
+
includePath: [/src\//, /src\\/],
|
|
680
|
+
/** 配置文件生成位置,默认为 './lang' */
|
|
681
|
+
globalPath: './lang',
|
|
682
|
+
/** 打包后生成文件的位置,例如 './dist/assets' */
|
|
683
|
+
distPath: '',
|
|
684
|
+
/** 打包后生成文件的主文件名称,默认是 'index' */
|
|
685
|
+
distKey: 'index',
|
|
686
|
+
/** 来源语言,默认是中文 */
|
|
687
|
+
originLang: OriginLangKeyEnum.ZH,
|
|
688
|
+
/** 翻译目标语言列表,默认包含英文 */
|
|
689
|
+
targetLangList: ['en'],
|
|
690
|
+
/** 语言key,用于请求谷歌api和生成配置文件下对应语言的内容文件 */
|
|
691
|
+
langKey: [],
|
|
692
|
+
/** 命名空间,防止全局命名冲突 */
|
|
693
|
+
namespace: 'lang',
|
|
694
|
+
/** 单位代码 */
|
|
695
|
+
orgCode: 'GREENCLOUD',
|
|
696
|
+
/** 是否启用源码的值作为key */
|
|
697
|
+
useValueAsKey: false,
|
|
698
|
+
/** 是否在构建结束之后将最新的翻译重新打包到主包中,默认不打包 */
|
|
699
|
+
buildToDist: false,
|
|
700
|
+
/** 是否启用上传翻译文件到服务器,默认开启 */
|
|
701
|
+
uploadEnabled: true,
|
|
702
|
+
/** 翻译器,决定自动翻译使用的api与调用方式,默认使用 Google 翻译器并使用7890(clash)端口代理 */
|
|
703
|
+
translator: new GoogleTranslator({
|
|
704
|
+
proxyOption: {
|
|
705
|
+
port: 7890,
|
|
706
|
+
host: '127.0.0.1',
|
|
707
|
+
headers: {
|
|
708
|
+
'User-Agent': 'Node'
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
}),
|
|
712
|
+
/** 翻译器配置选项,优先级低于translator */
|
|
713
|
+
translatorOption: undefined,
|
|
714
|
+
/**
|
|
715
|
+
* 翻译类型,支持全自动和半自动两种模式
|
|
716
|
+
* 全自动:所有翻译任务自动完成
|
|
717
|
+
* 半自动:需要人工标识,类似于 $t('key') 的方式
|
|
718
|
+
* 默认值为全自动
|
|
719
|
+
*/
|
|
720
|
+
translateType: TranslateTypeEnum.FULL_AUTO,
|
|
721
|
+
/**
|
|
722
|
+
* 是否重写配置文件,默认为true
|
|
723
|
+
*/
|
|
724
|
+
rewriteConfig: true,
|
|
725
|
+
/**
|
|
726
|
+
* 通用翻译key,默认使用namespace,如果commonTranslateKey不为空,则使用commonTranslateKey
|
|
727
|
+
*/
|
|
728
|
+
commonTranslateKey: '',
|
|
729
|
+
/**
|
|
730
|
+
* 实验性属性,表示是否进行深层扫描字符串,默认为 false
|
|
731
|
+
* 当设置为 true 时,会对代码中的字符串进行更深入的扫描
|
|
732
|
+
*/
|
|
733
|
+
deepScan: false,
|
|
734
|
+
/**
|
|
735
|
+
* 自定义文件拓展名数组
|
|
736
|
+
*/
|
|
737
|
+
insertFileExtensions: [],
|
|
738
|
+
/**
|
|
739
|
+
* 自定义拓展类,插件默认翻译函数挂载在window上,如果希望自定义翻译函数挂载在其他对象上,可以使用该属性
|
|
740
|
+
* 注意:该属性需要继承BaseExtends类,并且需要实现handleInitFile和handleCodeCall和handleCodeString方法
|
|
741
|
+
*/
|
|
742
|
+
translateExtends: null,
|
|
743
|
+
isClear: false,
|
|
744
|
+
// 是否清除已经不在上下文中的内容(清除项目中不再使用到的源语言键值对)
|
|
745
|
+
|
|
746
|
+
/**
|
|
747
|
+
* 是否保留空格
|
|
748
|
+
*/
|
|
749
|
+
isClearSpace: true
|
|
750
|
+
};
|
|
751
|
+
|
|
752
|
+
/**
|
|
753
|
+
* 类型定义:插件配置选项类型
|
|
754
|
+
*/
|
|
755
|
+
|
|
756
|
+
/**
|
|
757
|
+
* 全局插件配置实例,复制自默认配置
|
|
758
|
+
*/
|
|
759
|
+
let option = {
|
|
760
|
+
...DEFAULT_OPTION
|
|
761
|
+
};
|
|
762
|
+
|
|
763
|
+
/*
|
|
764
|
+
* @Author: xiaoshanwen
|
|
765
|
+
* @Date: 2023-10-30 18:23:03
|
|
766
|
+
* @LastEditTime: 2025-03-16 19:12:54
|
|
767
|
+
* @FilePath: /i18n_translation_vite/packages/autoI18nPluginCore/src/utils/translate.ts
|
|
768
|
+
*/
|
|
769
|
+
|
|
770
|
+
let langObj = {};
|
|
771
|
+
|
|
772
|
+
/**
|
|
773
|
+
* @description: 设置翻译对象属性
|
|
774
|
+
* @param {string} key
|
|
775
|
+
* @param {string} value
|
|
776
|
+
* @return {*}
|
|
777
|
+
*/
|
|
778
|
+
function setLangObj(key, value) {
|
|
779
|
+
if (!langObj[key]) {
|
|
780
|
+
langObj[key] = value;
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
/*
|
|
785
|
+
* @Date: 2025-03-26 20:28:21
|
|
786
|
+
* @LastEditors: xiaoshan
|
|
787
|
+
* @LastEditTime: 2025-03-31 10:29:49
|
|
788
|
+
* @FilePath: /i18n_translation_vite/packages/autoI18nPluginCore/src/utils/split.ts
|
|
789
|
+
*/
|
|
790
|
+
// 插件核心文件
|
|
791
|
+
// 字符串切割与转换函数
|
|
792
|
+
// import generate from '@babel/generator'
|
|
793
|
+
|
|
794
|
+
// todo 这个切割函数可以优化,性能可能很差
|
|
795
|
+
/**
|
|
796
|
+
* 根据正则表达式分割字符串,并将符合正则的连续字符拼接起来。
|
|
797
|
+
* @param str - 要分割的字符串。
|
|
798
|
+
* @param separatorRegex - 用于分割字符串的正则表达式。
|
|
799
|
+
* @returns 分割并拼接后的字符串数组。
|
|
800
|
+
*/
|
|
801
|
+
/**
|
|
802
|
+
* 这个函数的主要功能是根据给定的正则表达式分割字符串,并对分割结果进行特殊处理。
|
|
803
|
+
* 处理过程分为三个主要步骤:
|
|
804
|
+
*
|
|
805
|
+
* 1. 首先根据分隔符正则和标点符号正则进行初步分割
|
|
806
|
+
* 2. 然后将连续的标点符号和符合分隔符正则的部分重新连接
|
|
807
|
+
* 3. 最后将不符合分隔符正则的相邻部分合并
|
|
808
|
+
*
|
|
809
|
+
* @param str - 需要分割的源字符串
|
|
810
|
+
* @param separatorRegex - 用于分割的正则表达式
|
|
811
|
+
* @returns 处理后的字符串数组
|
|
812
|
+
*/
|
|
813
|
+
function splitByRegex(str, separatorRegex) {
|
|
814
|
+
if (str.includes('\n')) console.log(str, separatorRegex);
|
|
815
|
+
|
|
816
|
+
// 定义标点符号的正则表达式
|
|
817
|
+
const punctuationRegex = /[,。?!《》,..:!?""'';'"、0-9\n\r\t\v\f]/;
|
|
818
|
+
// 创建一个新的正则表达式,用于分割字符串
|
|
819
|
+
const splitRegex = new RegExp(`(${separatorRegex.source}|${punctuationRegex.source})`, separatorRegex.flags);
|
|
820
|
+
|
|
821
|
+
// 使用正则表达式分割字符串,并过滤掉空字符串
|
|
822
|
+
const splitArr = str.split(splitRegex).filter(Boolean);
|
|
823
|
+
const result = [];
|
|
824
|
+
let currentMatch = '';
|
|
825
|
+
|
|
826
|
+
// 定义连接标点符号的正则表达式
|
|
827
|
+
const connectPunctuationRegex = /[,。?!《》,..:!?;'"、0-9]/;
|
|
828
|
+
// 创建一个新的正则表达式,用于检测是否需要连接
|
|
829
|
+
const connectRegex = new RegExp(`(${separatorRegex.source}|${connectPunctuationRegex.source})`, separatorRegex.flags);
|
|
830
|
+
|
|
831
|
+
// 遍历分割后的数组
|
|
832
|
+
for (const item of splitArr) {
|
|
833
|
+
if (connectRegex.test(item)) {
|
|
834
|
+
// 如果当前项符合连接条件,则将其添加到当前匹配字符串中
|
|
835
|
+
currentMatch += item;
|
|
836
|
+
} else {
|
|
837
|
+
// 如果当前匹配字符串不为空,则将其添加到结果数组中
|
|
838
|
+
if (currentMatch) {
|
|
839
|
+
result.push(currentMatch);
|
|
840
|
+
currentMatch = '';
|
|
841
|
+
}
|
|
842
|
+
// 将当前项添加到结果数组中
|
|
843
|
+
result.push(item);
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
// 如果最后一个匹配字符串不为空,则将其添加到结果数组中
|
|
848
|
+
if (currentMatch) {
|
|
849
|
+
result.push(currentMatch);
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
// 再遍历一次,把不符合separatorRegex 这个正则的拼起来
|
|
853
|
+
const finalResult = [];
|
|
854
|
+
let tempStr = '';
|
|
855
|
+
for (let i = 0; i < result.length; i++) {
|
|
856
|
+
const item = result[i];
|
|
857
|
+
if (separatorRegex.test(item)) {
|
|
858
|
+
if (tempStr) {
|
|
859
|
+
finalResult.push(tempStr);
|
|
860
|
+
tempStr = '';
|
|
861
|
+
}
|
|
862
|
+
finalResult.push(item);
|
|
863
|
+
} else {
|
|
864
|
+
tempStr += item;
|
|
865
|
+
if (i === result.length - 1 || separatorRegex.test(result[i + 1])) {
|
|
866
|
+
finalResult.push(tempStr);
|
|
867
|
+
tempStr = '';
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
if (tempStr) {
|
|
872
|
+
finalResult.push(tempStr);
|
|
873
|
+
}
|
|
874
|
+
return finalResult;
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
/**
|
|
878
|
+
* 检查字符串是否需要切割。
|
|
879
|
+
* @param str - 要检查的字符串。
|
|
880
|
+
* @returns 如果字符串需要切割,则返回 true,否则返回 false。
|
|
881
|
+
*/
|
|
882
|
+
function checkNeedSplit(str) {
|
|
883
|
+
// 检查字符串中是否包含需要切割的特殊字符
|
|
884
|
+
return str.includes('\n') || str.includes('\\') || str.includes('\r') || str.includes('\t') || str.includes('\v') || str.includes('\f') || str.includes('>') || str.includes('<');
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
/**
|
|
888
|
+
* @description: 将字符串数组转换为babel的模板字符串节点
|
|
889
|
+
* @param {string[]} strArray - 字符串数组
|
|
890
|
+
* @return {types.CallExpression} - babel的深度扫描的表达式
|
|
891
|
+
*/
|
|
892
|
+
function convertToTemplateLiteral(strArray, option) {
|
|
893
|
+
const quasis = [];
|
|
894
|
+
const expressions = [];
|
|
895
|
+
strArray.forEach((str, index) => {
|
|
896
|
+
if (index === 0) {
|
|
897
|
+
if (getOriginRegex().test(str)) {
|
|
898
|
+
quasis.push(types__namespace.templateElement({
|
|
899
|
+
raw: '',
|
|
900
|
+
cooked: ''
|
|
901
|
+
}, false));
|
|
902
|
+
expressions.push(createI18nTranslator({
|
|
903
|
+
value: str,
|
|
904
|
+
isExpression: true,
|
|
905
|
+
insertOption: option
|
|
906
|
+
}));
|
|
907
|
+
} else {
|
|
908
|
+
quasis.push(types__namespace.templateElement({
|
|
909
|
+
raw: str,
|
|
910
|
+
cooked: str
|
|
911
|
+
}, false));
|
|
912
|
+
}
|
|
913
|
+
} else {
|
|
914
|
+
if (getOriginRegex().test(str)) {
|
|
915
|
+
expressions.push(createI18nTranslator({
|
|
916
|
+
value: str,
|
|
917
|
+
isExpression: true,
|
|
918
|
+
insertOption: option
|
|
919
|
+
}));
|
|
920
|
+
} else {
|
|
921
|
+
quasis.push(types__namespace.templateElement({
|
|
922
|
+
raw: str,
|
|
923
|
+
cooked: str
|
|
924
|
+
}, false));
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
});
|
|
928
|
+
if (quasis.length === expressions.length) {
|
|
929
|
+
quasis.push(types__namespace.templateElement({
|
|
930
|
+
raw: '',
|
|
931
|
+
cooked: ''
|
|
932
|
+
}, true));
|
|
933
|
+
} else if (quasis.length > expressions.length) {
|
|
934
|
+
quasis[quasis.length - 1].tail = true;
|
|
935
|
+
}
|
|
936
|
+
const templateLiteral = types__namespace.templateLiteral(quasis, expressions);
|
|
937
|
+
const deepScanCall = types__namespace.callExpression(types__namespace.identifier('$deepScan'), [templateLiteral]);
|
|
938
|
+
// 打印转换结果
|
|
939
|
+
// console.log('deepScanCall', (generate as any).default(deepScanCall).code)
|
|
940
|
+
return deepScanCall;
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
/*
|
|
944
|
+
* @Author: xiaoshanwen
|
|
945
|
+
* @Date: 2023-11-01 16:35:38
|
|
946
|
+
* @LastEditTime: 2025-03-31 02:29:02
|
|
947
|
+
* @FilePath: /i18n_translation_vite/packages/autoI18nPluginCore/src/filter/visitor/TemplateElement.ts
|
|
948
|
+
*/
|
|
949
|
+
|
|
950
|
+
// 定义一个包含亚洲语言代码的数组
|
|
951
|
+
const asianLangs = ['zh-cn', 'ja', 'ko'];
|
|
952
|
+
function TemplateLiteral (insertOption) {
|
|
953
|
+
return function (path) {
|
|
954
|
+
// 如果是半自动翻译,不做处理
|
|
955
|
+
if (option.translateType === TranslateTypeEnum.SEMI_AUTO) {
|
|
956
|
+
return;
|
|
957
|
+
}
|
|
958
|
+
let {
|
|
959
|
+
node,
|
|
960
|
+
parent
|
|
961
|
+
} = path;
|
|
962
|
+
if (!node.quasis.length) return;
|
|
963
|
+
if (types.isTaggedTemplateExpression(parent)) {
|
|
964
|
+
return;
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
// 获取真实调用函数
|
|
968
|
+
const extractFnName = extractFunctionName(parent);
|
|
969
|
+
|
|
970
|
+
// 调用语句判断当前调用语句是否包含需要过滤的调用语句
|
|
971
|
+
if (types.isCallExpression(parent) && extractFnName && (option.excludedCall.includes(extractFnName) || extractFnName?.split('.')?.pop() && option.excludedCall.includes(extractFnName?.split('.')?.pop() || ''))) return;
|
|
972
|
+
if (node.expressions.length && handleTemplateLiteralWithExpressions(node, path)) {
|
|
973
|
+
return;
|
|
974
|
+
}
|
|
975
|
+
node.quasis.forEach(item => handleTemplateElement(item, insertOption));
|
|
976
|
+
};
|
|
977
|
+
}
|
|
978
|
+
function handleTemplateLiteralWithExpressions(node, path) {
|
|
979
|
+
const placeholders = node.expressions.map(expression => getExpressionPlaceholder(expression));
|
|
980
|
+
if (placeholders.some(placeholder => !placeholder)) {
|
|
981
|
+
return false;
|
|
982
|
+
}
|
|
983
|
+
const fullValue = node.quasis.reduce((result, quasi, index) => {
|
|
984
|
+
let value = quasi.value.raw || quasi.value.cooked || '';
|
|
985
|
+
if (asianLangs.some(lang => option.originLang.includes(lang) || option.originLang === lang)) {
|
|
986
|
+
try {
|
|
987
|
+
value = unicodeToString(value);
|
|
988
|
+
} catch (error) {
|
|
989
|
+
console.log('转换异常');
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
return result + value + (index < node.expressions.length ? `\${${placeholders[index]}}` : '');
|
|
993
|
+
}, '');
|
|
994
|
+
if (!fullValue || !hasOriginSymbols(fullValue) || !option.excludedPattern.length || checkAgainstRegexArray(fullValue, [...option.excludedPattern])) {
|
|
995
|
+
return false;
|
|
996
|
+
}
|
|
997
|
+
const {
|
|
998
|
+
trimmedValue,
|
|
999
|
+
valStr
|
|
1000
|
+
} = normalizeTranslateValue(fullValue);
|
|
1001
|
+
const id = generateId(valStr);
|
|
1002
|
+
const translateNode = createTranslateNode(path, id, valStr, placeholders, node.expressions);
|
|
1003
|
+
path.replaceWith(translateNode);
|
|
1004
|
+
path.skip();
|
|
1005
|
+
setLangObj(id, trimmedValue);
|
|
1006
|
+
return true;
|
|
1007
|
+
}
|
|
1008
|
+
function getExpressionPlaceholder(expression) {
|
|
1009
|
+
if (types.isIdentifier(expression)) {
|
|
1010
|
+
return expression.name;
|
|
1011
|
+
}
|
|
1012
|
+
if (types.isMemberExpression(expression)) {
|
|
1013
|
+
const objectName = getExpressionPlaceholder(expression.object);
|
|
1014
|
+
const propertyName = expression.computed ? getExpressionPlaceholder(expression.property) : types.isIdentifier(expression.property) ? expression.property.name : '';
|
|
1015
|
+
const value = [objectName, propertyName].filter(Boolean).join('.');
|
|
1016
|
+
return cleanVueRuntimePrefix(value);
|
|
1017
|
+
}
|
|
1018
|
+
if (types.isStringLiteral(expression) || types.isNumericLiteral(expression)) {
|
|
1019
|
+
return String(expression.value);
|
|
1020
|
+
}
|
|
1021
|
+
if (types.isTSAsExpression(expression) || types.isTSTypeAssertion(expression)) {
|
|
1022
|
+
return getExpressionPlaceholder(expression.expression);
|
|
1023
|
+
}
|
|
1024
|
+
if (types.isTSNonNullExpression(expression)) {
|
|
1025
|
+
return getExpressionPlaceholder(expression.expression);
|
|
1026
|
+
}
|
|
1027
|
+
const generateCode = generate__namespace.default?.default || generate__namespace.default || generate__namespace;
|
|
1028
|
+
return cleanVueRuntimePrefix(generateCode(expression).code);
|
|
1029
|
+
}
|
|
1030
|
+
function createTranslateNode(path, id, valStr) {
|
|
1031
|
+
let placeholders = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : [];
|
|
1032
|
+
let expressions = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : [];
|
|
1033
|
+
const args = [types.stringLiteral(id), types.stringLiteral(valStr)];
|
|
1034
|
+
if (placeholders.length) {
|
|
1035
|
+
args.push(types.objectExpression(placeholders.map((placeholder, index) => types.objectProperty(types.stringLiteral(placeholder), types.cloneNode(expressions[index])))));
|
|
1036
|
+
}
|
|
1037
|
+
const translateCall = types.callExpression(types.identifier(option.translateKey), args);
|
|
1038
|
+
if (!isVueTemplateRender(path)) {
|
|
1039
|
+
return translateCall;
|
|
1040
|
+
}
|
|
1041
|
+
return types.sequenceExpression([createVueTemplateLanguageDependency(), translateCall]);
|
|
1042
|
+
}
|
|
1043
|
+
function isVueTemplateRender(path) {
|
|
1044
|
+
return Boolean(path.scope?.getBinding('_vm'));
|
|
1045
|
+
}
|
|
1046
|
+
function createVueTemplateLanguageDependency() {
|
|
1047
|
+
const vm = types.identifier('_vm');
|
|
1048
|
+
const store = types.memberExpression(types.cloneNode(vm), types.identifier('$store'));
|
|
1049
|
+
const storeState = types.memberExpression(types.cloneNode(store), types.identifier('state'));
|
|
1050
|
+
const siteState = types.memberExpression(types.cloneNode(storeState), types.identifier('site'));
|
|
1051
|
+
const storeLanguage = types.logicalExpression('&&', types.logicalExpression('&&', types.logicalExpression('&&', types.cloneNode(store), types.cloneNode(storeState)), types.cloneNode(siteState)), types.memberExpression(types.cloneNode(siteState), types.identifier('language')));
|
|
1052
|
+
const i18n = types.memberExpression(types.cloneNode(vm), types.identifier('$i18n'));
|
|
1053
|
+
const i18nLocale = types.logicalExpression('&&', types.cloneNode(i18n), types.memberExpression(types.cloneNode(i18n), types.identifier('locale')));
|
|
1054
|
+
return types.logicalExpression('||', storeLanguage, i18nLocale);
|
|
1055
|
+
}
|
|
1056
|
+
function cleanVueRuntimePrefix(value) {
|
|
1057
|
+
return value.replace(/^(?:\$setup|_ctx|_vm|this)\./, '').replace(/([^\w$.])(?:\$setup|_ctx|_vm|this)\./g, '$1');
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
// 处理模板元素
|
|
1061
|
+
function handleTemplateElement(node, insertOption) {
|
|
1062
|
+
let value = node.value.raw || node.value.cooked; // 获取模板字符串的值
|
|
1063
|
+
if (asianLangs.some(lang => option.originLang.includes(lang) || option.originLang === lang)) {
|
|
1064
|
+
try {
|
|
1065
|
+
value = unicodeToString(value || '');
|
|
1066
|
+
} catch (error) {
|
|
1067
|
+
console.log('转换异常');
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
// 是否存在来源语言字符,是否在默认字符串中,是否包含过滤字段
|
|
1071
|
+
if (value && hasOriginSymbols(value) && option.excludedPattern.length && !checkAgainstRegexArray(value, [...option.excludedPattern])) {
|
|
1072
|
+
// 生成字符类型翻译节点
|
|
1073
|
+
let newNode = createI18nTranslator({
|
|
1074
|
+
insertOption,
|
|
1075
|
+
value
|
|
1076
|
+
});
|
|
1077
|
+
|
|
1078
|
+
// 替换为字符类型翻译节点
|
|
1079
|
+
node.value.raw = node.value.cooked = `\${${newNode}}`;
|
|
1080
|
+
const {
|
|
1081
|
+
valStr
|
|
1082
|
+
} = normalizeTranslateValue(value);
|
|
1083
|
+
let id = generateId(valStr);
|
|
1084
|
+
if (id && value) {
|
|
1085
|
+
setLangObj(id, value);
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
/*
|
|
1091
|
+
* @Author: xiaoshanwen
|
|
1092
|
+
* @Date: 2023-10-12 18:18:51
|
|
1093
|
+
* @LastEditTime: 2025-03-16 15:17:30
|
|
1094
|
+
* @FilePath: /i18n_translation_vite/packages/autoI18nPluginCore/src/filter/visitor/CallExpression.ts
|
|
1095
|
+
*/
|
|
1096
|
+
|
|
1097
|
+
// 收集翻译对象
|
|
1098
|
+
function CallExpressionFn (insertOption) {
|
|
1099
|
+
return function (path) {
|
|
1100
|
+
let {
|
|
1101
|
+
node
|
|
1102
|
+
} = path;
|
|
1103
|
+
// 提取公共部分,减少重复访问 node.callee 属性
|
|
1104
|
+
const callee = node.callee;
|
|
1105
|
+
if (callee.name === option.translateKey || callee.property && callee.property.name === option.translateKey // 拓展 半自动模式下的 如 a.b.c() 调用
|
|
1106
|
+
) {
|
|
1107
|
+
if (option.translateType === TranslateTypeEnum.SEMI_AUTO) {
|
|
1108
|
+
// 获取当前翻译函数的参数
|
|
1109
|
+
let arg = node.arguments || [];
|
|
1110
|
+
// 如果参数数量不为 1,则直接返回
|
|
1111
|
+
if (arg.length === 1) {
|
|
1112
|
+
const value = arg[0]?.value || '';
|
|
1113
|
+
// 生成真实调用函数
|
|
1114
|
+
const replaceNode = createI18nTranslator({
|
|
1115
|
+
insertOption,
|
|
1116
|
+
value,
|
|
1117
|
+
isExpression: true
|
|
1118
|
+
});
|
|
1119
|
+
path.replaceWith(replaceNode);
|
|
1120
|
+
translateSetLang(replaceNode);
|
|
1121
|
+
}
|
|
1122
|
+
} else if (option.translateType === TranslateTypeEnum.FULL_AUTO) {
|
|
1123
|
+
// 全自动模式下还是只收集 单独 $t 调用
|
|
1124
|
+
if (callee.name === option.translateKey || callee.property && callee.property.name === option.translateKey) translateSetLang(node);
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
};
|
|
1128
|
+
}
|
|
1129
|
+
|
|
1130
|
+
/**
|
|
1131
|
+
* @description: 处理翻译并设置语言对象属性
|
|
1132
|
+
* @param node - 调用表达式节点
|
|
1133
|
+
* @return
|
|
1134
|
+
*/
|
|
1135
|
+
function translateSetLang(node) {
|
|
1136
|
+
// 获取调用表达式的参数
|
|
1137
|
+
let arg = node.arguments || [];
|
|
1138
|
+
// 提取参数作为值
|
|
1139
|
+
// 检查参数是否为字符串字面量
|
|
1140
|
+
const id = types__namespace.isStringLiteral(arg[0]) ? arg[0].value : '';
|
|
1141
|
+
const value = types__namespace.isStringLiteral(arg[1]) ? arg[1].value : '';
|
|
1142
|
+
// 检查 ID 和值是否存在,并且第二个参数是字符串字面量
|
|
1143
|
+
if (id && value && types__namespace.isStringLiteral(arg[1])) {
|
|
1144
|
+
// 调用翻译工具的 setLangObj 方法设置语言对象属性
|
|
1145
|
+
setLangObj(id, value);
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
/*
|
|
1150
|
+
* @Author: xiaoshanwen
|
|
1151
|
+
* @Date: 2023-10-12 18:18:51
|
|
1152
|
+
* @LastEditTime: 2025-03-31 02:28:53
|
|
1153
|
+
* @FilePath: /i18n_translation_vite/packages/autoI18nPluginCore/src/filter/visitor/StringLiteral.ts
|
|
1154
|
+
*/
|
|
1155
|
+
function StringLiteralFn (insertOption) {
|
|
1156
|
+
return function (path) {
|
|
1157
|
+
if (option.translateType === TranslateTypeEnum.SEMI_AUTO) {
|
|
1158
|
+
return;
|
|
1159
|
+
}
|
|
1160
|
+
let {
|
|
1161
|
+
node,
|
|
1162
|
+
parent
|
|
1163
|
+
} = path;
|
|
1164
|
+
let value = node.value;
|
|
1165
|
+
|
|
1166
|
+
// 定义一个包含亚洲语言代码的数组
|
|
1167
|
+
const asianLangs = ['zh-cn', 'ja', 'ko'];
|
|
1168
|
+
if (asianLangs.some(lang => option.originLang.includes(lang) || option.originLang === lang)) {
|
|
1169
|
+
try {
|
|
1170
|
+
value = unicodeToString(value);
|
|
1171
|
+
} catch (error) {
|
|
1172
|
+
console.log('转换异常');
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
1175
|
+
if (hasOriginSymbols(value) && option.excludedPattern.length && !checkAgainstRegexArray(value, [...option.excludedPattern])) {
|
|
1176
|
+
// 获取真实调用函数
|
|
1177
|
+
const extractFnName = extractFunctionName(parent);
|
|
1178
|
+
|
|
1179
|
+
// 防止导入语句,只处理那些当前节点不是键值对的键的字符串字面量,调用语句判断当前调用语句是否包含需要过滤的调用语句
|
|
1180
|
+
if (isTranslateCall(parent) || types__namespace.isImportDeclaration(parent) || parent.key === node || types__namespace.isCallExpression(parent) && extractFnName && (option.excludedCall.includes(extractFnName) || extractFnName?.split('.')?.pop() && option.excludedCall.includes(extractFnName?.split('.')?.pop() || ''))) return;
|
|
1181
|
+
let replaceNode;
|
|
1182
|
+
if (option.deepScan && checkNeedSplit(value)) {
|
|
1183
|
+
replaceNode = convertToTemplateLiteral(splitByRegex(value, getOriginRegex()), insertOption);
|
|
1184
|
+
} else if (types__namespace.isJSXAttribute(parent)) {
|
|
1185
|
+
let expression = createI18nTranslator({
|
|
1186
|
+
insertOption,
|
|
1187
|
+
value,
|
|
1188
|
+
isExpression: true
|
|
1189
|
+
});
|
|
1190
|
+
replaceNode = types__namespace.jSXExpressionContainer(expression);
|
|
1191
|
+
} else {
|
|
1192
|
+
replaceNode = createI18nTranslator({
|
|
1193
|
+
insertOption,
|
|
1194
|
+
value,
|
|
1195
|
+
isExpression: true
|
|
1196
|
+
});
|
|
1197
|
+
}
|
|
1198
|
+
path.replaceWith(replaceNode);
|
|
1199
|
+
}
|
|
1200
|
+
};
|
|
1201
|
+
}
|
|
1202
|
+
function isTranslateCall(node) {
|
|
1203
|
+
if (!types__namespace.isCallExpression(node)) return false;
|
|
1204
|
+
const callee = node.callee;
|
|
1205
|
+
if (types__namespace.isIdentifier(callee)) {
|
|
1206
|
+
return callee.name === option.translateKey;
|
|
1207
|
+
}
|
|
1208
|
+
if (types__namespace.isMemberExpression(callee)) {
|
|
1209
|
+
return types__namespace.isIdentifier(callee.property) && callee.property.name === option.translateKey;
|
|
1210
|
+
}
|
|
1211
|
+
return false;
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1214
|
+
/*
|
|
1215
|
+
* @Author: xiaoshanwen
|
|
1216
|
+
* @Date: 2023-11-01 16:35:38
|
|
1217
|
+
* @LastEditTime: 2025-03-16 18:24:44
|
|
1218
|
+
* @FilePath: /i18n_translation_vite/packages/autoI18nPluginCore/src/filter/visitor/JSXText.ts
|
|
1219
|
+
*/
|
|
1220
|
+
function JSXTextFn (insertOption) {
|
|
1221
|
+
return function (path) {
|
|
1222
|
+
console.log('jsx text');
|
|
1223
|
+
if (option.translateType === TranslateTypeEnum.SEMI_AUTO) {
|
|
1224
|
+
return;
|
|
1225
|
+
}
|
|
1226
|
+
let {
|
|
1227
|
+
node
|
|
1228
|
+
} = path;
|
|
1229
|
+
let value = node.value;
|
|
1230
|
+
// 定义一个包含亚洲语言代码的数组
|
|
1231
|
+
const asianLangs = ['zh-cn', 'ja', 'ko'];
|
|
1232
|
+
if (asianLangs.some(lang => option.originLang.includes(lang) || option.originLang === lang)) {
|
|
1233
|
+
try {
|
|
1234
|
+
value = unicodeToString(value);
|
|
1235
|
+
} catch (error) {
|
|
1236
|
+
console.log('转换异常');
|
|
1237
|
+
}
|
|
1238
|
+
}
|
|
1239
|
+
if (hasOriginSymbols(value) && option.excludedPattern.length && !checkAgainstRegexArray(value, [...option.excludedPattern])) {
|
|
1240
|
+
// 生成翻译节点
|
|
1241
|
+
let expression = createI18nTranslator({
|
|
1242
|
+
insertOption,
|
|
1243
|
+
value,
|
|
1244
|
+
isExpression: true
|
|
1245
|
+
});
|
|
1246
|
+
// 生成的翻译节点包装在 types.JSXExpressionContainer 中
|
|
1247
|
+
let newNode = types__namespace.jSXExpressionContainer(expression);
|
|
1248
|
+
// 使用 path.replaceWith 方法将原来的节点替换为新的翻译节点
|
|
1249
|
+
path.replaceWith(newNode);
|
|
1250
|
+
}
|
|
1251
|
+
};
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1254
|
+
/*
|
|
1255
|
+
* @Author: xiaoshanwen
|
|
1256
|
+
* @Date: 2023-10-12 18:00:37
|
|
1257
|
+
* @LastEditTime: 2023-11-02 10:36:02
|
|
1258
|
+
* @FilePath: /i18n_translation_vite/src/plugins/filter/index.ts
|
|
1259
|
+
*/
|
|
1260
|
+
|
|
1261
|
+
function index (insertOption) {
|
|
1262
|
+
// 分别调用各个访问器函数并传入插入选项
|
|
1263
|
+
const stringLiteralVisitor = StringLiteralFn(insertOption);
|
|
1264
|
+
const jsxTextVisitor = JSXTextFn(insertOption);
|
|
1265
|
+
const templateLiteralVisitor = TemplateLiteral(insertOption);
|
|
1266
|
+
const callExpressionVisitor = CallExpressionFn(insertOption);
|
|
1267
|
+
|
|
1268
|
+
// 返回一个函数,该函数返回包含访问器的对象
|
|
1269
|
+
return function () {
|
|
1270
|
+
return {
|
|
1271
|
+
// 定义 Babel 访问器对象
|
|
1272
|
+
visitor: {
|
|
1273
|
+
StringLiteral: stringLiteralVisitor,
|
|
1274
|
+
JSXText: jsxTextVisitor,
|
|
1275
|
+
TemplateLiteral: templateLiteralVisitor,
|
|
1276
|
+
CallExpression: callExpressionVisitor
|
|
1277
|
+
}
|
|
1278
|
+
};
|
|
1279
|
+
};
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1282
|
+
var index$1 = /*#__PURE__*/Object.freeze({
|
|
1283
|
+
__proto__: null,
|
|
1284
|
+
default: index
|
|
1285
|
+
});
|
|
1286
|
+
|
|
1287
|
+
/*
|
|
1288
|
+
* @Date: 2025-01-08 11:51:33
|
|
1289
|
+
* @LastEditors: xiaoshan
|
|
1290
|
+
* @LastEditTime: 2025-02-14 01:02:04
|
|
1291
|
+
* @FilePath: /i18n_translation_vite/packages/webpackPluginsAutoI18n/src/customLoader/index.ts
|
|
1292
|
+
*/
|
|
1293
|
+
/**
|
|
1294
|
+
* @description: 核心 Loader,用于解析和处理代码,将目标语言提取为国际化的 key-value 映射
|
|
1295
|
+
* @param source {string} - 源代码字符串,需要经过当前 Loader 处理的模块内容
|
|
1296
|
+
* @returns {string} - 返回经过处理后的代码
|
|
1297
|
+
*/
|
|
1298
|
+
module.exports = function (source) {
|
|
1299
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
1300
|
+
var baseUtils, option$1, filter, global, sourceObj, result, e_1;
|
|
1301
|
+
var _a;
|
|
1302
|
+
return __generator(this, function (_b) {
|
|
1303
|
+
switch (_b.label) {
|
|
1304
|
+
case 0:
|
|
1305
|
+
baseUtils = base, option$1 = option, filter = index$1;
|
|
1306
|
+
global = this;
|
|
1307
|
+
/**
|
|
1308
|
+
* 黑白名单过滤:
|
|
1309
|
+
* - 首先检查是否在 `includePath` 白名单内;如果不在白名单内直接返回原代码。
|
|
1310
|
+
* - 然后检查是否在 `excludedPath` 黑名单内;如果在黑名单内则返回原代码。
|
|
1311
|
+
*/
|
|
1312
|
+
if (option$1.includePath.length && !baseUtils.checkAgainstRegexArray(global.resourcePath, option$1.includePath)) {
|
|
1313
|
+
return [2 /*return*/, source]; // 不在白名单目录中的文件,不处理,直接返回原始代码。
|
|
1314
|
+
}
|
|
1315
|
+
if (option$1.excludedPath.length && baseUtils.checkAgainstRegexArray(global.resourcePath, option$1.excludedPath)) {
|
|
1316
|
+
return [2 /*return*/, source]; // 在黑名单目录中的文件,不处理,直接返回原始代码。
|
|
1317
|
+
}
|
|
1318
|
+
if (!option$1.translateExtends) return [3 /*break*/, 2];
|
|
1319
|
+
return [4 /*yield*/, (_a = option$1.translateExtends) === null || _a === void 0 ? void 0 : _a.handleInitFile(source, global.resourcePath)];
|
|
1320
|
+
case 1:
|
|
1321
|
+
sourceObj = _b.sent();
|
|
1322
|
+
return [3 /*break*/, 3];
|
|
1323
|
+
case 2:
|
|
1324
|
+
sourceObj = {
|
|
1325
|
+
source: source
|
|
1326
|
+
};
|
|
1327
|
+
_b.label = 3;
|
|
1328
|
+
case 3:
|
|
1329
|
+
_b.trys.push([3, 5,, 6]);
|
|
1330
|
+
return [4 /*yield*/, babel__namespace.transformAsync(sourceObj.source, {
|
|
1331
|
+
configFile: false,
|
|
1332
|
+
// 不加载本地 Babel 配置文件
|
|
1333
|
+
plugins: [filter.default(sourceObj)] // 使用核心模块提供的 `filter` 插件
|
|
1334
|
+
})
|
|
1335
|
+
// 如果转换成功,返回转换后的代码;否则返回空字符串。
|
|
1336
|
+
];
|
|
1337
|
+
case 4:
|
|
1338
|
+
result = _b.sent();
|
|
1339
|
+
// 如果转换成功,返回转换后的代码;否则返回空字符串。
|
|
1340
|
+
return [2 /*return*/, (result === null || result === void 0 ? void 0 : result.code) || ''];
|
|
1341
|
+
case 5:
|
|
1342
|
+
e_1 = _b.sent();
|
|
1343
|
+
// 捕捉和打印异常,保证整个构建过程不会中断
|
|
1344
|
+
console.error(e_1);
|
|
1345
|
+
return [3 /*break*/, 6];
|
|
1346
|
+
case 6:
|
|
1347
|
+
// 如果在过滤或转换过程中发生异常,返回原始未改动的代码
|
|
1348
|
+
return [2 /*return*/, source];
|
|
1349
|
+
}
|
|
1350
|
+
});
|
|
1351
|
+
});
|
|
1352
|
+
};
|
|
2
1353
|
//# sourceMappingURL=index.cjs.map
|