vue-i18n-extract-plugin 1.0.70 → 1.0.71

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 +56 -5
  2. package/package.json +1 -1
package/lib/visitors.js CHANGED
@@ -56,6 +56,7 @@ function getPropKey(propNode) {
56
56
  return null;
57
57
  }
58
58
 
59
+ // 将静态属性转换为动态属性,如 <div title="xxx" /> => <div :title="$t('hashed')" />
59
60
  function transformDirectiveIfNeeded(path, parentPath) {
60
61
  let hasCreateVNode = false;
61
62
  // 属性值情况,如 title: "xxx"
@@ -152,6 +153,45 @@ function generateJSXElement(name, id, msg) {
152
153
  return t.jsxElement(openingElement, null, [], true);
153
154
  }
154
155
 
156
+ function unwrapVueCacheIfNeeded(path) {
157
+ const assignPath = path.parentPath;
158
+ if (!assignPath || !assignPath.isAssignmentExpression({ operator: "=" })) {
159
+ return false;
160
+ }
161
+
162
+ const logicalPath = assignPath.parentPath;
163
+ if (!logicalPath || !logicalPath.isLogicalExpression({ operator: "||" })) {
164
+ return false;
165
+ }
166
+
167
+ const { left, right } = logicalPath.node;
168
+
169
+ // 校验 left: _cache[x]
170
+ const isCacheMember =
171
+ t.isMemberExpression(left) &&
172
+ (t.isIdentifier(left.object, { name: "_cache" }) ||
173
+ (t.isIdentifier(left.object) && left.object.name.startsWith("_cache")));
174
+
175
+ // 校验 right: (_cache[x] = createTextVNode(...))
176
+ const isSameAssignment =
177
+ right === assignPath.node &&
178
+ t.isMemberExpression(assignPath.node.left) &&
179
+ t.isCallExpression(assignPath.node.right);
180
+
181
+ if (!isCacheMember || !isSameAssignment) {
182
+ return false;
183
+ }
184
+
185
+ // 用 createTextVNode(...) 替换整个 _cache || (...)
186
+ logicalPath.replaceWith(assignPath.node.right);
187
+ return true;
188
+ }
189
+
190
+ function isDynamicTextExpression(node) {
191
+ // 只要不是 StringLiteral,100% 是动态文本
192
+ return !t.isStringLiteral(node);
193
+ }
194
+
155
195
  function createI18nVisitor(option, i18nMap) {
156
196
  const excludedCall = [...option.excludedCall, ...EXCLUDED_CALL];
157
197
 
@@ -189,7 +229,19 @@ function createI18nVisitor(option, i18nMap) {
189
229
  path.node.arguments.push(t.stringLiteral(keyText));
190
230
  }
191
231
  },
232
+ CallExpression(path) {
233
+ if (!isVNodeCall(path, "_createTextVNode")) return;
234
+
235
+ const args = path.node.arguments;
236
+ if (!args.length) return;
192
237
 
238
+ const content = args[0];
239
+
240
+ // 是否动态文本
241
+ if (isDynamicTextExpression(content)) {
242
+ args[1] = t.numericLiteral(1); // PatchFlags.TEXT createTextVNode(" " + toDisplayString$1(text)) => createTextVNode(" " + toDisplayString$1(text), 1)
243
+ }
244
+ },
193
245
  StringLiteral(path) {
194
246
  if (option.extractFromText === false) return;
195
247
  if (!shouldTransform(path)) return;
@@ -255,11 +307,10 @@ function createI18nVisitor(option, i18nMap) {
255
307
 
256
308
  // 判断是否createTextVNode或MemberExpression(如 Vue.createTextVNode)
257
309
  if (isVNodeCall(parentPath, "_createTextVNode")) {
258
- // 如果 createTextVNode 参数只有一个,则补充第二个参数 1
259
- const args = parentPath.node.arguments;
260
- if (args.length === 1) {
261
- parentPath.node.arguments = [callExpression, t.numericLiteral(1)];
262
- }
310
+ // createTextVNode强制补充第二个参数 1
311
+ parentPath.node.arguments = [callExpression, t.numericLiteral(1)];
312
+ // 尝试拆 cache
313
+ unwrapVueCacheIfNeeded(parentPath);
263
314
  // 是否 vue.createElementVNode(...),且该 StringLiteral 是第三个参数
264
315
  } else if (isVNodeCall(parentPath, "_createElementVNode")) {
265
316
  const callExpr = parentPath.node;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vue-i18n-extract-plugin",
3
- "version": "1.0.70",
3
+ "version": "1.0.71",
4
4
  "main": "lib/index.js",
5
5
  "types": "types/index.d.ts",
6
6
  "bin": {