@wevu/compiler 0.1.2 → 6.6.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.d.mts CHANGED
@@ -169,10 +169,10 @@ declare function getSfcCheckMtime(config?: {
169
169
  */
170
170
  interface MiniProgramPlatform {
171
171
  name: string;
172
- wrapIf: (exp: string, content: string) => string;
173
- wrapElseIf: (exp: string, content: string) => string;
172
+ wrapIf: (exp: string, content: string, renderMustache: (exp: string) => string) => string;
173
+ wrapElseIf: (exp: string, content: string, renderMustache: (exp: string) => string) => string;
174
174
  wrapElse: (content: string) => string;
175
- forAttrs: (listExp: string, item?: string, index?: string) => string[];
175
+ forAttrs: (listExp: string, renderMustache: (exp: string) => string, item?: string, index?: string) => string[];
176
176
  keyThisValue: string;
177
177
  keyAttr: (value: string) => string;
178
178
  mapEventName: (eventName: string) => string;
@@ -233,6 +233,8 @@ interface TemplateCompileOptions {
233
233
  scopedSlotsRequireProps?: boolean;
234
234
  slotMultipleInstance?: boolean;
235
235
  classStyleRuntime?: ClassStyleRuntime | 'auto';
236
+ objectLiteralBindMode?: ObjectLiteralBindMode;
237
+ mustacheInterpolation?: MustacheInterpolationMode;
236
238
  wxsExtension?: string;
237
239
  classStyleWxsSrc?: string;
238
240
  }
@@ -244,6 +246,14 @@ type ScopedSlotsCompilerMode = 'auto' | 'augmented' | 'off';
244
246
  * class/style 运行时模式。
245
247
  */
246
248
  type ClassStyleRuntime = 'wxs' | 'js';
249
+ /**
250
+ * 对象字面量 v-bind 产物模式。
251
+ */
252
+ type ObjectLiteralBindMode = 'runtime' | 'inline';
253
+ /**
254
+ * Mustache 输出风格。
255
+ */
256
+ type MustacheInterpolationMode = 'compact' | 'spaced';
247
257
  /**
248
258
  * class/style 绑定信息。
249
259
  */
package/dist/index.mjs CHANGED
@@ -415,11 +415,11 @@ function toAlipayDirectiveEvent(prefix, eventName) {
415
415
  */
416
416
  const alipayPlatform = {
417
417
  name: "alipay",
418
- wrapIf: (exp, content) => `<block a:if="{{${exp}}}">${content}</block>`,
419
- wrapElseIf: (exp, content) => `<block a:elif="{{${exp}}}">${content}</block>`,
418
+ wrapIf: (exp, content, renderMustache) => `<block a:if="${renderMustache(exp)}">${content}</block>`,
419
+ wrapElseIf: (exp, content, renderMustache) => `<block a:elif="${renderMustache(exp)}">${content}</block>`,
420
420
  wrapElse: (content) => `<block a:else>${content}</block>`,
421
- forAttrs: (listExp, item, index) => {
422
- const attrs = [`a:for="{{${listExp}}}"`];
421
+ forAttrs: (listExp, renderMustache, item, index) => {
422
+ const attrs = [`a:for="${renderMustache(listExp)}"`];
423
423
  if (item) attrs.push(`a:for-item="${item}"`);
424
424
  if (index) attrs.push(`a:for-index="${index}"`);
425
425
  return attrs;
@@ -474,11 +474,11 @@ function parseEventBinding$2(eventName) {
474
474
  */
475
475
  const swanPlatform = {
476
476
  name: "swan",
477
- wrapIf: (exp, content) => `<block s-if="{{${exp}}}">${content}</block>`,
478
- wrapElseIf: (exp, content) => `<block s-elif="{{${exp}}}">${content}</block>`,
477
+ wrapIf: (exp, content, renderMustache) => `<block s-if="${renderMustache(exp)}">${content}</block>`,
478
+ wrapElseIf: (exp, content, renderMustache) => `<block s-elif="${renderMustache(exp)}">${content}</block>`,
479
479
  wrapElse: (content) => `<block s-else>${content}</block>`,
480
- forAttrs: (listExp, item, index) => {
481
- const attrs = [`s-for="{{${listExp}}}"`];
480
+ forAttrs: (listExp, renderMustache, item, index) => {
481
+ const attrs = [`s-for="${renderMustache(listExp)}"`];
482
482
  if (item) attrs.push(`s-for-item="${item}"`);
483
483
  if (index) attrs.push(`s-for-index="${index}"`);
484
484
  return attrs;
@@ -538,11 +538,11 @@ function parseEventBinding$1(eventName) {
538
538
  */
539
539
  const ttPlatform = {
540
540
  name: "tt",
541
- wrapIf: (exp, content) => `<block tt:if="{{${exp}}}">${content}</block>`,
542
- wrapElseIf: (exp, content) => `<block tt:elif="{{${exp}}}">${content}</block>`,
541
+ wrapIf: (exp, content, renderMustache) => `<block tt:if="${renderMustache(exp)}">${content}</block>`,
542
+ wrapElseIf: (exp, content, renderMustache) => `<block tt:elif="${renderMustache(exp)}">${content}</block>`,
543
543
  wrapElse: (content) => `<block tt:else>${content}</block>`,
544
- forAttrs: (listExp, item, index) => {
545
- const attrs = [`tt:for="{{${listExp}}}"`];
544
+ forAttrs: (listExp, renderMustache, item, index) => {
545
+ const attrs = [`tt:for="${renderMustache(listExp)}"`];
546
546
  if (item) attrs.push(`tt:for-item="${item}"`);
547
547
  if (index) attrs.push(`tt:for-index="${index}"`);
548
548
  return attrs;
@@ -602,11 +602,11 @@ function parseEventBinding(eventName) {
602
602
  */
603
603
  const wechatPlatform = {
604
604
  name: "wechat",
605
- wrapIf: (exp, content) => `<block wx:if="{{${exp}}}">${content}</block>`,
606
- wrapElseIf: (exp, content) => `<block wx:elif="{{${exp}}}">${content}</block>`,
605
+ wrapIf: (exp, content, renderMustache) => `<block wx:if="${renderMustache(exp)}">${content}</block>`,
606
+ wrapElseIf: (exp, content, renderMustache) => `<block wx:elif="${renderMustache(exp)}">${content}</block>`,
607
607
  wrapElse: (content) => `<block wx:else>${content}</block>`,
608
- forAttrs: (listExp, item, index) => {
609
- const attrs = [`wx:for="{{${listExp}}}"`];
608
+ forAttrs: (listExp, renderMustache, item, index) => {
609
+ const attrs = [`wx:for="${renderMustache(listExp)}"`];
610
610
  if (item) attrs.push(`wx:for-item="${item}"`);
611
611
  if (index) attrs.push(`wx:for-index="${index}"`);
612
612
  return attrs;
@@ -1144,6 +1144,9 @@ function isTopLevel(path) {
1144
1144
 
1145
1145
  //#endregion
1146
1146
  //#region src/plugins/wevu/pageFeatures/flags.ts
1147
+ function injectWevuShareLifecycleHooksIntoOptionsObject(_optionsObject, _enabled) {
1148
+ return false;
1149
+ }
1147
1150
  /**
1148
1151
  * 扫描 AST,收集启用的 wevu 页面特性标识。
1149
1152
  */
@@ -1201,32 +1204,33 @@ function injectWevuPageFeatureFlagsIntoOptionsObject(optionsObject, enabled) {
1201
1204
  if (!enabled.size) return false;
1202
1205
  const expectedKeys = Array.from(enabled);
1203
1206
  const existingFeaturesProp = getObjectPropertyByKey$2(optionsObject, "features");
1207
+ let changed = false;
1204
1208
  if (!existingFeaturesProp) {
1205
1209
  const featuresObject = buildInjectedFeaturesObject(enabled);
1206
1210
  const setupIndex = getObjectMemberIndexByKey(optionsObject, "setup");
1207
1211
  const insertAt = setupIndex >= 0 ? setupIndex : 0;
1208
1212
  optionsObject.properties.splice(insertAt, 0, t.objectProperty(t.identifier("features"), featuresObject));
1209
- return true;
1210
- }
1211
- if (t.isObjectExpression(existingFeaturesProp.value)) {
1213
+ changed = true;
1214
+ } else if (t.isObjectExpression(existingFeaturesProp.value)) {
1212
1215
  const featuresObject = existingFeaturesProp.value;
1213
1216
  const injectedProps = [];
1214
1217
  for (const key of expectedKeys) {
1215
1218
  if (getObjectPropertyByKey$2(featuresObject, key)) continue;
1216
1219
  injectedProps.push(t.objectProperty(t.identifier(key), t.booleanLiteral(true)));
1217
1220
  }
1218
- if (!injectedProps.length) return false;
1219
- featuresObject.properties.splice(0, 0, ...injectedProps);
1220
- return true;
1221
- }
1222
- if (t.isIdentifier(existingFeaturesProp.value) || t.isMemberExpression(existingFeaturesProp.value)) {
1221
+ if (injectedProps.length) {
1222
+ featuresObject.properties.splice(0, 0, ...injectedProps);
1223
+ changed = true;
1224
+ }
1225
+ } else if (t.isIdentifier(existingFeaturesProp.value) || t.isMemberExpression(existingFeaturesProp.value)) {
1223
1226
  const base = t.cloneNode(existingFeaturesProp.value, true);
1224
1227
  const injected = buildInjectedFeaturesObject(enabled);
1225
1228
  injected.properties.push(t.spreadElement(base));
1226
1229
  existingFeaturesProp.value = injected;
1227
- return true;
1230
+ changed = true;
1228
1231
  }
1229
- return false;
1232
+ changed = injectWevuShareLifecycleHooksIntoOptionsObject(optionsObject, enabled) || changed;
1233
+ return changed;
1230
1234
  }
1231
1235
 
1232
1236
  //#endregion
@@ -1378,6 +1382,26 @@ function createModuleAnalysis(id, ast) {
1378
1382
 
1379
1383
  //#endregion
1380
1384
  //#region src/plugins/wevu/pageFeatures/optionsObjects.ts
1385
+ function unwrapTypeLikeExpression$1(node) {
1386
+ if (t.isTSAsExpression(node) || t.isTSSatisfiesExpression(node) || t.isTSNonNullExpression(node) || t.isTypeCastExpression(node)) return unwrapTypeLikeExpression$1(node.expression);
1387
+ if (t.isParenthesizedExpression(node)) return unwrapTypeLikeExpression$1(node.expression);
1388
+ return node;
1389
+ }
1390
+ function resolveOptionsObjectFromExpression(node) {
1391
+ const normalized = unwrapTypeLikeExpression$1(node);
1392
+ if (t.isObjectExpression(normalized)) return normalized;
1393
+ if (t.isIdentifier(normalized)) return null;
1394
+ if (t.isCallExpression(normalized)) {
1395
+ const callee = normalized.callee;
1396
+ if (t.isMemberExpression(callee) && !callee.computed && t.isIdentifier(callee.object, { name: "Object" }) && t.isIdentifier(callee.property, { name: "assign" })) for (let index = normalized.arguments.length - 1; index >= 0; index -= 1) {
1397
+ const argument = normalized.arguments[index];
1398
+ if (t.isSpreadElement(argument) || !t.isExpression(argument)) continue;
1399
+ const candidate = resolveOptionsObjectFromExpression(argument);
1400
+ if (candidate) return candidate;
1401
+ }
1402
+ }
1403
+ return null;
1404
+ }
1381
1405
  function getSetupFunctionFromOptionsObject(options) {
1382
1406
  for (const prop of options.properties) if (t.isObjectProperty(prop) && !prop.computed && isStaticObjectKeyMatch$1(prop.key, "setup")) {
1383
1407
  if (t.isFunctionExpression(prop.value) || t.isArrowFunctionExpression(prop.value)) return prop.value;
@@ -1411,7 +1435,8 @@ function collectTargetOptionsObjects(ast, moduleId) {
1411
1435
  if (objectBinding?.kind !== "namespace" || objectBinding.source !== WE_VU_MODULE_ID) return;
1412
1436
  if (node.callee.property.name !== WE_VU_RUNTIME_APIS.defineComponent && node.callee.property.name !== WE_VU_RUNTIME_APIS.createWevuComponent) return;
1413
1437
  } else return;
1414
- if (t.isObjectExpression(first)) optionsObjects.push(first);
1438
+ const inlineObject = resolveOptionsObjectFromExpression(first);
1439
+ if (inlineObject) optionsObjects.push(inlineObject);
1415
1440
  else if (t.isIdentifier(first)) {
1416
1441
  const target = constObjectBindings.get(first.name);
1417
1442
  if (target) optionsObjects.push(target);
@@ -1434,7 +1459,8 @@ function collectTargetOptionsObjects(ast, moduleId) {
1434
1459
  if (objectBinding?.kind !== "namespace" || objectBinding.source !== WE_VU_MODULE_ID) return;
1435
1460
  if (callee.property.name !== WE_VU_RUNTIME_APIS.defineComponent && callee.property.name !== WE_VU_RUNTIME_APIS.createWevuComponent) return;
1436
1461
  } else return;
1437
- if (t.isObjectExpression(first)) optionsObjects.push(first);
1462
+ const inlineObject = resolveOptionsObjectFromExpression(first);
1463
+ if (inlineObject) optionsObjects.push(inlineObject);
1438
1464
  else if (t.isIdentifier(first)) {
1439
1465
  const target = constObjectBindings.get(first.name);
1440
1466
  if (target) optionsObjects.push(target);
@@ -1870,6 +1896,21 @@ function isObjectAssignCall(node) {
1870
1896
  const callee = node.callee;
1871
1897
  return t.isMemberExpression(callee) && t.isIdentifier(callee.object, { name: "Object" }) && t.isIdentifier(callee.property, { name: "assign" });
1872
1898
  }
1899
+ function unwrapTypeLikeExpression(node) {
1900
+ if (t.isTSAsExpression(node) || t.isTSSatisfiesExpression(node) || t.isTSNonNullExpression(node) || t.isTypeCastExpression(node)) return unwrapTypeLikeExpression(node.expression);
1901
+ if (t.isParenthesizedExpression(node)) return unwrapTypeLikeExpression(node.expression);
1902
+ return node;
1903
+ }
1904
+ function resolveObjectExpressionFromAssignCall(node) {
1905
+ if (!isObjectAssignCall(node)) return null;
1906
+ for (let index = node.arguments.length - 1; index >= 0; index -= 1) {
1907
+ const arg = node.arguments[index];
1908
+ if (t.isSpreadElement(arg) || !t.isExpression(arg)) continue;
1909
+ const normalized = unwrapTypeLikeExpression(arg);
1910
+ if (t.isObjectExpression(normalized)) return normalized;
1911
+ }
1912
+ return null;
1913
+ }
1873
1914
  function unwrapDefineComponent(node, aliases) {
1874
1915
  if (t.isCallExpression(node) && isDefineComponentCall(node, aliases)) {
1875
1916
  const arg = node.arguments[0];
@@ -1887,6 +1928,7 @@ function resolveComponentExpression(declaration, defineComponentDecls, aliases)
1887
1928
  const matched = defineComponentDecls.get(arg.name);
1888
1929
  return matched ? t.cloneNode(matched, true) : null;
1889
1930
  }
1931
+ if (t.isExpression(arg)) return arg;
1890
1932
  return null;
1891
1933
  }
1892
1934
  if (t.isCallExpression(declaration) && isObjectAssignCall(declaration)) return declaration;
@@ -1896,6 +1938,13 @@ function resolveComponentExpression(declaration, defineComponentDecls, aliases)
1896
1938
  }
1897
1939
  return null;
1898
1940
  }
1941
+ function resolveComponentOptionsObject(componentExpr) {
1942
+ if (!componentExpr) return null;
1943
+ const normalized = unwrapTypeLikeExpression(componentExpr);
1944
+ if (t.isObjectExpression(normalized)) return normalized;
1945
+ if (t.isCallExpression(normalized)) return resolveObjectExpressionFromAssignCall(normalized);
1946
+ return null;
1947
+ }
1899
1948
 
1900
1949
  //#endregion
1901
1950
  //#region src/plugins/vue/transform/transformScript/collect.ts
@@ -2596,23 +2645,24 @@ function rewriteDefaultExport(ast, state, options, enabledPageFeatures, serializ
2596
2645
  let transformed = false;
2597
2646
  const exportPath = state.defaultExportPath;
2598
2647
  const componentExpr = resolveComponentExpression(exportPath.node.declaration, state.defineComponentDecls, state.defineComponentAliases);
2599
- if (componentExpr && t.isObjectExpression(componentExpr) && enabledPageFeatures.size) transformed = injectWevuPageFeatureFlagsIntoOptionsObject(componentExpr, enabledPageFeatures) || transformed;
2600
- if (componentExpr && t.isObjectExpression(componentExpr) && parsedWevuDefaults) transformed = applyWevuDefaultsToComponentOptions({
2601
- componentExpr,
2648
+ const componentOptionsObject = resolveComponentOptionsObject(componentExpr);
2649
+ if (componentOptionsObject && enabledPageFeatures.size) transformed = injectWevuPageFeatureFlagsIntoOptionsObject(componentOptionsObject, enabledPageFeatures) || transformed;
2650
+ if (componentOptionsObject && parsedWevuDefaults) transformed = applyWevuDefaultsToComponentOptions({
2651
+ componentExpr: componentOptionsObject,
2602
2652
  parsedWevuDefaults,
2603
2653
  options
2604
2654
  }) || transformed;
2605
2655
  const classStyleBindings = options?.classStyleBindings ?? [];
2606
- if (classStyleBindings.length) if (componentExpr && t.isObjectExpression(componentExpr)) {
2656
+ if (classStyleBindings.length) if (componentOptionsObject) {
2607
2657
  ensureClassStyleRuntimeImports(ast.program);
2608
- transformed = injectClassStyleComputed(componentExpr, classStyleBindings, warn) || transformed;
2658
+ transformed = injectClassStyleComputed(componentOptionsObject, classStyleBindings, warn) || transformed;
2609
2659
  } else warn("无法自动注入 class/style 计算属性:组件选项不是对象字面量。");
2610
2660
  const templateRefs = options?.templateRefs ?? [];
2611
- if (templateRefs.length) if (componentExpr && t.isObjectExpression(componentExpr)) transformed = injectTemplateRefs(componentExpr, templateRefs, warn) || transformed;
2661
+ if (templateRefs.length) if (componentOptionsObject) transformed = injectTemplateRefs(componentOptionsObject, templateRefs, warn) || transformed;
2612
2662
  else warn("无法自动注入 template ref 元数据:组件选项不是对象字面量。");
2613
2663
  const inlineExpressions = options?.inlineExpressions ?? [];
2614
- if (inlineExpressions.length) if (componentExpr && t.isObjectExpression(componentExpr)) {
2615
- const injected = injectInlineExpressions(componentExpr, inlineExpressions);
2664
+ if (inlineExpressions.length) if (componentOptionsObject) {
2665
+ const injected = injectInlineExpressions(componentOptionsObject, inlineExpressions);
2616
2666
  if (!injected) warn("无法自动注入内联表达式元数据:methods 不是对象字面量。");
2617
2667
  transformed = injected || transformed;
2618
2668
  } else warn("无法自动注入内联表达式元数据:组件选项不是对象字面量。");
@@ -2713,6 +2763,9 @@ function unwrapTsExpression$2(exp) {
2713
2763
  function normalizeInterpolationExpression(exp) {
2714
2764
  return normalizeWxmlExpression(printExpression(unwrapTsExpression$2(exp)));
2715
2765
  }
2766
+ function renderMustache$1(expression, context) {
2767
+ return context.mustacheInterpolation === "spaced" ? `{{ ${expression} }}` : `{{${expression}}}`;
2768
+ }
2716
2769
  function pushScope$1(context, names) {
2717
2770
  for (const name of names) {
2718
2771
  if (!name) continue;
@@ -2940,17 +2993,17 @@ function compileEventAttribute(name, value, context) {
2940
2993
  const inline = registerInlineExpression$1(exp, context);
2941
2994
  const attrs = [`data-wv-inline-id="${inline.id}"`, `${bindAttr}="__weapp_vite_inline"`];
2942
2995
  inline.scopeKeys.forEach((scopeKey, index) => {
2943
- attrs.push(`data-wv-s${index}="{{${scopeKey}}}"`);
2996
+ attrs.push(`data-wv-s${index}="${renderMustache$1(scopeKey, context)}"`);
2944
2997
  });
2945
2998
  return attrs;
2946
2999
  }
2947
- function compileNormalAttribute(name, value) {
3000
+ function compileNormalAttribute(name, value, context) {
2948
3001
  const normalizedName = name === "className" ? "class" : name;
2949
3002
  const exp = readJsxAttributeExpression(value);
2950
3003
  if (!exp) return null;
2951
3004
  if (t.isStringLiteral(exp)) return `${normalizedName}="${escapeAttr(exp.value)}"`;
2952
- if (t.isBooleanLiteral(exp)) return `${normalizedName}="{{${exp.value}}}"`;
2953
- return `${normalizedName}="{{${normalizeInterpolationExpression(exp)}}}"`;
3005
+ if (t.isBooleanLiteral(exp)) return `${normalizedName}="${renderMustache$1(String(exp.value), context)}"`;
3006
+ return `${normalizedName}="${renderMustache$1(normalizeInterpolationExpression(exp), context)}"`;
2954
3007
  }
2955
3008
  function compileJsxAttributes(attributes, context) {
2956
3009
  const output = [];
@@ -2969,7 +3022,7 @@ function compileJsxAttributes(attributes, context) {
2969
3022
  output.push(...compileEventAttribute(name, attr.value, context));
2970
3023
  continue;
2971
3024
  }
2972
- const normalAttr = compileNormalAttribute(name, attr.value);
3025
+ const normalAttr = compileNormalAttribute(name, attr.value, context);
2973
3026
  if (normalAttr) output.push(normalAttr);
2974
3027
  }
2975
3028
  return output;
@@ -2986,6 +3039,7 @@ function compileMapExpression(exp, context) {
2986
3039
  return null;
2987
3040
  }
2988
3041
  const listExp = compileListExpression(callee.object);
3042
+ const renderTemplateMustache = (expression) => renderMustache$1(expression, context);
2989
3043
  const itemParam = callback.params[0];
2990
3044
  const indexParam = callback.params[1];
2991
3045
  const item = t.isIdentifier(itemParam) ? itemParam.name : "item";
@@ -3008,27 +3062,29 @@ function compileMapExpression(exp, context) {
3008
3062
  if (extracted) keyValue = extracted;
3009
3063
  else if (index) keyValue = index;
3010
3064
  } else if (index) keyValue = index;
3011
- return `<block ${[...context.platform.forAttrs(listExp, item, index), context.platform.keyAttr(keyValue)].join(" ")}>${body}</block>`;
3065
+ return `<block ${[...context.platform.forAttrs(listExp, renderTemplateMustache, item, index), context.platform.keyAttr(keyValue)].join(" ")}>${body}</block>`;
3012
3066
  }
3013
3067
  function compileConditionalExpression(exp, context) {
3068
+ const renderTemplateMustache = (expression) => renderMustache$1(expression, context);
3014
3069
  const test = normalizeInterpolationExpression(exp.test);
3015
3070
  const consequent = compileRenderableExpression(exp.consequent, context);
3016
3071
  const alternate = compileRenderableExpression(exp.alternate, context);
3017
- if (!alternate) return context.platform.wrapIf(test, consequent);
3018
- return `${context.platform.wrapIf(test, consequent)}${context.platform.wrapElse(alternate)}`;
3072
+ if (!alternate) return context.platform.wrapIf(test, consequent, renderTemplateMustache);
3073
+ return `${context.platform.wrapIf(test, consequent, renderTemplateMustache)}${context.platform.wrapElse(alternate)}`;
3019
3074
  }
3020
3075
  function compileLogicalExpression(exp, context) {
3076
+ const renderTemplateMustache = (expression) => renderMustache$1(expression, context);
3021
3077
  if (exp.operator === "&&") {
3022
3078
  const test = normalizeInterpolationExpression(exp.left);
3023
3079
  const content = compileRenderableExpression(exp.right, context);
3024
- return context.platform.wrapIf(test, content);
3080
+ return context.platform.wrapIf(test, content, renderTemplateMustache);
3025
3081
  }
3026
3082
  if (exp.operator === "||") {
3027
3083
  const test = normalizeInterpolationExpression(t.unaryExpression("!", t.parenthesizedExpression(t.cloneNode(exp.left, true))));
3028
3084
  const content = compileRenderableExpression(exp.right, context);
3029
- return context.platform.wrapIf(test, content);
3085
+ return context.platform.wrapIf(test, content, renderTemplateMustache);
3030
3086
  }
3031
- return `{{${normalizeInterpolationExpression(exp)}}}`;
3087
+ return renderMustache$1(normalizeInterpolationExpression(exp), context);
3032
3088
  }
3033
3089
  function compileRenderableExpression(exp, context) {
3034
3090
  const node = unwrapTsExpression$2(exp);
@@ -3045,7 +3101,7 @@ function compileRenderableExpression(exp, context) {
3045
3101
  return compileRenderableExpression(element, context);
3046
3102
  }).join("");
3047
3103
  if (t.isNullLiteral(node) || t.isBooleanLiteral(node)) return "";
3048
- return `{{${normalizeInterpolationExpression(node)}}}`;
3104
+ return renderMustache$1(normalizeInterpolationExpression(node), context);
3049
3105
  }
3050
3106
  function compileExpressionContainer(node, context) {
3051
3107
  const exp = node.expression;
@@ -3187,6 +3243,7 @@ function collectJsxAutoComponentContext(source, filename, warn) {
3187
3243
  const importedComponents = collectImportedComponents(ast);
3188
3244
  const context = {
3189
3245
  platform: wechatPlatform,
3246
+ mustacheInterpolation: "compact",
3190
3247
  warnings: [],
3191
3248
  inlineExpressions: [],
3192
3249
  inlineExpressionSeed: 0,
@@ -3211,6 +3268,7 @@ function compileJsxTemplate(source, filename, options) {
3211
3268
  const ast = parse$2(source, BABEL_TS_MODULE_PARSER_OPTIONS);
3212
3269
  const context = {
3213
3270
  platform: options?.template?.platform ?? wechatPlatform,
3271
+ mustacheInterpolation: options?.template?.mustacheInterpolation ?? "compact",
3214
3272
  warnings: [],
3215
3273
  inlineExpressions: [],
3216
3274
  inlineExpressionSeed: 0,
@@ -4449,6 +4507,7 @@ const JS_RUNTIME_GLOBALS = new Set([
4449
4507
  "require",
4450
4508
  "arguments",
4451
4509
  "globalThis",
4510
+ "__wevuUnref",
4452
4511
  "wx",
4453
4512
  "getApp",
4454
4513
  "getCurrentPages"
@@ -4474,6 +4533,9 @@ function createMemberAccess(target, prop) {
4474
4533
  function createThisMemberAccess(prop) {
4475
4534
  return createMemberAccess(t.thisExpression(), prop);
4476
4535
  }
4536
+ function createUnrefCall(exp) {
4537
+ return t.callExpression(t.identifier("__wevuUnref"), [exp]);
4538
+ }
4477
4539
  function normalizeJsExpressionWithContext(exp, context, options) {
4478
4540
  const trimmed = exp.trim();
4479
4541
  if (!trimmed) return null;
@@ -4496,10 +4558,10 @@ function normalizeJsExpressionWithContext(exp, context, options) {
4496
4558
  if (context.rewriteScopedSlot) if (Object.prototype.hasOwnProperty.call(slotProps, name)) {
4497
4559
  const prop = slotProps[name];
4498
4560
  const base = createThisMemberAccess("__wvSlotPropsData");
4499
- replacement = prop ? createMemberAccess(base, prop) : base;
4500
- } else if (name === "__wvOwner" || name === "__wvSlotPropsData" || name === "__wvSlotProps" || name === "__wvSlotScope") replacement = createThisMemberAccess(name);
4501
- else replacement = createMemberAccess(createThisMemberAccess("__wvOwner"), name);
4502
- else replacement = createThisMemberAccess(name);
4561
+ replacement = createUnrefCall(prop ? createMemberAccess(base, prop) : base);
4562
+ } else if (name === "__wvOwner" || name === "__wvSlotPropsData" || name === "__wvSlotProps" || name === "__wvSlotScope") replacement = createUnrefCall(createThisMemberAccess(name));
4563
+ else replacement = createUnrefCall(createMemberAccess(createThisMemberAccess("__wvOwner"), name));
4564
+ else replacement = createUnrefCall(createThisMemberAccess(name));
4503
4565
  const parent = path.parentPath;
4504
4566
  if (parent.isObjectProperty() && parent.node.shorthand && parent.node.key === path.node) {
4505
4567
  parent.node.shorthand = false;
@@ -4512,6 +4574,12 @@ function normalizeJsExpressionWithContext(exp, context, options) {
4512
4574
  return (stmt && "expression" in stmt ? stmt.expression : null) || null;
4513
4575
  }
4514
4576
 
4577
+ //#endregion
4578
+ //#region src/plugins/vue/compiler/template/mustache.ts
4579
+ function renderMustache(expression, context) {
4580
+ return context.mustacheInterpolation === "spaced" ? `{{ ${expression} }}` : `{{${expression}}}`;
4581
+ }
4582
+
4515
4583
  //#endregion
4516
4584
  //#region src/plugins/vue/compiler/template/attributes.ts
4517
4585
  function toWxmlStringLiteral(value) {
@@ -4583,7 +4651,7 @@ function renderClassAttribute(staticClass, dynamicClassExp, context) {
4583
4651
  for (const part of normalizedParts) parts.push(`(${part})`);
4584
4652
  const mergedExp = parts.length > 1 ? `[${parts.join(",")}]` : parts[0];
4585
4653
  context.classStyleWxs = true;
4586
- return `class="{{__weapp_vite.cls(${mergedExp})}}"`;
4654
+ return `class="${renderMustache(`__weapp_vite.cls(${mergedExp})`, context)}"`;
4587
4655
  }
4588
4656
  const jsParts = [];
4589
4657
  if (staticValue) jsParts.push(t.stringLiteral(staticValue));
@@ -4593,7 +4661,7 @@ function renderClassAttribute(staticClass, dynamicClassExp, context) {
4593
4661
  const binding = createClassStyleBinding(context, "class", generateExpressionCode(expAst), expAst);
4594
4662
  context.classStyleBindings.push(binding);
4595
4663
  const indexAccess = buildForIndexAccess$1(context);
4596
- return `class="{{${binding.name}${indexAccess}}}"`;
4664
+ return `class="${renderMustache(`${binding.name}${indexAccess}`, context)}"`;
4597
4665
  }
4598
4666
  function renderStyleAttribute(staticStyle, dynamicStyleExp, vShowExp, context) {
4599
4667
  const staticValue = staticStyle?.trim();
@@ -4611,7 +4679,7 @@ function renderStyleAttribute(staticStyle, dynamicStyleExp, vShowExp, context) {
4611
4679
  }
4612
4680
  const mergedExp = parts.length > 1 ? `[${parts.join(",")}]` : parts[0] || "''";
4613
4681
  context.classStyleWxs = true;
4614
- return `style="{{__weapp_vite.style(${mergedExp})}}"`;
4682
+ return `style="${renderMustache(`__weapp_vite.style(${mergedExp})`, context)}"`;
4615
4683
  }
4616
4684
  const jsParts = [];
4617
4685
  if (staticValue) jsParts.push(t.stringLiteral(staticValue));
@@ -4627,7 +4695,7 @@ function renderStyleAttribute(staticStyle, dynamicStyleExp, vShowExp, context) {
4627
4695
  const binding = createClassStyleBinding(context, "style", generateExpressionCode(expAst), expAst);
4628
4696
  context.classStyleBindings.push(binding);
4629
4697
  const indexAccess = buildForIndexAccess$1(context);
4630
- return `style="{{${binding.name}${indexAccess}}}"`;
4698
+ return `style="${renderMustache(`${binding.name}${indexAccess}`, context)}"`;
4631
4699
  }
4632
4700
  function transformAttribute(node, _context) {
4633
4701
  const { name, value } = node;
@@ -4663,7 +4731,12 @@ function createBindRuntimeAttr(argValue, rawExpValue, context) {
4663
4731
  };
4664
4732
  context.classStyleBindings.push(binding);
4665
4733
  const indexAccess = buildForIndexAccess(context);
4666
- return `${argValue}="{{${binding.name}${indexAccess}}}"`;
4734
+ return `${argValue}="${renderMustache(`${binding.name}${indexAccess}`, context)}"`;
4735
+ }
4736
+ function createInlineObjectLiteralAttr(argValue, rawExpValue, context) {
4737
+ const expValue = normalizeWxmlExpressionWithContext(rawExpValue, context).trim();
4738
+ if (context.mustacheInterpolation === "spaced") return `${argValue}="${renderMustache(expValue, context)}"`;
4739
+ return `${argValue}="{{ ${expValue} }}"`;
4667
4740
  }
4668
4741
  const isSimpleIdentifier = (value) => /^[A-Z_$][\w$]*$/i.test(value);
4669
4742
  const isSimpleMemberPath = (value) => /^[A-Z_$][\w$]*(?:\.[A-Z_$][\w$]*)*$/i.test(value);
@@ -4699,8 +4772,11 @@ function transformBindDirective(node, context, forInfo) {
4699
4772
  }
4700
4773
  return context.platform.keyAttr(expValue);
4701
4774
  }
4702
- if (isTopLevelObjectLiteral(rawExpValue)) return createBindRuntimeAttr(argValue, rawExpValue, context);
4703
- return `${argValue}="{{${normalizeWxmlExpressionWithContext(rawExpValue, context)}}}"`;
4775
+ if (isTopLevelObjectLiteral(rawExpValue)) {
4776
+ if (context.objectLiteralBindMode === "inline") return createInlineObjectLiteralAttr(argValue, rawExpValue, context);
4777
+ return createBindRuntimeAttr(argValue, rawExpValue, context);
4778
+ }
4779
+ return `${argValue}="${renderMustache(normalizeWxmlExpressionWithContext(rawExpValue, context), context)}"`;
4704
4780
  }
4705
4781
 
4706
4782
  //#endregion
@@ -4724,8 +4800,8 @@ function transformCustomDirective(name, exp, arg, context) {
4724
4800
  const dataAttrName = `data-v-${name}`;
4725
4801
  if (exp && exp.type === NodeTypes.SIMPLE_EXPRESSION) {
4726
4802
  const expValue = normalizeWxmlExpressionWithContext(exp.content, context);
4727
- if (/^[a-z_$][\w$]*$/i.test(expValue)) return `${dataAttrName}="{{${expValue}}}"`;
4728
- return `${dataAttrName}="{{${expValue}}}"`;
4803
+ if (/^[a-z_$][\w$]*$/i.test(expValue)) return `${dataAttrName}="${renderMustache(expValue, context)}"`;
4804
+ return `${dataAttrName}="${renderMustache(expValue, context)}"`;
4729
4805
  }
4730
4806
  if (arg && arg.type === NodeTypes.SIMPLE_EXPRESSION) return `${dataAttrName}="${arg.content}"`;
4731
4807
  context.warnings.push(`自定义指令 v-${name} 可能需要运行时支持。已生成 data 属性:${dataAttrName}`);
@@ -4746,24 +4822,24 @@ function transformVModel(element, expValue, context) {
4746
4822
  const bindModel = (event) => {
4747
4823
  return `${context.platform.eventBindingAttr(event)}="__weapp_vite_model" data-wv-model="${escapedModel}"`;
4748
4824
  };
4749
- if (!element) return `value="{{${expValue}}}" ${bindModel("input")}`;
4825
+ if (!element) return `value="${renderMustache(expValue, context)}" ${bindModel("input")}`;
4750
4826
  const tag = element.tag;
4751
4827
  const typeAttr = getElementType(element);
4752
4828
  switch (tag) {
4753
4829
  case "input": switch (typeAttr) {
4754
- case "checkbox": return `checked="{{${expValue}}}" ${bindModel("change")}`;
4755
- case "radio": return `value="{{${expValue}}}" ${bindModel("change")}`;
4756
- default: return `value="{{${expValue}}}" ${bindModel("input")}`;
4830
+ case "checkbox": return `checked="${renderMustache(expValue, context)}" ${bindModel("change")}`;
4831
+ case "radio": return `value="${renderMustache(expValue, context)}" ${bindModel("change")}`;
4832
+ default: return `value="${renderMustache(expValue, context)}" ${bindModel("input")}`;
4757
4833
  }
4758
- case "textarea": return `value="{{${expValue}}}" ${bindModel("input")}`;
4759
- case "select": return `value="{{${expValue}}}" ${bindModel("change")}`;
4834
+ case "textarea": return `value="${renderMustache(expValue, context)}" ${bindModel("input")}`;
4835
+ case "select": return `value="${renderMustache(expValue, context)}" ${bindModel("change")}`;
4760
4836
  case "switch":
4761
- case "checkbox": return `checked="{{${expValue}}}" ${bindModel("change")}`;
4762
- case "slider": return `value="{{${expValue}}}" ${bindModel("change")}`;
4763
- case "picker": return `value="{{${expValue}}}" ${bindModel("change")}`;
4837
+ case "checkbox": return `checked="${renderMustache(expValue, context)}" ${bindModel("change")}`;
4838
+ case "slider": return `value="${renderMustache(expValue, context)}" ${bindModel("change")}`;
4839
+ case "picker": return `value="${renderMustache(expValue, context)}" ${bindModel("change")}`;
4764
4840
  default:
4765
4841
  context.warnings.push(`在 <${tag}> 上使用 v-model 可能无法按预期工作,已使用默认绑定。`);
4766
- return `value="{{${expValue}}}" ${bindModel("input")}`;
4842
+ return `value="${renderMustache(expValue, context)}" ${bindModel("input")}`;
4767
4843
  }
4768
4844
  }
4769
4845
  function transformModelDirective(node, context, elementNode) {
@@ -4775,9 +4851,9 @@ function transformModelDirective(node, context, elementNode) {
4775
4851
  //#endregion
4776
4852
  //#region src/plugins/vue/compiler/template/directives/on.ts
4777
4853
  const isSimpleHandler = (value) => /^[A-Z_$][\w$]*$/i.test(value);
4778
- function buildInlineScopeAttrs(scopeBindings) {
4854
+ function buildInlineScopeAttrs(scopeBindings, context) {
4779
4855
  return scopeBindings.map((binding, index) => {
4780
- return `data-wv-s${index}="{{${binding.replace(/"/g, "&quot;")}}}"`;
4856
+ return `data-wv-s${index}="${renderMustache(binding.replace(/"/g, "&quot;"), context)}"`;
4781
4857
  });
4782
4858
  }
4783
4859
  function resolveEventPrefix(modifiers) {
@@ -4804,7 +4880,7 @@ function transformOnDirective(node, context) {
4804
4880
  const bindAttr = context.platform.eventBindingAttr(`${eventPrefix}:${mappedEvent}`);
4805
4881
  if (context.rewriteScopedSlot) {
4806
4882
  if (inlineExpression) {
4807
- const scopeAttrs = buildInlineScopeAttrs(inlineExpression.scopeBindings);
4883
+ const scopeAttrs = buildInlineScopeAttrs(inlineExpression.scopeBindings, context);
4808
4884
  return [
4809
4885
  `data-wv-inline-id="${inlineExpression.id}"`,
4810
4886
  ...scopeAttrs,
@@ -4819,7 +4895,7 @@ function transformOnDirective(node, context) {
4819
4895
  }
4820
4896
  const expValue = normalizeWxmlExpressionWithContext(rawExpValue, context);
4821
4897
  if (inlineExpression) {
4822
- const scopeAttrs = buildInlineScopeAttrs(inlineExpression.scopeBindings);
4898
+ const scopeAttrs = buildInlineScopeAttrs(inlineExpression.scopeBindings, context);
4823
4899
  return [
4824
4900
  `data-wv-inline-id="${inlineExpression.id}"`,
4825
4901
  ...scopeAttrs,
@@ -4835,7 +4911,7 @@ function transformOnDirective(node, context) {
4835
4911
  function transformShowDirective(node, context) {
4836
4912
  const { exp } = node;
4837
4913
  if (!exp) return null;
4838
- return `style="{{${normalizeWxmlExpressionWithContext(exp.type === NodeTypes.SIMPLE_EXPRESSION ? exp.content : "", context)} ? '' : 'display: none'}}"`;
4914
+ return `style="${renderMustache(`${normalizeWxmlExpressionWithContext(exp.type === NodeTypes.SIMPLE_EXPRESSION ? exp.content : "", context)} ? '' : 'display: none'`, context)}"`;
4839
4915
  }
4840
4916
 
4841
4917
  //#endregion
@@ -4952,7 +5028,7 @@ function collectElementAttributes(node, context, options) {
4952
5028
  //#region src/plugins/vue/compiler/template/elements/tag-slot.ts
4953
5029
  function renderSlotNameAttribute(info, context, attrName) {
4954
5030
  if (info.type === "static" && info.value !== "default") return `${attrName}="${info.value}"`;
4955
- if (info.type === "dynamic") return `${attrName}="{{${normalizeWxmlExpressionWithContext(info.exp, context)}}}"`;
5031
+ if (info.type === "dynamic") return `${attrName}="${renderMustache(normalizeWxmlExpressionWithContext(info.exp, context), context)}"`;
4956
5032
  }
4957
5033
  function resolveSlotNameFromDirective(slotDirective) {
4958
5034
  if (!slotDirective.arg) return { type: "default" };
@@ -5150,8 +5226,9 @@ function transformSlotElement(node, context, transformNode) {
5150
5226
  if (context.scopedSlotsRequireProps && !slotPropsExp) return slotTag;
5151
5227
  const genericKey = `scoped-slots-${resolveSlotKey(context, slotNameInfo)}`;
5152
5228
  context.componentGenerics[genericKey] = true;
5153
- const scopedAttrs = [`__wv-owner-id="{{__wvSlotOwnerId}}"`, `__wv-slot-props="{{${slotPropsExp ?? "[]"}}}"`];
5154
- if (context.slotMultipleInstance) scopedAttrs.push(`__wv-slot-scope="{{__wvSlotScope}}"`);
5229
+ const resolvedSlotPropsExp = slotPropsExp ?? "[]";
5230
+ const scopedAttrs = [`__wv-owner-id="${renderMustache("__wvSlotOwnerId", context)}"`, `__wv-slot-props="${renderMustache(resolvedSlotPropsExp, context)}"`];
5231
+ if (context.slotMultipleInstance) scopedAttrs.push(`__wv-slot-scope="${renderMustache("__wvSlotScope", context)}"`);
5155
5232
  return `${slotTag}${`<${genericKey}${scopedAttrs.length ? ` ${scopedAttrs.join(" ")}` : ""} />`}`;
5156
5233
  }
5157
5234
  function transformSlotElementPlain(node, context, transformNode) {
@@ -5200,7 +5277,7 @@ function transformComponentWithSlots(node, context, transformNode, options) {
5200
5277
  isComponent: true
5201
5278
  });
5202
5279
  let children = node.children.map((child) => transformNode(child, context)).join("");
5203
- if (vTextExp !== void 0) children = `{{${vTextExp}}}`;
5280
+ if (vTextExp !== void 0) children = renderMustache(vTextExp, context);
5204
5281
  const attrString = attrs.length ? ` ${attrs.join(" ")}` : "";
5205
5282
  const { tag } = node;
5206
5283
  return children ? `<${tag}${attrString}>${children}</${tag}>` : `<${tag}${attrString} />`;
@@ -5230,11 +5307,11 @@ function transformComponentWithSlots(node, context, transformNode, options) {
5230
5307
  ...attrs,
5231
5308
  ...slotGenericAttrs
5232
5309
  ];
5233
- if (slotNames.length) mergedAttrs.push(`vue-slots="{{[${slotNames.join(",")}]}}"`);
5310
+ if (slotNames.length) mergedAttrs.push(`vue-slots="${renderMustache(`[${slotNames.join(",")}]`, context)}"`);
5234
5311
  if (scopedSlotDeclarations.length) {
5235
5312
  const scopePropsExp = buildScopePropsExpression(context);
5236
- if (scopePropsExp) mergedAttrs.push(`__wv-slot-scope="{{${scopePropsExp}}}"`);
5237
- mergedAttrs.push(`__wv-slot-owner-id="{{__wvOwnerId || ''}}"`);
5313
+ if (scopePropsExp) mergedAttrs.push(`__wv-slot-scope="${renderMustache(scopePropsExp, context)}"`);
5314
+ mergedAttrs.push(`__wv-slot-owner-id="${renderMustache(`__wvOwnerId || ''`, context)}"`);
5238
5315
  }
5239
5316
  const attrString = mergedAttrs.length ? ` ${mergedAttrs.join(" ")}` : "";
5240
5317
  const { tag } = node;
@@ -5270,7 +5347,7 @@ function transformComponentWithSlotsFallback(node, context, transformNode, optio
5270
5347
  isComponent: true
5271
5348
  });
5272
5349
  let children = node.children.map((child) => transformNode(child, context)).join("");
5273
- if (vTextExp !== void 0) children = `{{${vTextExp}}}`;
5350
+ if (vTextExp !== void 0) children = renderMustache(vTextExp, context);
5274
5351
  const attrString = attrs.length ? ` ${attrs.join(" ")}` : "";
5275
5352
  const { tag } = node;
5276
5353
  return children ? `<${tag}${attrString}>${children}</${tag}>` : `<${tag}${attrString} />`;
@@ -5307,7 +5384,7 @@ function transformComponentElement(node, context, transformNode) {
5307
5384
  if (slotDirective || templateSlotChildren.length > 0) return transformComponentWithSlots({
5308
5385
  ...node,
5309
5386
  props: otherProps
5310
- }, context, transformNode, { extraAttrs: [`data-is="{{${componentVar}}}"`] });
5387
+ }, context, transformNode, { extraAttrs: [`data-is="${renderMustache(componentVar, context)}"`] });
5311
5388
  for (const prop of otherProps) if (prop.type === NodeTypes.ATTRIBUTE) {
5312
5389
  const attr = transformAttribute(prop, context);
5313
5390
  if (attr) attrs.push(attr);
@@ -5318,7 +5395,7 @@ function transformComponentElement(node, context, transformNode) {
5318
5395
  const children = node.children.map((child) => transformNode(child, context)).join("");
5319
5396
  const attrString = attrs.length ? ` ${attrs.join(" ")}` : "";
5320
5397
  context.warnings.push("动态组件使用 data-is 属性,可能需要小程序运行时支持。");
5321
- return `<component data-is="{{${componentVar}}}"${attrString}>${children}</component>`;
5398
+ return `<component data-is="${renderMustache(componentVar, context)}"${attrString}>${children}</component>`;
5322
5399
  }
5323
5400
 
5324
5401
  //#endregion
@@ -5331,7 +5408,7 @@ function transformNormalElement(node, context, transformNode) {
5331
5408
  const { attrs, vTextExp } = collectElementAttributes(node, context);
5332
5409
  let children = "";
5333
5410
  if (node.children.length > 0) children = node.children.map((child) => transformNode(child, context)).join("");
5334
- if (vTextExp !== void 0) children = `{{${vTextExp}}}`;
5411
+ if (vTextExp !== void 0) children = renderMustache(vTextExp, context);
5335
5412
  const attrString = attrs.length ? ` ${attrs.join(" ")}` : "";
5336
5413
  return children ? `<${tag}${attrString}>${children}</${tag}>` : `<${tag}${attrString} />`;
5337
5414
  }
@@ -5339,6 +5416,7 @@ function transformNormalElement(node, context, transformNode) {
5339
5416
  //#endregion
5340
5417
  //#region src/plugins/vue/compiler/template/elements/tag-structural.ts
5341
5418
  function transformIfElement(node, context, transformNode) {
5419
+ const renderTemplateMustache = (exp) => renderMustache(exp, context);
5342
5420
  const ifDirective = node.props.find((prop) => prop.type === NodeTypes.DIRECTIVE && (prop.name === "if" || prop.name === "else-if" || prop.name === "else"));
5343
5421
  if (!ifDirective)
5344
5422
  /* istanbul ignore next */
@@ -5354,14 +5432,15 @@ function transformIfElement(node, context, transformNode) {
5354
5432
  const dir = ifDirective;
5355
5433
  if (dir.name === "if" && dir.exp) {
5356
5434
  const expValue = normalizeWxmlExpressionWithContext(dir.exp.type === NodeTypes.SIMPLE_EXPRESSION ? dir.exp.content : "", context);
5357
- return context.platform.wrapIf(expValue, content);
5435
+ return context.platform.wrapIf(expValue, content, renderTemplateMustache);
5358
5436
  } else if (dir.name === "else-if" && dir.exp) {
5359
5437
  const expValue = normalizeWxmlExpressionWithContext(dir.exp.type === NodeTypes.SIMPLE_EXPRESSION ? dir.exp.content : "", context);
5360
- return context.platform.wrapElseIf(expValue, content);
5438
+ return context.platform.wrapElseIf(expValue, content, renderTemplateMustache);
5361
5439
  } else if (dir.name === "else") return context.platform.wrapElse(content);
5362
5440
  return content;
5363
5441
  }
5364
5442
  function transformForElement(node, context, transformNode) {
5443
+ const renderTemplateMustache = (exp) => renderMustache(exp, context);
5365
5444
  const forDirective = node.props.find((prop) => prop.type === NodeTypes.DIRECTIVE && prop.name === "for");
5366
5445
  if (!forDirective || !forDirective.exp) return transformNormalElement(node, context, transformNode);
5367
5446
  const forInfo = parseForExpression(forDirective.exp.type === NodeTypes.SIMPLE_EXPRESSION ? forDirective.exp.content : "");
@@ -5387,7 +5466,7 @@ function transformForElement(node, context, transformNode) {
5387
5466
  ...node,
5388
5467
  props: otherProps
5389
5468
  };
5390
- const extraAttrs = listExp ? context.platform.forAttrs(listExp, forInfo.item, forInfo.index) : [];
5469
+ const extraAttrs = listExp ? context.platform.forAttrs(listExp, renderTemplateMustache, forInfo.item, forInfo.index) : [];
5391
5470
  const slotDirective = findSlotDirective(elementWithoutFor);
5392
5471
  const templateSlotChildren = elementWithoutFor.children.filter((child) => child.type === NodeTypes.ELEMENT && child.tag === "template" && findSlotDirective(child));
5393
5472
  if (slotDirective || templateSlotChildren.length > 0) return transformComponentWithSlots(elementWithoutFor, context, transformNode, {
@@ -5400,7 +5479,7 @@ function transformForElement(node, context, transformNode) {
5400
5479
  });
5401
5480
  let children = "";
5402
5481
  if (elementWithoutFor.children.length > 0) children = elementWithoutFor.children.map((child) => transformNode(child, context)).join("");
5403
- if (vTextExp !== void 0) children = `{{${vTextExp}}}`;
5482
+ if (vTextExp !== void 0) children = renderMustache(vTextExp, context);
5404
5483
  const { tag } = elementWithoutFor;
5405
5484
  const attrString = attrs.length ? ` ${attrs.join(" ")}` : "";
5406
5485
  return children ? `<${tag}${attrString}>${children}</${tag}>` : `<${tag}${attrString} />`;
@@ -5420,6 +5499,7 @@ function transformKeepAliveElement(node, context, transformNode) {
5420
5499
  return `<block data-keep-alive="true">${node.children.map((child) => transformNode(child, context)).join("")}</block>`;
5421
5500
  }
5422
5501
  function transformTemplateElement(node, context, transformNode) {
5502
+ const renderTemplateMustache = (exp) => renderMustache(exp, context);
5423
5503
  let nameAttr = "";
5424
5504
  let isAttr = "";
5425
5505
  let dataAttr = "";
@@ -5454,11 +5534,11 @@ function transformTemplateElement(node, context, transformNode) {
5454
5534
  };
5455
5535
  if (dir.name === "if" && dir.exp) {
5456
5536
  const expValue = normalizeWxmlExpressionWithContext(dir.exp.type === NodeTypes.SIMPLE_EXPRESSION ? dir.exp.content : "", context);
5457
- return context.platform.wrapIf(expValue, children);
5537
+ return context.platform.wrapIf(expValue, children, renderTemplateMustache);
5458
5538
  }
5459
5539
  if (dir.name === "else-if" && dir.exp) {
5460
5540
  const expValue = normalizeWxmlExpressionWithContext(dir.exp.type === NodeTypes.SIMPLE_EXPRESSION ? dir.exp.content : "", context);
5461
- return context.platform.wrapElseIf(expValue, children);
5541
+ return context.platform.wrapElseIf(expValue, children, renderTemplateMustache);
5462
5542
  }
5463
5543
  if (dir.name === "else") return context.platform.wrapElse(children);
5464
5544
  return transformIfElement(fakeNode, context, transformNode);
@@ -5499,9 +5579,9 @@ function transformText(node, _context) {
5499
5579
  }
5500
5580
  function transformInterpolation(node, context) {
5501
5581
  const { content } = node;
5502
- if (content.type === NodeTypes.SIMPLE_EXPRESSION) return `{{${normalizeWxmlExpressionWithContext(content.content, context)}}}`;
5582
+ if (content.type === NodeTypes.SIMPLE_EXPRESSION) return renderMustache(normalizeWxmlExpressionWithContext(content.content, context), context);
5503
5583
  /* istanbul ignore next */
5504
- return "{{}}";
5584
+ return renderMustache("", context);
5505
5585
  }
5506
5586
  function transformNode(node, context) {
5507
5587
  switch (node.type) {
@@ -5544,6 +5624,8 @@ function compileVueTemplateToWxml(template, filename, options) {
5544
5624
  slotPropStack: [],
5545
5625
  rewriteScopedSlot: false,
5546
5626
  classStyleRuntime: resolvedRuntime === "wxs" ? "wxs" : "js",
5627
+ objectLiteralBindMode: options?.objectLiteralBindMode ?? "runtime",
5628
+ mustacheInterpolation: options?.mustacheInterpolation ?? "compact",
5547
5629
  classStyleBindings: [],
5548
5630
  classStyleWxs: false,
5549
5631
  classStyleWxsExtension: wxsExtension,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@wevu/compiler",
3
3
  "type": "module",
4
- "version": "0.1.2",
4
+ "version": "6.6.4",
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",