@wevu/compiler 6.6.3 → 6.6.5

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/dist/index.mjs +71 -26
  2. package/package.json +2 -2
package/dist/index.mjs CHANGED
@@ -4574,6 +4574,50 @@ function normalizeJsExpressionWithContext(exp, context, options) {
4574
4574
  return (stmt && "expression" in stmt ? stmt.expression : null) || null;
4575
4575
  }
4576
4576
 
4577
+ //#endregion
4578
+ //#region src/plugins/vue/compiler/template/expression/runtimeBinding.ts
4579
+ function buildForIndexAccess$1(context) {
4580
+ if (!context.forStack.length) return "";
4581
+ return context.forStack.map((info) => `[${info.index ?? "index"}]`).join("");
4582
+ }
4583
+ /**
4584
+ * 检测表达式是否包含小程序模板不稳定的调用语义。
4585
+ */
4586
+ function shouldFallbackToRuntimeBinding(exp) {
4587
+ const trimmed = exp.trim();
4588
+ if (!trimmed) return false;
4589
+ const parsed = parseBabelExpressionFile(normalizeWxmlExpression(trimmed));
4590
+ if (!parsed) return false;
4591
+ let shouldFallback = false;
4592
+ traverse(parsed.ast, {
4593
+ CallExpression(path) {
4594
+ shouldFallback = true;
4595
+ path.stop();
4596
+ },
4597
+ OptionalCallExpression(path) {
4598
+ shouldFallback = true;
4599
+ path.stop();
4600
+ }
4601
+ });
4602
+ return shouldFallback;
4603
+ }
4604
+ /**
4605
+ * 将复杂表达式注册为 JS 运行时计算绑定,返回可用于模板 mustache 的绑定引用。
4606
+ */
4607
+ function registerRuntimeBindingExpression(exp, context, options) {
4608
+ const expAst = normalizeJsExpressionWithContext(exp, context, options);
4609
+ if (!expAst) return null;
4610
+ const binding = {
4611
+ name: `__wv_bind_${context.classStyleBindings.filter((item) => item.type === "bind").length}`,
4612
+ type: "bind",
4613
+ exp,
4614
+ expAst,
4615
+ forStack: context.forStack.map((info) => ({ ...info }))
4616
+ };
4617
+ context.classStyleBindings.push(binding);
4618
+ return `${binding.name}${buildForIndexAccess$1(context)}`;
4619
+ }
4620
+
4577
4621
  //#endregion
4578
4622
  //#region src/plugins/vue/compiler/template/mustache.ts
