vue-i18n-extract-plugin 1.0.75 → 1.0.77

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.
Files changed (2) hide show
  1. package/lib/visitors.js +74 -24
  2. package/package.json +1 -1
package/lib/visitors.js CHANGED
@@ -182,6 +182,7 @@ function unwrapVueCacheCallIfNeeded(path) {
182
182
  return false;
183
183
  }
184
184
 
185
+ normalizeVNodePatchFlag(assignPath.node.right);
185
186
  // 用 createTextVNode(...) 替换整个 _cache || (...)
186
187
  logicalPath.replaceWith(assignPath.node.right);
187
188
  return true;
@@ -213,23 +214,93 @@ function unwrapVueSlotArrayCache(path) {
213
214
 
214
215
  if (!isCache) return false;
215
216
 
217
+ // 删除 array 里的 vnode参数-1
218
+ arrayPath.node.elements.forEach(el => {
219
+ normalizeVNodePatchFlag(el);
220
+ });
221
+
216
222
  // unwrap:用 array.elements 替换 spread(...)
217
223
  spreadPath.replaceWithMultiple(arrayPath.node.elements);
218
224
 
219
225
  return true;
220
226
  }
221
227
 
228
+ function normalizeVNodePatchFlag(node) {
229
+ const path = { node, isCallExpression: () => t.isCallExpression(node) };
230
+ if (!isAnyVNodeCall(path)) return;
231
+ if (isVNodeCall(path, "_createTextVNode")) return;
232
+
233
+ const args = node.arguments;
234
+ if (!args || args.length < 4) return;
235
+
236
+ const flag = args[3];
237
+ if (t.isNumericLiteral(flag) && flag.value !== -1) {
238
+ return;
239
+ }
240
+ args.splice(3, 1); // 删除第4个参数 -1
241
+ }
242
+
222
243
  function isDynamicTextExpression(node) {
223
244
  // 只要不是 StringLiteral,100% 是动态文本
224
245
  return !t.isStringLiteral(node);
225
246
  }
226
247
 
248
+ function unwrapNearestCacheBoundary(path) {
249
+ let p = path.parentPath;
250
+
251
+ while (p) {
252
+ // 先拆[..._cache2[0] || (_cache2[0] = [createBaseVNode(...)])]
253
+ if (!unwrapVueSlotArrayCache(p)) {
254
+ // 再尝试拆 _cache2[0] || (_cache2[0] = createTextVNode(...))
255
+ unwrapVueCacheCallIfNeeded(p);
256
+ }
257
+ p = p.parentPath;
258
+ }
259
+ }
260
+
261
+ const VNODE_CALLS = new Set([
262
+ "_createTextVNode",
263
+ "_createElementVNode",
264
+ "_createElementBlock",
265
+ "_createVNode",
266
+ "_createBlock",
267
+ "_createBaseVNode",
268
+ "_createStaticVNode"
269
+ ]);
270
+
271
+ function isAnyVNodeCall(path) {
272
+ if (!path.isCallExpression()) return false;
273
+
274
+ const callee = path.node.callee;
275
+
276
+ if (t.isIdentifier(callee)) {
277
+ return VNODE_CALLS.has(callee.name);
278
+ }
279
+
280
+ if (t.isMemberExpression(callee) && t.isIdentifier(callee.property)) {
281
+ return VNODE_CALLS.has(callee.property.name);
282
+ }
283
+
284
+ return false;
285
+ }
286
+
227
287
  function createI18nVisitor(option, i18nMap) {
228
288
  const excludedCall = [...option.excludedCall, ...EXCLUDED_CALL];
229
289
 
230
290
  return {
231
291
  CallExpression(path) {
232
- if (!isTFunction(path.node, option)) return;
292
+ if (!isTFunction(path.node, option)) {
293
+ if (isVNodeCall(path, "_createTextVNode")) {
294
+ const args = path.node.arguments;
295
+ if (!args.length) return;
296
+ const content = args[0];
297
+ // 是否动态文本
298
+ if (isDynamicTextExpression(content)) {
299
+ args[1] = t.numericLiteral(1); // PatchFlags.TEXT createTextVNode(" " + toDisplayString$1(text)) => createTextVNode(" " + toDisplayString$1(text), 1)
300
+ }
301
+ }
302
+ return;
303
+ }
233
304
 
234
305
  const [firstArg] = path.node.arguments;
235
306
  let keyText = null;
@@ -261,19 +332,6 @@ function createI18nVisitor(option, i18nMap) {
261
332
  path.node.arguments.push(t.stringLiteral(keyText));
262
333
  }
263
334
  },
264
- CallExpression(path) {
265
- if (!isVNodeCall(path, "_createTextVNode")) return;
266
-
267
- const args = path.node.arguments;
268
- if (!args.length) return;
269
-
270
- const content = args[0];
271
-
272
- // 是否动态文本
273
- if (isDynamicTextExpression(content)) {
274
- args[1] = t.numericLiteral(1); // PatchFlags.TEXT createTextVNode(" " + toDisplayString$1(text)) => createTextVNode(" " + toDisplayString$1(text), 1)
275
- }
276
- },
277
335
  StringLiteral(path) {
278
336
  if (option.extractFromText === false) return;
279
337
  if (!shouldTransform(path)) return;
@@ -341,11 +399,7 @@ function createI18nVisitor(option, i18nMap) {
341
399
  if (isVNodeCall(parentPath, "_createTextVNode")) {
342
400
  // createTextVNode强制补充第二个参数 1
343
401
  parentPath.node.arguments = [callExpression, t.numericLiteral(1)];
344
- // 先尝试 [...(_cache2[4] || (_cache2[4] = [ createTextVNode(...) ]))]
345
- if (!unwrapVueSlotArrayCache(parentPath)) {
346
- // 再尝试拆 _cache2[0] || (_cache2[0] = createTextVNode(...))
347
- unwrapVueCacheCallIfNeeded(parentPath);
348
- }
402
+ unwrapNearestCacheBoundary(path);
349
403
  // 是否 vue.createElementVNode(...),且该 StringLiteral 是第三个参数
350
404
  } else if (
351
405
  isVNodeCall(parentPath, "_createElementVNode") ||
@@ -363,11 +417,7 @@ function createI18nVisitor(option, i18nMap) {
363
417
  } else {
364
418
  args[3] = t.numericLiteral(1);
365
419
  }
366
- // 先尝试 [...(_cache2[4] || (_cache2[4] = [ createTextVNode(...) ]))]
367
- if (!unwrapVueSlotArrayCache(parentPath)) {
368
- // 再尝试拆 _cache2[0] || (_cache2[0] = createTextVNode(...))
369
- unwrapVueCacheCallIfNeeded(parentPath);
370
- }
420
+ unwrapNearestCacheBoundary(path);
371
421
  }
372
422
  } else {
373
423
  const hasCreateVNode = transformDirectiveIfNeeded(path, parentPath);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vue-i18n-extract-plugin",
3
- "version": "1.0.75",
3
+ "version": "1.0.77",
4
4
  "main": "lib/index.js",
5
5
  "types": "types/index.d.ts",
6
6
  "bin": {