4579
4623
  function renderMustache(expression, context) {
@@ -4588,7 +4632,7 @@ function toWxmlStringLiteral(value) {
4588
4632
  function cloneForStack(context) {
4589
4633
  return context.forStack.map((info) => ({ ...info }));
4590
4634
  }
4591
- function buildForIndexAccess$1(context) {
4635
+ function buildForIndexAccess(context) {
4592
4636
  if (!context.forStack.length) return "";
4593
4637
  return context.forStack.map((info) => `[${info.index ?? "index"}]`).join("");
4594
4638
  }
@@ -4660,7 +4704,7 @@ function renderClassAttribute(staticClass, dynamicClassExp, context) {
4660
4704
  const expAst = mergeJsExpressionParts(jsParts);
4661
4705
  const binding = createClassStyleBinding(context, "class", generateExpressionCode(expAst), expAst);
4662
4706
  context.classStyleBindings.push(binding);
4663
- const indexAccess = buildForIndexAccess$1(context);
4707
+ const indexAccess = buildForIndexAccess(context);
4664
4708
  return `class="${renderMustache(`${binding.name}${indexAccess}`, context)}"`;
4665
4709
  }
4666
4710
  function renderStyleAttribute(staticStyle, dynamicStyleExp, vShowExp, context) {
@@ -4694,7 +4738,7 @@ function renderStyleAttribute(staticStyle, dynamicStyleExp, vShowExp, context) {
4694
4738
  const expAst = mergeJsExpressionParts(jsParts);
4695
4739
  const binding = createClassStyleBinding(context, "style", generateExpressionCode(expAst), expAst);
4696
4740
  context.classStyleBindings.push(binding);
4697
- const indexAccess = buildForIndexAccess$1(context);
4741
+ const indexAccess = buildForIndexAccess(context);
4698
4742
  return `style="${renderMustache(`${binding.name}${indexAccess}`, context)}"`;
4699
4743
  }
4700
4744
  function transformAttribute(node, _context) {
@@ -4715,23 +4759,10 @@ function isTopLevelObjectLiteral(exp) {
4715
4759
  if (!parsed) return false;
4716
4760
  return unwrapTsExpression(parsed).type === "ObjectExpression";
4717
4761
  }
4718
- function buildForIndexAccess(context) {
4719
- if (!context.forStack.length) return "";
4720
- return context.forStack.map((info) => `[${info.index ?? "index"}]`).join("");
4721
- }
4722
4762
  function createBindRuntimeAttr(argValue, rawExpValue, context) {
4723
- const expAst = normalizeJsExpressionWithContext(rawExpValue, context, { hint: `:${argValue} 绑定` });
4724
- if (!expAst) return null;
4725
- const binding = {
4726
- name: `__wv_bind_${context.classStyleBindings.filter((item) => item.type === "bind").length}`,
4727
- type: "bind",
4728
- exp: rawExpValue,
4729
- expAst,
4730
- forStack: context.forStack.map((info) => ({ ...info }))
4731
- };
4732
- context.classStyleBindings.push(binding);
4733
- const indexAccess = buildForIndexAccess(context);
4734
- return `${argValue}="${renderMustache(`${binding.name}${indexAccess}`, context)}"`;
4763
+ const bindingRef = registerRuntimeBindingExpression(rawExpValue, context, { hint: `:${argValue} 绑定` });
4764
+ if (!bindingRef) return null;
4765
+ return `${argValue}="${renderMustache(bindingRef, context)}"`;
4735
4766
  }
4736
4767
  function createInlineObjectLiteralAttr(argValue, rawExpValue, context) {
4737
4768
  const expValue = normalizeWxmlExpressionWithContext(rawExpValue, context).trim();
@@ -4776,6 +4807,10 @@ function transformBindDirective(node, context, forInfo) {
4776
4807
  if (context.objectLiteralBindMode === "inline") return createInlineObjectLiteralAttr(argValue, rawExpValue, context);
4777
4808
  return createBindRuntimeAttr(argValue, rawExpValue, context);
4778
4809
  }
4810
+ if (shouldFallbackToRuntimeBinding(rawExpValue)) {
4811
+ const runtimeAttr = createBindRuntimeAttr(argValue, rawExpValue, context);
4812
+ if (runtimeAttr) return runtimeAttr;
4813
+ }
4779
4814
  return `${argValue}="${renderMustache(normalizeWxmlExpressionWithContext(rawExpValue, context), context)}"`;
4780
4815
  }
4781
4816
 
@@ -4995,7 +5030,8 @@ function collectElementAttributes(node, context, options) {
4995
5030
  continue;
4996
5031
  }
4997
5032
  if (prop.name === "text" && prop.exp?.type === NodeTypes.SIMPLE_EXPRESSION) {
4998
- vTextExp = normalizeWxmlExpressionWithContext(prop.exp.content, context);
5033
+ const rawExp = prop.exp.content;
5034
+ vTextExp = (shouldFallbackToRuntimeBinding(rawExp) ? registerRuntimeBindingExpression(rawExp, context, { hint: "v-text" }) : null) ?? normalizeWxmlExpressionWithContext(rawExp, context);
4999
5035
  continue;
5000
5036
  }
5001
5037
  const dir = transformDirective(prop, context, node, options?.forInfo);
@@ -5415,6 +5451,9 @@ function transformNormalElement(node, context, transformNode) {
5415
5451
 
5416
5452
  //#endregion
5417
5453
  //#region src/plugins/vue/compiler/template/elements/tag-structural.ts
5454
+ function resolveConditionExpression$1(rawExpValue, context, hint) {
5455
+ return (shouldFallbackToRuntimeBinding(rawExpValue) ? registerRuntimeBindingExpression(rawExpValue, context, { hint }) : null) ?? normalizeWxmlExpressionWithContext(rawExpValue, context);
5456
+ }
5418
5457
  function transformIfElement(node, context, transformNode) {
5419
5458
  const renderTemplateMustache = (exp) => renderMustache(exp, context);
5420
5459
  const ifDirective = node.props.find((prop) => prop.type === NodeTypes.DIRECTIVE && (prop.name === "if" || prop.name === "else-if" || prop.name === "else"));
@@ -5431,10 +5470,10 @@ function transformIfElement(node, context, transformNode) {
5431
5470
  const content = slotDirective || templateSlotChildren.length > 0 ? transformComponentWithSlots(elementWithoutIf, context, transformNode) : transformNormalElement(elementWithoutIf, context, transformNode);
5432
5471
  const dir = ifDirective;
5433
5472
  if (dir.name === "if" && dir.exp) {
5434
- const expValue = normalizeWxmlExpressionWithContext(dir.exp.type === NodeTypes.SIMPLE_EXPRESSION ? dir.exp.content : "", context);
5473
+ const expValue = resolveConditionExpression$1(dir.exp.type === NodeTypes.SIMPLE_EXPRESSION ? dir.exp.content : "", context, "v-if");
5435
5474
  return context.platform.wrapIf(expValue, content, renderTemplateMustache);
5436
5475
  } else if (dir.name === "else-if" && dir.exp) {
5437
- const expValue = normalizeWxmlExpressionWithContext(dir.exp.type === NodeTypes.SIMPLE_EXPRESSION ? dir.exp.content : "", context);
5476
+ const expValue = resolveConditionExpression$1(dir.exp.type === NodeTypes.SIMPLE_EXPRESSION ? dir.exp.content : "", context, "v-else-if");
5438
5477
  return context.platform.wrapElseIf(expValue, content, renderTemplateMustache);
5439
5478
  } else if (dir.name === "else") return context.platform.wrapElse(content);
5440
5479
  return content;
@@ -5445,7 +5484,7 @@ function transformForElement(node, context, transformNode) {
5445
5484
  if (!forDirective || !forDirective.exp) return transformNormalElement(node, context, transformNode);
5446
5485
  const forInfo = parseForExpression(forDirective.exp.type === NodeTypes.SIMPLE_EXPRESSION ? forDirective.exp.content : "");
5447
5486
  if (context.classStyleRuntime === "js" && !forInfo.index) forInfo.index = `__wv_index_${context.forIndexSeed++}`;
5448
- const listExp = forInfo.listExp ? normalizeWxmlExpressionWithContext(forInfo.listExp, context) : void 0;
5487
+ const listExp = forInfo.listExp ? resolveConditionExpression$1(forInfo.listExp, context, "v-for 列表") : void 0;
5449
5488
  const listExpAst = forInfo.listExp ? normalizeJsExpressionWithContext(forInfo.listExp, context, { hint: "v-for 列表" }) : void 0;
5450
5489
  const scopedForInfo = listExp ? {
5451
5490
  ...forInfo,
@@ -5488,6 +5527,9 @@ function transformForElement(node, context, transformNode) {
5488
5527
 
5489
5528
  //#endregion
5490
5529
  //#region src/plugins/vue/compiler/template/elements/tag-builtin.ts
5530
+ function resolveConditionExpression(rawExpValue, context, hint) {
5531
+ return (shouldFallbackToRuntimeBinding(rawExpValue) ? registerRuntimeBindingExpression(rawExpValue, context, { hint }) : null) ?? normalizeWxmlExpressionWithContext(rawExpValue, context);
5532
+ }
5491
5533
  function transformTransitionElement(node, context, transformNode) {
5492
5534
  context.warnings.push("<transition> 组件:过渡效果需要动画库或运行时支持,仅渲染子节点。");
5493
5535
  const children = node.children.map((child) => transformNode(child, context)).join("");
@@ -5533,11 +5575,11 @@ function transformTemplateElement(node, context, transformNode) {
5533
5575
  props: base
5534
5576
  };
5535
5577
  if (dir.name === "if" && dir.exp) {
5536
- const expValue = normalizeWxmlExpressionWithContext(dir.exp.type === NodeTypes.SIMPLE_EXPRESSION ? dir.exp.content : "", context);
5578
+ const expValue = resolveConditionExpression(dir.exp.type === NodeTypes.SIMPLE_EXPRESSION ? dir.exp.content : "", context, "template v-if");
5537
5579
  return context.platform.wrapIf(expValue, children, renderTemplateMustache);
5538
5580
  }
5539
5581
  if (dir.name === "else-if" && dir.exp) {
5540
- const expValue = normalizeWxmlExpressionWithContext(dir.exp.type === NodeTypes.SIMPLE_EXPRESSION ? dir.exp.content : "", context);
5582
+ const expValue = resolveConditionExpression(dir.exp.type === NodeTypes.SIMPLE_EXPRESSION ? dir.exp.content : "", context, "template v-else-if");
5541
5583
  return context.platform.wrapElseIf(expValue, children, renderTemplateMustache);
5542
5584
  }
5543
5585
  if (dir.name === "else") return context.platform.wrapElse(children);
@@ -5579,7 +5621,10 @@ function transformText(node, _context) {
5579
5621
  }
5580
5622
  function transformInterpolation(node, context) {
5581
5623
  const { content } = node;
5582
- if (content.type === NodeTypes.SIMPLE_EXPRESSION) return renderMustache(normalizeWxmlExpressionWithContext(content.content, context), context);
5624
+ if (content.type === NodeTypes.SIMPLE_EXPRESSION) {
5625
+ const rawExpValue = content.content;
5626
+ return renderMustache((shouldFallbackToRuntimeBinding(rawExpValue) ? registerRuntimeBindingExpression(rawExpValue, context, { hint: "插值表达式" }) : null) ?? normalizeWxmlExpressionWithContext(rawExpValue, context), context);
5627
+ }
5583
5628
  /* istanbul ignore next */
5584
5629
  return renderMustache("", context);
5585
5630
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@wevu/compiler",
3
3
  "type": "module",
4
- "version": "6.6.3",
4
+ "version": "6.6.5",
5
5
  "description": "wevu 编译器基础包,面向小程序模板的编译与转换",
6
6
  "author": "ice breaker <1324318532@qq.com>",
7
7
  "license": "MIT",
@@ -48,7 +48,7 @@
48
48
  "@vue/compiler-core": "^3.5.28",
49
49
  "comment-json": "^4.5.1",
50
50
  "fs-extra": "^11.3.3",
51
- "lru-cache": "^11.2.5",
51
+ "lru-cache": "^11.2.6",
52
52
  "magic-string": "^0.30.21",
53
53
  "merge": "^2.1.1",
54
54
  "pathe": "^2.0.3",