@wevu/compiler 6.21.0 → 6.23.0

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.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { createRequire } from "node:module";
2
- import { WEAPP_VITE_RUNTIME_REACTIVITY_VIRTUAL_ID, WEAPP_VITE_RUNTIME_TEMPLATE_VIRTUAL_ID, WEAPP_VITE_RUNTIME_VIRTUAL_ID, WEVU_CLASS_STYLE_RUNTIME_FILE, WEVU_CLASS_STYLE_RUNTIME_MODULE, WEVU_EXPRESSION_ERROR_IDENTIFIER, WEVU_FUNCTION_PROP_PATHS_KEY, WEVU_INLINE_HANDLER, WEVU_INLINE_MAP_KEY, WEVU_IS_PAGE_KEY, WEVU_JSX_ISLAND_DATA_KEY, WEVU_JSX_ISLAND_HANDLER, WEVU_JSX_ISLAND_TEMPLATE_NAME, WEVU_LAYOUT_HOSTS_KEY, WEVU_LAYOUT_HOST_ID_PREFIX, WEVU_LAYOUT_HOST_REF_PREFIX, WEVU_MODEL_HANDLER, WEVU_OWNER_HANDLER, WEVU_PROPS_ALIASES_KEY, WEVU_PROPS_DERIVED_KEYS_KEY, WEVU_PROPS_KEY, WEVU_SLOT_FALLBACK_VIRTUAL_HOST_BASE, WEVU_SLOT_FALLBACK_VIRTUAL_HOST_TAG_NAME, WEVU_SLOT_FUNCTION_TOKEN, WEVU_SLOT_NAMES_ATTR, WEVU_SLOT_NAMES_PROP, WEVU_SLOT_OWNER_ID_ATTR, WEVU_SLOT_OWNER_ID_KEY, WEVU_SLOT_OWNER_ID_PROP, WEVU_SLOT_OWNER_KEY, WEVU_SLOT_OWNER_PROXY_KEY, WEVU_SLOT_PROPS_ATTR, WEVU_SLOT_PROPS_DATA_KEY, WEVU_SLOT_PROPS_KEY, WEVU_SLOT_SCOPE_ATTR, WEVU_SLOT_SCOPE_KEY, WEVU_TEMPLATE_REFS_KEY, WEVU_TEMPLATE_REF_CLASS_PREFIX } from "@weapp-core/constants";
3
- import { getMiniProgramRuntimeGlobalKeys, getMiniProgramTemplatePreset, removeExtensionDeep } from "@weapp-core/shared";
2
+ import { WEAPP_I18N_RUNTIME_MARKER, WEAPP_VITE_RUNTIME_REACTIVITY_VIRTUAL_ID, WEAPP_VITE_RUNTIME_TEMPLATE_VIRTUAL_ID, WEAPP_VITE_RUNTIME_VIRTUAL_ID, WEVU_CLASS_STYLE_RUNTIME_FILE, WEVU_CLASS_STYLE_RUNTIME_MODULE, WEVU_CSS_MODULES_KEY, WEVU_CSS_VARS_STYLE_KEY, WEVU_EXPRESSION_ERROR_IDENTIFIER, WEVU_FUNCTION_PROP_PATHS_KEY, WEVU_INLINE_HANDLER, WEVU_INLINE_MAP_KEY, WEVU_IS_PAGE_KEY, WEVU_JSX_ISLAND_DATA_KEY, WEVU_JSX_ISLAND_HANDLER, WEVU_JSX_ISLAND_TEMPLATE_NAME, WEVU_LAYOUT_HOSTS_KEY, WEVU_LAYOUT_HOST_ID_PREFIX, WEVU_LAYOUT_HOST_REF_PREFIX, WEVU_MODEL_HANDLER, WEVU_OWNER_HANDLER, WEVU_PROPS_ALIASES_KEY, WEVU_PROPS_DERIVED_KEYS_KEY, WEVU_PROPS_KEY, WEVU_SLOT_FALLBACK_VIRTUAL_HOST_BASE, WEVU_SLOT_FALLBACK_VIRTUAL_HOST_TAG_NAME, WEVU_SLOT_FUNCTION_TOKEN, WEVU_SLOT_NAMES_ATTR, WEVU_SLOT_NAMES_PROP, WEVU_SLOT_OWNER_ID_ATTR, WEVU_SLOT_OWNER_ID_KEY, WEVU_SLOT_OWNER_ID_PROP, WEVU_SLOT_OWNER_KEY, WEVU_SLOT_OWNER_PROXY_KEY, WEVU_SLOT_PROPS_ATTR, WEVU_SLOT_PROPS_DATA_KEY, WEVU_SLOT_PROPS_KEY, WEVU_SLOT_SCOPE_ATTR, WEVU_SLOT_SCOPE_KEY, WEVU_TEMPLATE_REFS_KEY, WEVU_TEMPLATE_REF_CLASS_PREFIX } from "@weapp-core/constants";
3
+ import { escapeWxmlAttribute, escapeWxmlText, getMiniProgramRuntimeGlobalKeys, getMiniProgramTemplatePreset, removeExtensionDeep } from "@weapp-core/shared";
4
4
  import path from "pathe";
5
5
  import { NodeTypes, baseParse } from "@vue/compiler-core";
6
6
  import { createHash } from "node:crypto";
@@ -18,7 +18,7 @@ import { LRUCache } from "lru-cache";
18
18
  import { collectJsxImportedComponentsAndDefaultExportFromBabelAst, collectJsxTemplateTagsFromBabelExpression, getObjectPropertyByKey, getRenderPropertyFromComponentOptions, parseJsLikeWithEngine, resolveRenderExpressionFromComponentOptions, toStaticObjectKey, unwrapTypeScriptExpression } from "@weapp-vite/ast";
19
19
  import vueJsxPlugin from "@vue/babel-plugin-jsx";
20
20
  import { transformSync } from "@weapp-vite/ast/babelCore";
21
- import { compileScript, parse } from "vue/compiler-sfc";
21
+ import { compileScript, compileStyleAsync, parse } from "vue/compiler-sfc";
22
22
  import { fileURLToPath } from "node:url";
23
23
  import postcss from "postcss";
24
24
  import selectorParser from "postcss-selector-parser";
@@ -2523,6 +2523,8 @@ const INTERNAL_RUNTIME_VALUE_EXPORTS = /* @__PURE__ */ new Set([
2523
2523
  "triggerRef",
2524
2524
  "unref",
2525
2525
  "useAttrs",
2526
+ "useCssModule",
2527
+ "useCssVars",
2526
2528
  "useAsyncPullDownRefresh",
2527
2529
  "useBindModel",
2528
2530
  "useBoundingClientRect",
@@ -2605,6 +2607,8 @@ function createImportVisitors(program, state) {
2605
2607
  "resolveComponent",
2606
2608
  "resolveDirective",
2607
2609
  "useAttrs",
2610
+ "useCssModule",
2611
+ "useCssVars",
2608
2612
  "useSlots",
2609
2613
  "useModel",
2610
2614
  "mergeModels",
@@ -3060,7 +3064,8 @@ function buildForExpression(binding, forStack, level, helpers) {
3060
3064
  if (level >= forStack.length) return buildNormalizedExpression(binding, helpers);
3061
3065
  const info = forStack[level];
3062
3066
  const listId = t.identifier(`__wv_list_${level}`);
3063
- const listExp = info.listExpAst ? t.cloneNode(info.listExpAst, true) : t.arrayExpression([]);
3067
+ const listExpAst = !binding.exp.startsWith("v-for :key ") && info.projectedListExpAst ? info.projectedListExpAst : info.listExpAst;
3068
+ const listExp = listExpAst ? t.cloneNode(listExpAst, true) : t.arrayExpression([]);
3064
3069
  const unrefHelper = helpers.unref ? t.cloneNode(helpers.unref) : t.identifier("unref");
3065
3070
  const listUnrefExp = t.callExpression(unrefHelper, [listExp]);
3066
3071
  const listDecl = t.variableDeclaration("let", [t.variableDeclarator(listId, t.arrayExpression([]))]);
@@ -3673,6 +3678,14 @@ function injectFunctionPropPaths(componentOptionsObject, paths) {
3673
3678
  componentOptionsObject.properties.push(t.objectProperty(t.identifier(WEVU_FUNCTION_PROP_PATHS_KEY), t.arrayExpression(uniquePaths.map((path) => t.stringLiteral(path)))));
3674
3679
  return true;
3675
3680
  }
3681
+ function createObjectLiteral(value) {
3682
+ return t.objectExpression(Object.entries(value).map(([key, item]) => t.objectProperty(t.stringLiteral(key), item && typeof item === "object" && !Array.isArray(item) ? createObjectLiteral(item) : t.valueToNode(item))));
3683
+ }
3684
+ function injectCssModules(componentOptionsObject, modules) {
3685
+ if (hasStaticProperty(componentOptionsObject, WEVU_CSS_MODULES_KEY)) return false;
3686
+ componentOptionsObject.properties.push(t.objectProperty(t.stringLiteral(WEVU_CSS_MODULES_KEY), createObjectLiteral(modules)));
3687
+ return true;
3688
+ }
3676
3689
  function createScopedSlotHostPropertyDefinition(typeName, value) {
3677
3690
  return t.objectExpression([t.objectProperty(t.identifier("type"), typeName === "String" ? t.identifier("String") : t.nullLiteral()), t.objectProperty(t.identifier("value"), value === null ? t.nullLiteral() : t.stringLiteral(value))]);
3678
3691
  }
@@ -3806,6 +3819,7 @@ function rewriteDefaultExport(ast, state, options, enabledPageFeatures, serializ
3806
3819
  if (componentOptionsObject) transformed = injectSetupInitialData(componentOptionsObject) || transformed;
3807
3820
  if (componentOptionsObject && options?.relaxStructuredTypeOnlyProps) transformed = relaxStructuredTypeOnlyProps(componentOptionsObject) || transformed;
3808
3821
  if (componentOptionsObject && options?.scopedSlotHostProperties) transformed = injectScopedSlotHostProperties(componentOptionsObject) || transformed;
3822
+ if (componentOptionsObject && options?.cssModules && Object.keys(options.cssModules).length) transformed = injectCssModules(componentOptionsObject, options.cssModules) || transformed;
3809
3823
  if (componentOptionsObject) {
3810
3824
  transformed = injectPropsAliases(componentOptionsObject, options?.propsAliases) || transformed;
3811
3825
  transformed = injectPropsDerivedKeys(componentOptionsObject, options?.propsDerivedKeys) || transformed;
@@ -3928,6 +3942,31 @@ function createInlineExpressionId(seed) {
3928
3942
  return `i${seed.toString(36)}`;
3929
3943
  }
3930
3944
  //#endregion
3945
+ //#region src/plugins/vue/compiler/template/expression/numeric.ts
3946
+ const DIGIT_NUMERIC_SEPARATOR_RE = /\d_\d/;
3947
+ const NON_DECIMAL_NUMERIC_LITERAL_RE = /\b0[bxo][\da-f_]/i;
3948
+ const DECIMAL_BIGINT_LITERAL_RE = /\b\d[\d_]*n\b/;
3949
+ const NON_DECIMAL_NUMERIC_RAW_RE = /^0[bxo]/i;
3950
+ function hasExtendedNumericLiteralSyntax(exp) {
3951
+ return DIGIT_NUMERIC_SEPARATOR_RE.test(exp) || NON_DECIMAL_NUMERIC_LITERAL_RE.test(exp) || DECIMAL_BIGINT_LITERAL_RE.test(exp);
3952
+ }
3953
+ function serializeBigIntForWxml(value) {
3954
+ const asNumber = Number(value);
3955
+ if (!Number.isSafeInteger(asNumber)) return t.stringLiteral(value.toString());
3956
+ return asNumber < 0 ? t.unaryExpression("-", t.numericLiteral(Math.abs(asNumber))) : t.numericLiteral(asNumber);
3957
+ }
3958
+ function normalizeTopLevelBigInt(expression) {
3959
+ if (t.isBigIntLiteral(expression)) return serializeBigIntForWxml(BigInt(expression.value));
3960
+ if (t.isUnaryExpression(expression, { operator: "-" }) && t.isBigIntLiteral(expression.argument)) return serializeBigIntForWxml(-BigInt(expression.argument.value));
3961
+ return expression;
3962
+ }
3963
+ function canonicalizeNumericLiteral(node) {
3964
+ const raw = node.extra?.raw;
3965
+ if (typeof raw !== "string" || !raw.includes("_") && !NON_DECIMAL_NUMERIC_RAW_RE.test(raw)) return;
3966
+ delete node.extra?.raw;
3967
+ delete node.extra?.rawValue;
3968
+ }
3969
+ //#endregion
3931
3970
  //#region src/plugins/vue/compiler/template/expression/wxml.ts
3932
3971
  function templateLiteralToConcat(node) {
3933
3972
  const segments = [];
@@ -4027,7 +4066,8 @@ function normalizeWxmlExpression(exp) {
4027
4066
  const hasTypeScriptSyntax = /\s(?:as|satisfies)\s/.test(exp) || /[\w$)\]]!(?=[.[\s,);:?]|$)/.test(exp) || /^\s*<[^>]+>/.test(exp);
4028
4067
  const needsVueSlotsRewrite = exp.includes("$slots");
4029
4068
  const needsThisRewrite = /\bthis\./.test(exp);
4030
- if (!exp.includes("`") && !exp.includes("??") && !exp.includes("?.") && !hasTypeScriptSyntax && !needsVueSlotsRewrite && !needsThisRewrite) return exp;
4069
+ const needsNumericLiteralRewrite = hasExtendedNumericLiteralSyntax(exp);
4070
+ if (!exp.includes("`") && !exp.includes("??") && !exp.includes("?.") && !hasTypeScriptSyntax && !needsVueSlotsRewrite && !needsThisRewrite && !needsNumericLiteralRewrite) return exp;
4031
4071
  try {
4032
4072
  const ast = parse$3(`(${exp})`, {
4033
4073
  sourceType: "module",
@@ -4036,6 +4076,8 @@ function normalizeWxmlExpression(exp) {
4036
4076
  const stmt = ast.program.body[0];
4037
4077
  if (!stmt || !("expression" in stmt)) return exp;
4038
4078
  if (needsVueSlotsRewrite) rewriteVueSlotsExpression(ast);
4079
+ const expressionStatement = stmt;
4080
+ expressionStatement.expression = normalizeTopLevelBigInt(expressionStatement.expression);
4039
4081
  traverse(ast, {
4040
4082
  MemberExpression: { exit(path) {
4041
4083
  const node = path.node;
@@ -4052,6 +4094,9 @@ function normalizeWxmlExpression(exp) {
4052
4094
  TSTypeAssertion(path) {
4053
4095
  path.replaceWith(path.node.expression);
4054
4096
  },
4097
+ NumericLiteral(path) {
4098
+ canonicalizeNumericLiteral(path.node);
4099
+ },
4055
4100
  OptionalMemberExpression: { exit(path) {
4056
4101
  if (isOptionalChainNode(path.parentPath.node)) return;
4057
4102
  path.replaceWith(lowerOptionalChain(path.node));
@@ -4089,8 +4134,6 @@ function normalizeWxmlExpression(exp) {
4089
4134
  }
4090
4135
  //#endregion
4091
4136
  //#region src/plugins/jsx/compileJsx/ast.ts
4092
- const ESCAPED_TEXT_RE = /[&<>]/g;
4093
- const ESCAPED_ATTR_RE = /[&"<>]/g;
4094
4137
  const WXML_EXPRESSION_GENERATE_OPTIONS = {
4095
4138
  compact: true,
4096
4139
  jsescOption: {
@@ -4098,23 +4141,8 @@ const WXML_EXPRESSION_GENERATE_OPTIONS = {
4098
4141
  minimal: true
4099
4142
  }
4100
4143
  };
4101
- const ESCAPED_TEXT_MAP = {
4102
- "&": "&amp;",
4103
- "<": "&lt;",
4104
- ">": "&gt;"
4105
- };
4106
- const ESCAPED_ATTR_MAP = {
4107
- "&": "&amp;",
4108
- "\"": "&quot;",
4109
- "<": "&lt;",
4110
- ">": "&gt;"
4111
- };
4112
- function escapeText(value) {
4113
- return value.replace(ESCAPED_TEXT_RE, (ch) => ESCAPED_TEXT_MAP[ch] || ch);
4114
- }
4115
- function escapeAttr(value) {
4116
- return value.replace(ESCAPED_ATTR_RE, (ch) => ESCAPED_ATTR_MAP[ch] || ch);
4117
- }
4144
+ const escapeText = escapeWxmlText;
4145
+ const escapeAttr = escapeWxmlAttribute;
4118
4146
  const WHITESPACE_RE = /\s+/g;
4119
4147
  function normalizeJsxText(value) {
4120
4148
  return value.replace(WHITESPACE_RE, " ");
@@ -6609,106 +6637,69 @@ function transformNestedWxssVars(source) {
6609
6637
  }
6610
6638
  //#endregion
6611
6639
  //#region src/plugins/vue/compiler/style.ts
6612
- const CSS_RULE_RE = /([^{]+)(\{[^}]*\})/g;
6613
- const CSS_CLASS_RE = /\.([a-z_][\w-]*)(?:\[[^\]]+\])?\s*\{/gi;
6640
+ function normalizeStyleError(error) {
6641
+ return error instanceof Error ? error.message : String(error);
6642
+ }
6643
+ function hasSlottedScopeSelector(source, slottedScopeId) {
6644
+ let found = false;
6645
+ const processor = selectorParser((selectors) => {
6646
+ selectors.walkAttributes((attribute) => {
6647
+ if (attribute.attribute === slottedScopeId) found = true;
6648
+ });
6649
+ });
6650
+ postcss.parse(source).walkRules((rule) => {
6651
+ if (!found) processor.processSync(rule.selector);
6652
+ });
6653
+ return found;
6654
+ }
6655
+ /**
6656
+ * compiler-sfc 已在 scoped 插件中处理 deep 选择器,此函数保留为兼容入口。
6657
+ */
6614
6658
  function transformVueDeepSelectors(source) {
6615
- if (!source.includes(":deep") && !source.includes("::v-deep")) return source;
6616
6659
  const root = postcss.parse(source);
6617
6660
  const processor = selectorParser((selectors) => {
6618
6661
  selectors.walkTags((tag) => {
6619
- const name = tag.value.toLowerCase();
6620
- if (DEFAULT_HTML_TO_WXML_TAG_MAP[name] !== name && DEFAULT_HTML_TO_WXML_TAG_MAP[name]) tag.replaceWith(selectorParser.className({ value: name }));
6662
+ const mapped = DEFAULT_HTML_TO_WXML_TAG_MAP[tag.value.toLowerCase()];
6663
+ if (mapped && mapped !== tag.value.toLowerCase()) tag.replaceWith(selectorParser.className({ value: tag.value.toLowerCase() }));
6621
6664
  });
6622
6665
  selectors.walkPseudos((pseudo) => {
6623
- if (pseudo.value !== ":deep" && pseudo.value !== "::v-deep") return;
6666
+ if (![":deep", "::v-deep"].includes(pseudo.value)) return;
6624
6667
  const replacement = pseudo.nodes?.[0]?.nodes.map((node) => node.clone()) ?? [];
6625
- if (replacement.length > 0) pseudo.replaceWith(...replacement);
6626
- else {
6627
- const previous = pseudo.prev();
6628
- const next = pseudo.next();
6629
- if (next?.type === "combinator" && (!previous || previous.type === "combinator")) next.remove();
6630
- pseudo.remove();
6631
- }
6668
+ replacement.length ? pseudo.replaceWith(...replacement) : pseudo.remove();
6632
6669
  });
6633
6670
  });
6634
6671
  root.walkRules((rule) => {
6635
- if (rule.selector.includes(":deep") || rule.selector.includes("::v-deep")) rule.selector = processor.processSync(rule.selector);
6672
+ rule.selector = processor.processSync(rule.selector).replace(/\s{2,}/g, " ").trim();
6636
6673
  });
6637
6674
  return root.toString();
6638
6675
  }
6639
6676
  /**
6640
- * 转换 scoped CSS
6641
- * 为每个选择器添加特定的 scoped 属性
6677
+ * 将 Vue SFC style 块编译为可交给 Vite CSS 管线的内容。
6642
6678
  */
6643
- function transformScopedCss(source, id) {
6644
- const scopedId = `data-v-${id}`;
6645
- return source.replace(CSS_RULE_RE, (match, selector, rules) => {
6646
- const trimmedSelector = selector.trim();
6647
- if (!trimmedSelector) return match;
6648
- if (trimmedSelector.includes("[") || trimmedSelector.includes(":deep(") || trimmedSelector.includes(":slotted(")) return match;
6649
- if (trimmedSelector.startsWith("@")) return match;
6650
- return `${trimmedSelector.split(",").map((s) => {
6651
- return `${s.trim()}[${scopedId}]`;
6652
- }).join(", ")} ${rules}`;
6679
+ async function compileVueStyleToWxss(styleBlock, options) {
6680
+ const filename = options.filename ?? `style-${options.id}.${styleBlock.lang || "css"}`;
6681
+ const moduleName = typeof styleBlock.module === "string" ? styleBlock.module : typeof options.modules === "string" ? options.modules : "$style";
6682
+ const modules = Boolean(options.modules || styleBlock.module);
6683
+ const result = await compileStyleAsync({
6684
+ filename,
6685
+ id: `data-v-${options.id}`,
6686
+ source: styleBlock.content,
6687
+ scoped: options.transformScoped !== false && Boolean(options.scoped || styleBlock.scoped),
6688
+ modules,
6689
+ modulesOptions: modules ? { generateScopedName: (name) => `${name}_${options.id}` } : void 0,
6690
+ preprocessLang: styleBlock.lang,
6691
+ preprocessOptions: options.preprocessOptions
6653
6692
  });
6654
- }
6655
- /**
6656
- * 样式转换:CSS → WXSS
6657
- * 处理小程序不支持的 CSS 特性
6658
- */
6659
- /**
6660
- * 生成简单的 hash
6661
- */
6662
- function generateHash(str) {
6663
- let hash = 0;
6664
- for (let i = 0; i < str.length; i++) {
6665
- const char = str.charCodeAt(i);
6666
- hash = (hash << 5) - hash + char;
6667
- hash = hash & hash;
6668
- }
6669
- return Math.abs(hash).toString(36) + str.length.toString(36);
6670
- }
6671
- /**
6672
- * 转换 CSS Modules
6673
- */
6674
- function transformCssModules(source, id) {
6675
- const classes = {};
6676
- const hash = generateHash(id);
6677
- const classRegex = new RegExp(CSS_CLASS_RE.source, CSS_CLASS_RE.flags);
6678
- const foundClasses = [];
6679
- let result = classRegex.exec(source);
6680
- while (result !== null) {
6681
- foundClasses.push(result[1]);
6682
- result = classRegex.exec(source);
6683
- }
6684
- for (const className of foundClasses) classes[className] = `${className}_${hash}`;
6685
- let code = source;
6686
- for (const [original, scoped] of Object.entries(classes)) {
6687
- const regex = new RegExp(`\\.${original}\\b`, "g");
6688
- code = code.replace(regex, `.${scoped}`);
6689
- }
6693
+ if (result.errors.length) throw new Error(`SFC 样式编译失败(${filename}):${result.errors.map(normalizeStyleError).join("; ")}`);
6690
6694
  return {
6691
- code,
6692
- classes
6695
+ code: options.preserveDeepSelectors ? result.code : transformVueDeepSelectors(result.code),
6696
+ map: result.map ? JSON.stringify(result.map) : void 0,
6697
+ scopedId: options.scoped || styleBlock.scoped ? `data-v-${options.id}` : void 0,
6698
+ usesSlotted: hasSlottedScopeSelector(result.code, `data-v-${options.id}-s`),
6699
+ modules: result.modules ? { [moduleName]: result.modules } : void 0,
6700
+ dependencies: [...result.dependencies]
6693
6701
  };
6694
6702
  }
6695
- /**
6696
- * 将 Vue SFC 的 style 块转换为 WXSS
6697
- */
6698
- function compileVueStyleToWxss(styleBlock, options) {
6699
- const { id, scoped, modules, preserveDeepSelectors, transformScoped = true } = options;
6700
- let code = styleBlock.content;
6701
- if (transformScoped && (scoped || styleBlock.scoped)) code = transformScopedCss(code, id);
6702
- if (modules || styleBlock.module) {
6703
- const moduleName = typeof styleBlock.module === "string" ? styleBlock.module : "$style";
6704
- const moduleResult = transformCssModules(code, id);
6705
- return {
6706
- code: preserveDeepSelectors ? moduleResult.code : transformVueDeepSelectors(moduleResult.code),
6707
- modules: { [moduleName]: moduleResult.classes }
6708
- };
6709
- }
6710
- return { code: preserveDeepSelectors ? code : transformVueDeepSelectors(code) };
6711
- }
6712
6703
  //#endregion
6713
6704
  //#region src/plugins/vue/compiler/template/classStyleRuntime.ts
6714
6705
  /**
@@ -6968,11 +6959,93 @@ function getClassStyleWxsSource(options = {}) {
6968
6959
  ].join("\n");
6969
6960
  }
6970
6961
  //#endregion
6971
- //#region src/plugins/vue/compiler/template/elements/forExpression.ts
6962
+ //#region src/plugins/vue/compiler/template/expression/inlineShared.ts
6972
6963
  const IDENTIFIER_RE$5 = /^[A-Z_$][\w$]*$/i;
6964
+ const INLINE_GLOBALS = /* @__PURE__ */ new Set([
6965
+ "Math",
6966
+ "Number",
6967
+ "Date",
6968
+ "Array",
6969
+ "Object",
6970
+ "Boolean",
6971
+ "String",
6972
+ "RegExp",
6973
+ "Map",
6974
+ "Set",
6975
+ "JSON",
6976
+ "Intl",
6977
+ "Promise",
6978
+ "console",
6979
+ "Infinity",
6980
+ "undefined",
6981
+ "NaN",
6982
+ "isFinite",
6983
+ "isNaN",
6984
+ "parseFloat",
6985
+ "parseInt",
6986
+ "decodeURI",
6987
+ "decodeURIComponent",
6988
+ "encodeURI",
6989
+ "encodeURIComponent",
6990
+ "require",
6991
+ "arguments",
6992
+ WEVU_CLASS_STYLE_RUNTIME_MODULE,
6993
+ "__wevuUnref",
6994
+ "globalThis",
6995
+ "setTimeout",
6996
+ "clearTimeout",
6997
+ "setInterval",
6998
+ "clearInterval",
6999
+ "Page",
7000
+ "App",
7001
+ "Component",
7002
+ "requirePlugin",
7003
+ "getApp",
7004
+ "getCurrentPages",
7005
+ "ctx",
7006
+ "scope",
7007
+ ...getMiniProgramRuntimeGlobalKeys()
7008
+ ]);
7009
+ function createMemberAccess$1(target, prop) {
7010
+ if (IDENTIFIER_RE$5.test(prop)) return t.memberExpression(t.identifier(target), t.identifier(prop));
7011
+ return t.memberExpression(t.identifier(target), t.stringLiteral(prop), true);
7012
+ }
7013
+ function replaceIdentifierWithExpression$1(path, replacement) {
7014
+ const parent = path.parentPath;
7015
+ if (parent.isObjectProperty() && parent.node.shorthand && parent.node.key === path.node) {
7016
+ parent.node.shorthand = false;
7017
+ parent.node.value = replacement;
7018
+ return;
7019
+ }
7020
+ path.replaceWith(replacement);
7021
+ }
7022
+ //#endregion
7023
+ //#region src/plugins/vue/compiler/template/expression/forItemAccess.ts
7024
+ function getForItemAccess(context, name) {
7025
+ for (let index = context.forStack.length - 1; index >= 0; index -= 1) {
7026
+ const forInfo = context.forStack[index];
7027
+ if (forInfo?.item === name && forInfo.itemAccess) return forInfo.itemAccess;
7028
+ }
7029
+ return name;
7030
+ }
7031
+ function rewriteForItemAccess(ast, context) {
7032
+ const itemAccesses = /* @__PURE__ */ new Map();
7033
+ for (const forInfo of context.forStack) if (forInfo.item && forInfo.itemAccess) itemAccesses.set(forInfo.item, forInfo.itemAccess);
7034
+ if (!itemAccesses.size) return;
7035
+ traverse(ast, { Identifier(path) {
7036
+ if (!path.isReferencedIdentifier() || path.scope.hasBinding(path.node.name)) return;
7037
+ const replacement = itemAccesses.get(path.node.name);
7038
+ if (!replacement) return;
7039
+ replaceIdentifierWithExpression$1(path, replacement.split(".").slice(1).reduce((target, property) => t.memberExpression(target, t.identifier(property)), t.identifier(path.node.name)));
7040
+ path.skip();
7041
+ } });
7042
+ }
7043
+ //#endregion
7044
+ //#region src/plugins/vue/compiler/template/elements/forExpression.ts
7045
+ const IDENTIFIER_RE$4 = /^[A-Z_$][\w$]*$/i;
6973
7046
  const FOR_ITEM_ALIAS_PLACEHOLDER = "__wv_for_item__";
6974
7047
  function isIdentifier(value) {
6975
- return IDENTIFIER_RE$5.test(value);
7048
+ return IDENTIFIER_RE$4.test(value);
6976
7049
  }
6977
7050
  function splitTopLevelByComma(input) {
6978
7051
  const out = [];
@@ -7248,7 +7321,7 @@ function withSlotProps(context, mapping, fn) {
7248
7321
  popSlotProps(context);
7249
7322
  }
7250
7323
  }
7251
- const IDENTIFIER_RE$4 = /^[A-Z_$][\w$]*$/i;
7324
+ const IDENTIFIER_RE$3 = /^[A-Z_$][\w$]*$/i;
7252
7325
  const BIND_SHORTHAND_ARG_RE = /^[A-Z_$][\w$]*(?:-[A-Z_$][\w$]*)*$/i;
7253
7326
  const BACKSLASH_RE$2 = /\\/g;
7254
7327
  const SINGLE_QUOTE_RE$2 = /'/g;
@@ -7269,7 +7342,7 @@ function collectScopePropMapping(context) {
7269
7342
  const mapping = {};
7270
7343
  if (!context.slotMultipleInstance) return mapping;
7271
7344
  for (const scope of context.scopeStack) for (const name of scope) {
7272
- if (!IDENTIFIER_RE$4.test(name)) continue;
7345
+ if (!IDENTIFIER_RE$3.test(name)) continue;
7273
7346
  if (!hasOwn(mapping, name)) mapping[name] = name;
7274
7347
  }
7275
7348
  return mapping;
@@ -7281,7 +7354,7 @@ function buildScopePropsExpression(context) {
7281
7354
  const mapping = collectScopePropMapping(context);
7282
7355
  const keys = Object.keys(mapping);
7283
7356
  if (!keys.length) return null;
7284
- return `[${keys.map((key) => `${toWxmlStringLiteral$1(key)},${key}`).join(",")}]`;
7357
+ return `[${keys.map((key) => `${toWxmlStringLiteral$1(key)},${getForItemAccess(context, key)}`).join(",")}]`;
7285
7358
  }
7286
7359
  function hashString(input) {
7287
7360
  let hash = 0;
@@ -7350,7 +7423,7 @@ function collectForAliasMapping$2(context) {
7350
7423
  }
7351
7424
  return mapping;
7352
7425
  }
7353
- function replaceIdentifierWithExpression$1(path, replacement) {
7426
+ function replaceIdentifierWithExpression(path, replacement) {
7354
7427
  const parent = path.parentPath;
7355
7428
  if (parent.isObjectProperty() && parent.node.shorthand && parent.node.key === path.node) {
7356
7429
  parent.node.shorthand = false;
@@ -7359,7 +7432,7 @@ function replaceIdentifierWithExpression$1(path, replacement) {
7359
7432
  }
7360
7433
  path.replaceWith(replacement);
7361
7434
  }
7362
- const IDENTIFIER_RE$3 = /^[A-Z_$][\w$]*$/i;
7435
+ const IDENTIFIER_RE$2 = /^[A-Z_$][\w$]*$/i;
7363
7436
  function rewriteScopedSlotExpression(exp, context) {
7364
7437
  const normalized = normalizeWxmlExpression(exp);
7365
7438
  const parsed = parseBabelExpressionFile(normalized);
@@ -7370,7 +7443,7 @@ function rewriteScopedSlotExpression(exp, context) {
7370
7443
  const forAliases = collectForAliasMapping$2(context);
7371
7444
  const createMemberAccess = (target, prop) => {
7372
7445
  if (!prop) return t.identifier(target);
7373
- if (IDENTIFIER_RE$3.test(prop)) return t.memberExpression(t.identifier(target), t.identifier(prop));
7446
+ if (IDENTIFIER_RE$2.test(prop)) return t.memberExpression(t.identifier(target), t.identifier(prop));
7374
7447
  return t.memberExpression(t.identifier(target), t.stringLiteral(prop), true);
7375
7448
  };
7376
7449
  traverse(ast, { Identifier(path) {
@@ -7381,17 +7454,18 @@ function rewriteScopedSlotExpression(exp, context) {
7381
7454
  if (hasOwn(forAliases, name)) {
7382
7455
  const aliasExp = parseBabelExpression(forAliases[name]);
7383
7456
  if (aliasExp) {
7384
- replaceIdentifierWithExpression$1(path, t.cloneNode(aliasExp, true));
7457
+ replaceIdentifierWithExpression(path, t.cloneNode(aliasExp, true));
7385
7458
  return;
7386
7459
  }
7387
7460
  }
7388
7461
  if (locals.has(name)) return;
7389
7462
  if (hasOwn(slotProps, name)) {
7390
- replaceIdentifierWithExpression$1(path, createMemberAccess(WEVU_SLOT_PROPS_DATA_KEY, slotProps[name]));
7463
+ replaceIdentifierWithExpression(path, createMemberAccess(WEVU_SLOT_PROPS_DATA_KEY, slotProps[name]));
7391
7464
  return;
7392
7465
  }
7393
- replaceIdentifierWithExpression$1(path, createMemberAccess(WEVU_SLOT_OWNER_KEY, name));
7466
+ replaceIdentifierWithExpression(path, createMemberAccess(WEVU_SLOT_OWNER_KEY, name));
7394
7467
  } });
7468
+ rewriteForItemAccess(ast, context);
7395
7469
  const stmt = ast.program.body[0];
7396
7470
  const updatedExpression = stmt && "expression" in stmt ? stmt.expression : null;
7397
7471
  return updatedExpression ? generateExpression(updatedExpression) : normalized;
@@ -7399,7 +7473,7 @@ function rewriteScopedSlotExpression(exp, context) {
7399
7473
  function rewriteForAliasExpression(exp, context) {
7400
7474
  const normalized = normalizeWxmlExpression(exp);
7401
7475
  const forAliases = collectForAliasMapping$2(context);
7402
- if (!Object.keys(forAliases).length) return normalized;
7476
+ if (!Object.keys(forAliases).length && !context.forStack.some((forInfo) => forInfo.itemAccess)) return normalized;
7403
7477
  const parsed = parseBabelExpressionFile(normalized);
7404
7478
  if (!parsed) return normalized;
7405
7479
  const { ast } = parsed;
@@ -7409,9 +7483,10 @@ function rewriteForAliasExpression(exp, context) {
7409
7483
  if (path.scope.hasBinding(name)) return;
7410
7484
  if (hasOwn(forAliases, name)) {
7411
7485
  const aliasExp = parseBabelExpression(forAliases[name]);
7412
- if (aliasExp) replaceIdentifierWithExpression$1(path, t.cloneNode(aliasExp, true));
7486
+ if (aliasExp) replaceIdentifierWithExpression(path, t.cloneNode(aliasExp, true));
7413
7487
  }
7414
7488
  } });
7489
+ rewriteForItemAccess(ast, context);
7415
7490
  const stmt = ast.program.body[0];
7416
7491
  const updatedExpression = stmt && "expression" in stmt ? stmt.expression : null;
7417
7492
  return updatedExpression ? generateExpression(updatedExpression) : normalized;
@@ -7521,68 +7596,89 @@ function normalizeStyleBindingExpression(exp, context) {
7521
7596
  return out;
7522
7597
  }
7523
7598
  //#endregion
7524
- //#region src/plugins/vue/compiler/template/expression/inline.ts
7525
- const INLINE_GLOBALS = /* @__PURE__ */ new Set([
7526
- "Math",
7527
- "Number",
7528
- "Date",
7529
- "Array",
7530
- "Object",
7531
- "Boolean",
7532
- "String",
7533
- "RegExp",
7534
- "Map",
7535
- "Set",
7536
- "JSON",
7537
- "Intl",
7538
- "Promise",
7539
- "console",
7540
- "Infinity",
7541
- "undefined",
7542
- "NaN",
7543
- "isFinite",
7544
- "isNaN",
7545
- "parseFloat",
7546
- "parseInt",
7547
- "decodeURI",
7548
- "decodeURIComponent",
7549
- "encodeURI",
7550
- "encodeURIComponent",
7551
- "require",
7552
- "arguments",
7553
- WEVU_CLASS_STYLE_RUNTIME_MODULE,
7554
- "__wevuUnref",
7555
- "globalThis",
7556
- "setTimeout",
7557
- "clearTimeout",
7558
- "setInterval",
7559
- "clearInterval",
7560
- "Page",
7561
- "App",
7562
- "Component",
7563
- "requirePlugin",
7564
- "getApp",
7565
- "getCurrentPages",
7566
- "ctx",
7567
- "scope",
7568
- ...getMiniProgramRuntimeGlobalKeys()
7569
- ]);
7570
- const IDENTIFIER_RE$2 = /^[A-Z_$][\w$]*$/i;
7599
+ //#region src/plugins/vue/compiler/template/expression/forItemResolver.ts
7571
7600
  const SIMPLE_PATH_RE = /^[A-Z_$][\w$]*(?:\.[A-Z_$][\w$]*)*$/i;
7572
- const SCRIPT_SETUP_REF_BINDINGS = /* @__PURE__ */ new Set(["setup-ref", "setup-maybe-ref"]);
7573
- function createMemberAccess$1(target, prop) {
7574
- if (IDENTIFIER_RE$2.test(prop)) return t.memberExpression(t.identifier(target), t.identifier(prop));
7575
- return t.memberExpression(t.identifier(target), t.stringLiteral(prop), true);
7601
+ function rewriteForItemResolverExpression(rawExp, resolvedLocals, resolvedIndexes) {
7602
+ const parsed = parseBabelExpressionFile(rawExp);
7603
+ if (!parsed) return null;
7604
+ traverse(parsed.ast, {
7605
+ Identifier(path) {
7606
+ if (!path.isReferencedIdentifier() || path.scope.hasBinding(path.node.name)) return;
7607
+ const name = path.node.name;
7608
+ const localExpression = resolvedLocals.get(name) ?? resolvedIndexes.get(name);
7609
+ if (localExpression) {
7610
+ replaceIdentifierWithExpression$1(path, t.cloneNode(localExpression, true));
7611
+ path.skip();
7612
+ return;
7613
+ }
7614
+ if (INLINE_GLOBALS.has(name)) return;
7615
+ replaceIdentifierWithExpression$1(path, createMemberAccess$1("ctx", name));
7616
+ path.skip();
7617
+ },
7618
+ ThisExpression(path) {
7619
+ path.replaceWith(t.identifier("ctx"));
7620
+ }
7621
+ });
7622
+ const statement = parsed.ast.program.body[0];
7623
+ return statement && t.isExpressionStatement(statement) ? statement.expression : null;
7576
7624
  }
7577
- function replaceIdentifierWithExpression(path, replacement) {
7578
- const parent = path.parentPath;
7579
- if (parent.isObjectProperty() && parent.node.shorthand && parent.node.key === path.node) {
7580
- parent.node.shorthand = false;
7581
- parent.node.value = replacement;
7582
- return;
7625
+ function buildNestedForItemResolverExpression(targetKey, targetLevel, context, slotProps, indexBindings) {
7626
+ const resolvedLocals = /* @__PURE__ */ new Map();
7627
+ const resolvedIndexes = /* @__PURE__ */ new Map();
7628
+ for (let level = 0; level <= targetLevel; level += 1) {
7629
+ const forInfo = context.forStack[level];
7630
+ const listExp = forInfo?.listExp?.trim() ?? "";
7631
+ const indexBinding = indexBindings[level];
7632
+ if (!forInfo || !listExp || !indexBinding) return null;
7633
+ const root = SIMPLE_PATH_RE.test(listExp) ? listExp.split(".")[0] : "";
7634
+ if (root && hasOwn(slotProps, root) && !resolvedLocals.has(root)) return null;
7635
+ const listExpression = rewriteForItemResolverExpression(listExp, resolvedLocals, resolvedIndexes);
7636
+ if (!listExpression) return null;
7637
+ const indexExpression = createMemberAccess$1("scope", indexBinding.key);
7638
+ const itemExpression = t.memberExpression(listExpression, t.cloneNode(indexExpression), true);
7639
+ if (forInfo.item) resolvedLocals.set(forInfo.item, itemExpression);
7640
+ for (const [alias, aliasExp] of Object.entries(forInfo.itemAliases ?? {})) {
7641
+ const resolvedAlias = rewriteForItemResolverExpression(aliasExp, resolvedLocals, resolvedIndexes);
7642
+ if (resolvedAlias) resolvedLocals.set(alias, resolvedAlias);
7643
+ }
7644
+ const targetExpression = resolvedLocals.get(targetKey);
7645
+ if (level === targetLevel && targetExpression) return generateExpression(t.arrowFunctionExpression([t.identifier("ctx"), t.identifier("scope")], t.cloneNode(targetExpression, true)));
7646
+ resolvedIndexes.set(forInfo.index?.trim() || "index", indexExpression);
7647
+ if (forInfo.key) resolvedIndexes.set(forInfo.key, indexExpression);
7583
7648
  }
7584
- path.replaceWith(replacement);
7649
+ return null;
7585
7650
  }
7651
+ function buildForItemResolverExpression(targetKey, context, slotProps, indexBindings) {
7652
+ let targetLevel = -1;
7653
+ for (let level = context.forStack.length - 1; level >= 0; level -= 1) {
7654
+ const forInfo = context.forStack[level];
7655
+ if (forInfo?.item === targetKey || hasOwn(forInfo?.itemAliases ?? {}, targetKey)) {
7656
+ targetLevel = level;
7657
+ break;
7658
+ }
7659
+ }
7660
+ if (targetLevel < 0) return null;
7661
+ const forInfo = context.forStack[targetLevel];
7662
+ const listExp = forInfo?.listExp?.trim() ?? "";
7663
+ const indexBinding = indexBindings[targetLevel];
7664
+ if (!listExp || !indexBinding) return null;
7665
+ if (forInfo?.item === targetKey && SIMPLE_PATH_RE.test(listExp)) {
7666
+ const root = listExp.split(".")[0];
7667
+ const localRoots = new Set(Object.keys(slotProps));
7668
+ for (let level = 0; level <= targetLevel; level += 1) {
7669
+ const item = context.forStack[level]?.item?.trim();
7670
+ const index = context.forStack[level]?.index?.trim();
7671
+ if (item) localRoots.add(item);
7672
+ if (index) localRoots.add(index);
7673
+ localRoots.add("index");
7674
+ }
7675
+ if (!localRoots.has(root)) return `({type:'for-item',path:${JSON.stringify(listExp)},indexKey:${JSON.stringify(indexBinding.key)}})`;
7676
+ }
7677
+ return buildNestedForItemResolverExpression(targetKey, targetLevel, context, slotProps, indexBindings);
7678
+ }
7679
+ //#endregion
7680
+ //#region src/plugins/vue/compiler/template/expression/inline.ts
7681
+ const SCRIPT_SETUP_REF_BINDINGS = /* @__PURE__ */ new Set(["setup-ref", "setup-maybe-ref"]);
7586
7682
  function resolveSlotPropBinding(slotProps, name) {
7587
7683
  if (!hasOwn(slotProps, name)) return null;
7588
7684
  const prop = slotProps[name];
@@ -7599,11 +7695,11 @@ function rewriteExpressionAst(ast, locals, options) {
7599
7695
  if (path.scope.getBinding(name)) return;
7600
7696
  if (locals.has(name)) {
7601
7697
  options?.markLocal?.(name);
7602
- replaceIdentifierWithExpression(path, createMemberAccess$1("scope", name));
7698
+ replaceIdentifierWithExpression$1(path, createMemberAccess$1("scope", name));
7603
7699
  return;
7604
7700
  }
7605
7701
  if (INLINE_GLOBALS.has(name)) return;
7606
- replaceIdentifierWithExpression(path, createMemberAccess$1("ctx", name));
7702
+ replaceIdentifierWithExpression$1(path, createMemberAccess$1("ctx", name));
7607
7703
  },
7608
7704
  ThisExpression(path) {
7609
7705
  path.replaceWith(t.identifier("ctx"));
@@ -7617,28 +7713,6 @@ function buildInlineIndexBindings(context) {
7617
7713
  binding: forInfo.index?.trim() || "index"
7618
7714
  }));
7619
7715
  }
7620
- function buildForItemResolverExpression(targetKey, context, slotProps, indexBindings) {
7621
- let targetLevel = -1;
7622
- for (let level = context.forStack.length - 1; level >= 0; level -= 1) if (context.forStack[level]?.item === targetKey) {
7623
- targetLevel = level;
7624
- break;
7625
- }
7626
- if (targetLevel < 0) return null;
7627
- const listExp = context.forStack[targetLevel]?.listExp?.trim() ?? "";
7628
- const indexBinding = indexBindings[targetLevel];
7629
- if (!listExp || !indexBinding || !SIMPLE_PATH_RE.test(listExp)) return null;
7630
- const root = listExp.split(".")[0];
7631
- const localRoots = new Set(Object.keys(slotProps));
7632
- for (let level = 0; level <= targetLevel; level += 1) {
7633
- const item = context.forStack[level]?.item?.trim();
7634
- const index = context.forStack[level]?.index?.trim();
7635
- if (item) localRoots.add(item);
7636
- if (index) localRoots.add(index);
7637
- localRoots.add("index");
7638
- }
7639
- if (localRoots.has(root)) return null;
7640
- return `({type:'for-item',path:${JSON.stringify(listExp)},indexKey:${JSON.stringify(indexBinding.key)}})`;
7641
- }
7642
7716
  function buildScopeResolvers(usedLocals, context, slotProps, indexBindings) {
7643
7717
  const resolvers = [];
7644
7718
  for (const key of usedLocals) {
@@ -7800,7 +7874,7 @@ function createThisMemberAccess(prop) {
7800
7874
  function createUnrefCall(exp) {
7801
7875
  return t.callExpression(t.identifier("__wevuUnref"), [exp]);
7802
7876
  }
7803
- function createHasOwnPropertyCall(target, key) {
7877
+ function createHasOwnPropertyCall$1(target, key) {
7804
7878
  return t.callExpression(t.memberExpression(t.memberExpression(t.memberExpression(t.identifier("Object"), t.identifier("prototype")), t.identifier("hasOwnProperty")), t.identifier("call")), [target, t.stringLiteral(key)]);
7805
7879
  }
7806
7880
  function createResolvePropValueCall(name, fallback, preferProps = false) {
@@ -7816,7 +7890,7 @@ function createPropsKeyAccessFallback(name, fallback) {
7816
7890
  const propsObject = createThisMemberAccess(WEVU_PROPS_KEY);
7817
7891
  const propsAccess = createMemberAccess(propsObject, name);
7818
7892
  const hasPropsObject = t.binaryExpression("!=", propsObject, t.nullLiteral());
7819
- const hasPropsValue = t.logicalExpression("&&", hasPropsObject, t.logicalExpression("||", t.binaryExpression("!==", propsAccess, t.identifier("undefined")), createHasOwnPropertyCall(propsObject, name)));
7893
+ const hasPropsValue = t.logicalExpression("&&", hasPropsObject, t.logicalExpression("||", t.binaryExpression("!==", propsAccess, t.identifier("undefined")), createHasOwnPropertyCall$1(propsObject, name)));
7820
7894
  return t.conditionalExpression(hasPropsValue, propsAccess, fallback);
7821
7895
  }
7822
7896
  function createIdentifierAccessWithPropsFallback(name, context, useRuntimePropHelper = false) {
@@ -7838,10 +7912,10 @@ function createIdentifierAccessWithPropsFallback(name, context, useRuntimePropHe
7838
7912
  const stateObject = createThisMemberAccess("$state");
7839
7913
  const hasPropsObject = t.binaryExpression("!=", propsObject, t.nullLiteral());
7840
7914
  const hasDefinedPropsValue = t.binaryExpression("!==", propsAccess, t.identifier("undefined"));
7841
- const hasPropsKey = createHasOwnPropertyCall(propsObject, name);
7915
+ const hasPropsKey = createHasOwnPropertyCall$1(propsObject, name);
7842
7916
  const hasUsablePropsValue = t.logicalExpression("&&", hasPropsObject, t.logicalExpression("||", hasDefinedPropsValue, hasPropsKey));
7843
7917
  const hasStateObject = t.binaryExpression("!=", stateObject, t.nullLiteral());
7844
- const hasStateKey = createHasOwnPropertyCall(stateObject, name);
7918
+ const hasStateKey = createHasOwnPropertyCall$1(stateObject, name);
7845
7919
  const shouldUseStateAccess = Boolean(context.propsDerivedKeys?.includes(name)) ? t.booleanLiteral(false) : t.logicalExpression("&&", hasStateObject, hasStateKey);
7846
7920
  return t.conditionalExpression(shouldUseStateAccess, thisAccess, t.conditionalExpression(hasUsablePropsValue, propsAccess, thisAccess));
7847
7921
  }
@@ -7905,6 +7979,9 @@ function normalizeJsExpressionWithContext(exp, context, options) {
7905
7979
  }
7906
7980
  }
7907
7981
  if (locals.has(name)) return;
7982
+ if (options?.preserveForItems && context.forStack.some((forInfo) => {
7983
+ return forInfo.item === name || forInfo.index === name || forInfo.key === name;
7984
+ })) return;
7908
7985
  let replacement;
7909
7986
  if (context.rewriteScopedSlot) {
7910
7987
  if (hasOwn(slotProps, name)) {
@@ -7927,6 +8004,7 @@ function normalizeJsExpressionWithContext(exp, context, options) {
7927
8004
  path.replaceWith(replacement);
7928
8005
  path.skip();
7929
8006
  } });
8007
+ rewriteForItemAccess(ast, context);
7930
8008
  if (options?.unrefMemberAccess) traverse(ast, { MemberExpression: { exit(path) {
7931
8009
  if (!shouldUnrefMemberAccess(path.node, path.parentPath?.node)) return;
7932
8010
  path.replaceWith(createUnrefCall(t.cloneNode(path.node, true)));
@@ -7944,7 +8022,7 @@ function buildForIndexAccess$1(context) {
7944
8022
  /**
7945
8023
  * 检测表达式是否包含小程序模板不稳定的调用语义。
7946
8024
  */
7947
- function shouldFallbackToRuntimeBinding(exp) {
8025
+ function shouldFallbackToRuntimeBinding(exp, templateSafeCallNames = /* @__PURE__ */ new Set()) {
7948
8026
  const trimmed = exp.trim();
7949
8027
  if (!trimmed) return false;
7950
8028
  const parsed = parseBabelExpressionFile(normalizeWxmlExpression(trimmed));
@@ -7952,6 +8030,7 @@ function shouldFallbackToRuntimeBinding(exp) {
7952
8030
  let shouldFallback = false;
7953
8031
  traverse(parsed.ast, {
7954
8032
  CallExpression(path) {
8033
+ if (path.node.callee.type === "Identifier" && templateSafeCallNames.has(path.node.callee.name)) return;
7955
8034
  shouldFallback = true;
7956
8035
  path.stop();
7957
8036
  },
@@ -7963,6 +8042,10 @@ function shouldFallbackToRuntimeBinding(exp) {
7963
8042
  if (path.node.operator !== "typeof") return;
7964
8043
  shouldFallback = true;
7965
8044
  path.stop();
8045
+ },
8046
+ BigIntLiteral(path) {
8047
+ shouldFallback = true;
8048
+ path.stop();
7966
8049
  }
7967
8050
  });
7968
8051
  return shouldFallback;
@@ -8140,10 +8223,161 @@ function renderStyleAttribute(staticStyle, dynamicStyleExp, vShowExp, context) {
8140
8223
  function transformAttribute(node, _context) {
8141
8224
  const { name, value } = node;
8142
8225
  if (!value) return name;
8143
- if (value.type === NodeTypes.TEXT) return `${name}="${value.content}"`;
8226
+ if (value.type === NodeTypes.TEXT) return `${name}="${escapeWxmlAttribute(value.content)}"`;
8144
8227
  return `${name}=""`;
8145
8228
  }
8146
8229
  //#endregion
8230
+ //#region src/plugins/vue/compiler/template/directives/forKey/projection.ts
8231
+ function createConsoleErrorGuard(message, errorId) {
8232
+ return t.ifStatement(t.logicalExpression("&&", t.binaryExpression("!==", t.unaryExpression("typeof", t.identifier("console")), t.stringLiteral("undefined")), t.binaryExpression("===", t.unaryExpression("typeof", t.memberExpression(t.identifier("console"), t.identifier("error"))), t.stringLiteral("function"))), t.blockStatement([t.expressionStatement(t.callExpression(t.memberExpression(t.identifier("console"), t.identifier("error")), [t.stringLiteral(message), t.cloneNode(errorId)]))]));
8233
+ }
8234
+ function createConsoleWarnGuard(message, item) {
8235
+ return t.ifStatement(t.logicalExpression("&&", t.binaryExpression("!==", t.unaryExpression("typeof", t.identifier("console")), t.stringLiteral("undefined")), t.binaryExpression("===", t.unaryExpression("typeof", t.memberExpression(t.identifier("console"), t.identifier("warn"))), t.stringLiteral("function"))), t.blockStatement([t.expressionStatement(t.callExpression(t.memberExpression(t.identifier("console"), t.identifier("warn")), [t.stringLiteral(message), t.cloneNode(item)]))]));
8236
+ }
8237
+ function createHasOwnPropertyCall(item, field) {
8238
+ return t.callExpression(t.memberExpression(t.memberExpression(t.memberExpression(t.identifier("Object"), t.identifier("prototype")), t.identifier("hasOwnProperty")), t.identifier("call")), [t.cloneNode(item), t.stringLiteral(field)]);
8239
+ }
8240
+ function createSafeKeyExpression(exp, rawExp, seed, item) {
8241
+ const errorId = t.identifier(`__wv_for_key_error_${seed}`);
8242
+ const shouldReportError = item ? t.binaryExpression("!=", t.cloneNode(item), t.nullLiteral()) : t.booleanLiteral(true);
8243
+ return t.callExpression(t.arrowFunctionExpression([], t.blockStatement([t.tryStatement(t.blockStatement([t.returnStatement(t.cloneNode(exp, true))]), t.catchClause(errorId, t.blockStatement([t.ifStatement(shouldReportError, t.blockStatement([createConsoleErrorGuard(`[wevu] v-for :key 表达式执行失败: ${rawExp}`, errorId)])), t.returnStatement(t.identifier("undefined"))])), null)])), []);
8244
+ }
8245
+ function createProjectedItemExpression(item, keyExp, rawKeyExp, keyField, valueField, seed) {
8246
+ const isObject = t.logicalExpression("&&", t.binaryExpression("!=", t.cloneNode(item), t.nullLiteral()), t.binaryExpression("===", t.unaryExpression("typeof", t.cloneNode(item)), t.stringLiteral("object")));
8247
+ const projected = t.callExpression(t.arrowFunctionExpression([], t.blockStatement([t.ifStatement(t.logicalExpression("||", createHasOwnPropertyCall(item, keyField), createHasOwnPropertyCall(item, valueField)), t.blockStatement([createConsoleWarnGuard(`[wevu] v-for :key 内部字段冲突,投影将使用保留字段 ${keyField} / ${valueField}`, item)])), t.returnStatement(t.callExpression(t.memberExpression(t.identifier("Object"), t.identifier("assign")), [
8248
+ t.objectExpression([]),
8249
+ t.cloneNode(item),
8250
+ t.objectExpression([t.objectProperty(t.stringLiteral(valueField), t.cloneNode(item)), t.objectProperty(t.stringLiteral(keyField), createSafeKeyExpression(keyExp, rawKeyExp, seed, item))])
8251
+ ]))])), []);
8252
+ const primitiveProjected = t.objectExpression([t.objectProperty(t.stringLiteral(valueField), t.cloneNode(item)), t.objectProperty(t.stringLiteral(keyField), createSafeKeyExpression(keyExp, rawKeyExp, seed, item))]);
8253
+ return t.conditionalExpression(isObject, projected, primitiveProjected);
8254
+ }
8255
+ function createArrayProjection(sourceId, keyExp, rawKeyExp, keyField, valueField, forInfo, seed) {
8256
+ const itemId = forInfo.item && t.isValidIdentifier(forInfo.item) ? t.identifier(forInfo.item) : t.identifier(`__wv_for_key_item_${seed}`);
8257
+ const indexId = forInfo.index && t.isValidIdentifier(forInfo.index) ? t.identifier(forInfo.index) : t.identifier(`__wv_for_key_index_${seed}`);
8258
+ const body = [];
8259
+ if (forInfo.key && t.isValidIdentifier(forInfo.key) && forInfo.key !== indexId.name) body.push(t.variableDeclaration("const", [t.variableDeclarator(t.identifier(forInfo.key), t.cloneNode(indexId))]));
8260
+ body.push(t.returnStatement(createProjectedItemExpression(itemId, keyExp, rawKeyExp, keyField, valueField, seed)));
8261
+ return t.callExpression(t.memberExpression(t.cloneNode(sourceId), t.identifier("map")), [t.arrowFunctionExpression([itemId, indexId], t.blockStatement(body))]);
8262
+ }
8263
+ function createObjectProjection(sourceId, keyExp, rawKeyExp, keyField, valueField, forInfo, seed) {
8264
+ const resultId = t.identifier(`__wv_for_key_result_${seed}`);
8265
+ const keysId = t.identifier(`__wv_for_key_keys_${seed}`);
8266
+ const loopIndexId = t.identifier(`__wv_for_key_loop_index_${seed}`);
8267
+ const sourceKeyId = t.identifier(`__wv_for_key_source_key_${seed}`);
8268
+ const sourceItemId = t.identifier(`__wv_for_key_source_item_${seed}`);
8269
+ const body = [t.variableDeclaration("const", [t.variableDeclarator(sourceKeyId, t.memberExpression(keysId, loopIndexId, true))]), t.variableDeclaration("const", [t.variableDeclarator(sourceItemId, t.memberExpression(sourceId, sourceKeyId, true))])];
8270
+ if (forInfo.item && t.isValidIdentifier(forInfo.item) && forInfo.item !== sourceItemId.name) body.push(t.variableDeclaration("const", [t.variableDeclarator(t.identifier(forInfo.item), t.cloneNode(sourceItemId))]));
8271
+ if (forInfo.key && t.isValidIdentifier(forInfo.key) && forInfo.key !== sourceKeyId.name) body.push(t.variableDeclaration("const", [t.variableDeclarator(t.identifier(forInfo.key), t.cloneNode(sourceKeyId))]));
8272
+ if (forInfo.index && t.isValidIdentifier(forInfo.index)) {
8273
+ const source = forInfo.key ? loopIndexId : sourceKeyId;
8274
+ if (forInfo.index !== source.name) body.push(t.variableDeclaration("const", [t.variableDeclarator(t.identifier(forInfo.index), t.cloneNode(source))]));
8275
+ }
8276
+ body.push(t.expressionStatement(t.assignmentExpression("=", t.memberExpression(resultId, sourceKeyId, true), createProjectedItemExpression(sourceItemId, keyExp, rawKeyExp, keyField, valueField, seed))));
8277
+ return t.callExpression(t.arrowFunctionExpression([], t.blockStatement([
8278
+ t.variableDeclaration("const", [t.variableDeclarator(resultId, t.objectExpression([]))]),
8279
+ t.variableDeclaration("const", [t.variableDeclarator(keysId, t.callExpression(t.memberExpression(t.identifier("Object"), t.identifier("keys")), [t.cloneNode(sourceId)]))]),
8280
+ t.forStatement(t.variableDeclaration("let", [t.variableDeclarator(loopIndexId, t.numericLiteral(0))]), t.binaryExpression("<", loopIndexId, t.memberExpression(keysId, t.identifier("length"))), t.updateExpression("++", loopIndexId), t.blockStatement(body)),
8281
+ t.returnStatement(resultId)
8282
+ ])), []);
8283
+ }
8284
+ function createForKeyProjectionExpression(sourceExp, keyExp, rawKeyExp, keyField, valueField, forInfo, seed) {
8285
+ const sourceId = t.identifier(`__wv_for_key_source_${seed}`);
8286
+ const objectCheck = t.logicalExpression("&&", t.binaryExpression("!=", t.cloneNode(sourceId), t.nullLiteral()), t.binaryExpression("===", t.unaryExpression("typeof", t.cloneNode(sourceId)), t.stringLiteral("object")));
8287
+ return t.callExpression(t.arrowFunctionExpression([], t.blockStatement([
8288
+ t.variableDeclaration("const", [t.variableDeclarator(sourceId, t.cloneNode(sourceExp, true))]),
8289
+ t.ifStatement(t.callExpression(t.memberExpression(t.identifier("Array"), t.identifier("isArray")), [t.cloneNode(sourceId)]), t.blockStatement([t.returnStatement(createArrayProjection(sourceId, keyExp, rawKeyExp, keyField, valueField, forInfo, seed))])),
8290
+ t.ifStatement(objectCheck, t.blockStatement([t.returnStatement(createObjectProjection(sourceId, keyExp, rawKeyExp, keyField, valueField, forInfo, seed))])),
8291
+ t.returnStatement(t.cloneNode(sourceId))
8292
+ ])), []);
8293
+ }
8294
+ //#endregion
8295
+ //#region src/plugins/vue/compiler/template/directives/forKey/index.ts
8296
+ const SIMPLE_IDENTIFIER_RE$1 = /^[A-Z_$][\w$]*$/i;
8297
+ const SIMPLE_MEMBER_PATH_RE = /^[A-Z_$][\w$]*(?:\.[A-Z_$][\w$]*)*$/i;
8298
+ const RUNTIME_BINDING_REF_RE = /^__wv_bind_\d+(?:\[[A-Z_$][\w$]*\])*$/i;
8299
+ function createSourceContext(context) {
8300
+ return {
8301
+ ...context,
8302
+ forStack: context.forStack.map((forInfo) => ({
8303
+ ...forInfo,
8304
+ itemAccess: void 0
8305
+ }))
8306
+ };
8307
+ }
8308
+ function hasKnownPrimitiveItems(exp) {
8309
+ if (t.isStringLiteral(exp) || t.isNumericLiteral(exp) || t.isBooleanLiteral(exp) || t.isNullLiteral(exp)) return true;
8310
+ if (!t.isArrayExpression(exp)) return false;
8311
+ return exp.elements.every((element) => {
8312
+ return element == null || t.isStringLiteral(element) || t.isNumericLiteral(element) || t.isBooleanLiteral(element) || t.isNullLiteral(element);
8313
+ });
8314
+ }
8315
+ function resolveItemAliasKeyField(trimmed, forInfo) {
8316
+ const aliasExp = forInfo.itemAliases?.[trimmed]?.trim();
8317
+ if (!aliasExp || !forInfo.item || !aliasExp.startsWith(`${forInfo.item}.`)) return null;
8318
+ const remainder = aliasExp.slice(forInfo.item.length + 1);
8319
+ return SIMPLE_MEMBER_PATH_RE.test(remainder) && !remainder.includes(".") ? remainder : null;
8320
+ }
8321
+ function resolveNativeForKeyValue(exp, forInfo, keyThisValue) {
8322
+ const trimmed = exp.trim();
8323
+ if (!forInfo) return null;
8324
+ if (forInfo.item && trimmed === forInfo.item || forInfo.key && trimmed === forInfo.key) return keyThisValue;
8325
+ if (forInfo.item && trimmed.startsWith(`${forInfo.item}.`)) {
8326
+ const remainder = trimmed.slice(forInfo.item.length + 1);
8327
+ if (SIMPLE_MEMBER_PATH_RE.test(remainder) && !remainder.includes(".")) return remainder;
8328
+ return null;
8329
+ }
8330
+ if (SIMPLE_IDENTIFIER_RE$1.test(trimmed)) {
8331
+ if (forInfo.index === trimmed) return trimmed;
8332
+ return resolveItemAliasKeyField(trimmed, forInfo);
8333
+ }
8334
+ return null;
8335
+ }
8336
+ function createForKeyProjection(node, forInfo, context) {
8337
+ const rawKeyExp = getBindDirectiveExpression(node).trim();
8338
+ if (!rawKeyExp || !forInfo.listExp || resolveNativeForKeyValue(rawKeyExp, forInfo, context.platform.keyThisValue)) return null;
8339
+ const listExp = forInfo.listExp?.trim() ?? "";
8340
+ const rawListExp = forInfo.rawListExp?.trim() || listExp;
8341
+ const projectionListExp = RUNTIME_BINDING_REF_RE.test(listExp) ? listExp : rawListExp;
8342
+ const sourceContext = createSourceContext(context);
8343
+ const projectionSourceAst = RUNTIME_BINDING_REF_RE.test(projectionListExp) ? normalizeJsExpressionWithContext(projectionListExp, sourceContext, {
8344
+ hint: "v-for :key 数据源",
8345
+ runtimePropAccess: "helper",
8346
+ unrefMemberAccess: true,
8347
+ preserveForItems: true
8348
+ }) : normalizeJsExpressionWithContext(projectionListExp, sourceContext, {
8349
+ hint: "v-for :key 数据源",
8350
+ preserveForItems: true
8351
+ });
8352
+ if (!projectionSourceAst) return null;
8353
+ if (hasKnownPrimitiveItems(projectionSourceAst)) return null;
8354
+ const keyExpAst = normalizeJsExpressionWithContext(rawKeyExp, sourceContext, {
8355
+ hint: "v-for :key",
8356
+ runtimePropAccess: "helper",
8357
+ unrefMemberAccess: true,
8358
+ preserveForItems: true
8359
+ });
8360
+ if (!keyExpAst) return null;
8361
+ const bindingSeed = context.classStyleBindings.filter((binding) => binding.type === "bind").length;
8362
+ const bindingName = `__wv_bind_${bindingSeed}`;
8363
+ const keyField = `__wv_key_${bindingSeed}`;
8364
+ const valueField = `__wv_value_${bindingSeed}`;
8365
+ const outerForStack = context.forStack.slice(0, -1).map((info) => ({ ...info }));
8366
+ context.classStyleBindings.push({
8367
+ name: bindingName,
8368
+ type: "bind",
8369
+ exp: `v-for :key ${rawKeyExp}`,
8370
+ expAst: createForKeyProjectionExpression(projectionSourceAst, keyExpAst, rawKeyExp, keyField, valueField, forInfo, bindingSeed),
8371
+ forStack: outerForStack
8372
+ });
8373
+ const indexAccess = outerForStack.map((info) => `[${info.index ?? "index"}]`).join("");
8374
+ return {
8375
+ keyAttr: context.platform.keyAttr(keyField),
8376
+ listExp: `${bindingName}${indexAccess}`,
8377
+ itemAccess: `${forInfo.item}.${valueField}`
8378
+ };
8379
+ }
8380
+ //#endregion
8147
8381
  //#region src/plugins/vue/compiler/template/directives/bind.ts
8148
8382
  function unwrapTsExpression(node) {
8149
8383
  if (node.type === "TSAsExpression" || node.type === "TSNonNullExpression" || node.type === "TSTypeAssertion") return unwrapTsExpression(node.expression);
@@ -8190,10 +8424,6 @@ function createInlineObjectLiteralAttr(argValue, rawExpValue, context) {
8190
8424
  if (context.mustacheInterpolation === "spaced") return `${argValue}="${renderMustache(expValue, context)}"`;
8191
8425
  return `${argValue}="{{ ${expValue} }}"`;
8192
8426
  }
8193
- const SIMPLE_IDENTIFIER_RE$1 = /^[A-Z_$][\w$]*$/i;
8194
- const SIMPLE_MEMBER_PATH_RE = /^[A-Z_$][\w$]*(?:\.[A-Z_$][\w$]*)*$/i;
8195
- const isSimpleIdentifier = (value) => SIMPLE_IDENTIFIER_RE$1.test(value);
8196
- const isSimpleMemberPath = (value) => SIMPLE_MEMBER_PATH_RE.test(value);
8197
8427
  const COMPONENT_NON_PROP_BINDINGS = /* @__PURE__ */ new Set([
8198
8428
  "class",
8199
8429
  "style",
@@ -8265,24 +8495,10 @@ function transformBindDirective(node, context, forInfo, options) {
8265
8495
  if (argValue === "key") {
8266
8496
  const expValue = normalizeWxmlExpressionWithContext(rawExpValue, context);
8267
8497
  const trimmed = expValue.trim();
8268
- const warnKeyFallback = (reason) => {
8269
- if (!forInfo) return;
8270
- context.warnings.push(`v-for :key "${trimmed}" ${reason},已降级为 ${context.platform.keyAttr(context.platform.keyThisValue)}。建议使用稳定的基础类型 key(例如 item.id)。`);
8271
- };
8272
- if (forInfo?.item && trimmed === forInfo.item) return context.platform.keyAttr(context.platform.keyThisValue);
8273
- if (forInfo?.key && trimmed === forInfo.key) return context.platform.keyAttr(context.platform.keyThisValue);
8274
- if (forInfo?.item && trimmed.startsWith(`${forInfo.item}.`)) {
8275
- const remainder = trimmed.slice(forInfo.item.length + 1);
8276
- if (isSimpleMemberPath(remainder)) {
8277
- const firstSegment = remainder.split(".")[0] || remainder;
8278
- return context.platform.keyAttr(firstSegment);
8279
- }
8280
- warnKeyFallback("不是简单的成员路径");
8281
- return context.platform.keyAttr(context.platform.keyThisValue);
8282
- }
8283
- if (isSimpleIdentifier(trimmed)) return context.platform.keyAttr(trimmed);
8498
+ const nativeKeyValue = resolveNativeForKeyValue(trimmed, forInfo, context.platform.keyThisValue);
8499
+ if (nativeKeyValue) return context.platform.keyAttr(nativeKeyValue);
8284
8500
  if (forInfo) {
8285
- warnKeyFallback("是复杂表达式");
8501
+ context.warnings.push(`v-for :key "${trimmed}" 无法生成运行时 key 投影,已降级为 ${context.platform.keyAttr(context.platform.keyThisValue)}。建议使用稳定的基础类型 key。`);
8286
8502
  return context.platform.keyAttr(context.platform.keyThisValue);
8287
8503
  }
8288
8504
  return context.platform.keyAttr(expValue);
@@ -8291,7 +8507,7 @@ function transformBindDirective(node, context, forInfo, options) {
8291
8507
  if (context.objectLiteralBindMode === "inline" || isStaticObjectLiteral(rawExpValue)) return createInlineObjectLiteralAttr(argValue, rawExpValue, context);
8292
8508
  return createBindRuntimeAttr(argValue, rawExpValue, context);
8293
8509
  }
8294
- if (shouldFallbackToRuntimeBinding(rawExpValue)) {
8510
+ if (shouldFallbackToRuntimeBinding(rawExpValue, context.templateSafeCallNames)) {
8295
8511
  const runtimeAttr = createBindRuntimeAttr(argValue, rawExpValue, context);
8296
8512
  if (runtimeAttr) return runtimeAttr;
8297
8513
  }
@@ -8335,7 +8551,6 @@ function getElementType(element) {
8335
8551
  }
8336
8552
  return "";
8337
8553
  }
8338
- const QUOTE_RE$1 = /"/g;
8339
8554
  const CAMELIZE_RE = /-([a-z0-9])/gi;
8340
8555
  const IDENTIFIER_RE = /^[A-Z_$][\w$]*$/i;
8341
8556
  const NATIVE_MODEL_TAGS = /* @__PURE__ */ new Set([
@@ -8359,7 +8574,7 @@ function isNativeModelElement(element) {
8359
8574
  return NATIVE_MODEL_TAGS.has(element.tag);
8360
8575
  }
8361
8576
  function transformVModel(element, expValue, context) {
8362
- const escapedModel = expValue.replace(QUOTE_RE$1, "&quot;");
8577
+ const escapedModel = escapeWxmlAttribute(expValue);
8363
8578
  const bindModel = (event) => {
8364
8579
  return `${context.platform.eventBindingAttr(event)}="${WEVU_MODEL_HANDLER}" data-wv-model="${escapedModel}"`;
8365
8580
  };
@@ -8437,15 +8652,14 @@ function isScriptSetupHandlerBinding(value, context) {
8437
8652
  function shouldUseDetailPayload(options) {
8438
8653
  return options?.isComponent === true;
8439
8654
  }
8440
- const QUOTE_RE = /"/g;
8441
8655
  function buildInlineScopeAttrs(scopeBindings, context) {
8442
8656
  return scopeBindings.map((binding, index) => {
8443
- return `data-wv-s${index}="${renderMustache(binding.replace(QUOTE_RE, "&quot;"), context)}"`;
8657
+ return `data-wv-s${index}="${renderMustache(escapeWxmlAttribute(binding), context)}"`;
8444
8658
  });
8445
8659
  }
8446
8660
  function buildInlineIndexAttrs(indexBindings, context) {
8447
8661
  return indexBindings.map((binding, index) => {
8448
- return `data-wv-i${index}="${renderMustache(binding.replace(QUOTE_RE, "&quot;"), context)}"`;
8662
+ return `data-wv-i${index}="${renderMustache(escapeWxmlAttribute(binding), context)}"`;
8449
8663
  });
8450
8664
  }
8451
8665
  function resolveEventPrefix(modifiers) {
@@ -8510,7 +8724,7 @@ function transformOnDirective(node, context, options) {
8510
8724
  }
8511
8725
  if (isInlineExpression) return [
8512
8726
  detailAttr,
8513
- `data-wv-inline-${eventSuffix}="${inlineSource.replace(QUOTE_RE, "&quot;")}"`,
8727
+ `data-wv-inline-${eventSuffix}="${escapeWxmlAttribute(inlineSource)}"`,
8514
8728
  `${bindAttr}="${WEVU_INLINE_HANDLER}"`
8515
8729
  ].filter(Boolean).join(" ");
8516
8730
  return [detailAttr, `${bindAttr}="${expValue}"`].filter(Boolean).join(" ");
@@ -8557,6 +8771,7 @@ function collectElementAttributes(node, context, options) {
8557
8771
  const resolvedTag = options?.resolvedTag ?? resolveTemplateTagName(node.tag, context);
8558
8772
  const isComponentElement = options?.isComponent ?? !isBuiltinTag(resolvedTag);
8559
8773
  const attrs = options?.extraAttrs ? [...options.extraAttrs] : [];
8774
+ if (context.scopeId) attrs.push(`${context.scopeId}=""`);
8560
8775
  const mappedTagClass = resolveMappedHtmlTagClassName(node.tag, context, resolvedTag);
8561
8776
  let staticClass;
8562
8777
  let staticId;
@@ -8636,7 +8851,7 @@ function collectElementAttributes(node, context, options) {
8636
8851
  }
8637
8852
  if (prop.name === "text" && prop.exp?.type === NodeTypes.SIMPLE_EXPRESSION) {
8638
8853
  const rawExp = prop.exp.content;
8639
- vTextExp = (shouldFallbackToRuntimeBinding(rawExp) ? registerRuntimeBindingExpression(rawExp, context, { hint: "v-text" }) : null) ?? normalizeWxmlExpressionWithContext(rawExp, context);
8854
+ vTextExp = (shouldFallbackToRuntimeBinding(rawExp, context.templateSafeCallNames) ? registerRuntimeBindingExpression(rawExp, context, { hint: "v-text" }) : null) ?? normalizeWxmlExpressionWithContext(rawExp, context);
8640
8855
  continue;
8641
8856
  }
8642
8857
  const dir = transformDirective(prop, context, node, options?.forInfo, { isComponent: isComponentElement });
@@ -8680,7 +8895,7 @@ function collectElementAttributes(node, context, options) {
8680
8895
  if (staticId) attrs.unshift(`id="${staticId}"`);
8681
8896
  const classAttr = renderClassAttribute(staticClass, dynamicClassExp, context);
8682
8897
  if (classAttr) attrs.unshift(classAttr);
8683
- const styleAttr = renderStyleAttribute(staticStyle, dynamicStyleExp, vShowExp, context);
8898
+ const styleAttr = renderStyleAttribute(staticStyle, context.cssVars ? dynamicStyleExp ? `[${dynamicStyleExp}, ${WEVU_CSS_VARS_STYLE_KEY}]` : WEVU_CSS_VARS_STYLE_KEY : dynamicStyleExp, vShowExp, context);
8684
8899
  if (styleAttr) attrs.unshift(styleAttr);
8685
8900
  return {
8686
8901
  attrs,
@@ -9039,6 +9254,7 @@ function renderPlainSlotOutlet(node, context, transformNode) {
9039
9254
  if (hasScopeBindings) context.warnings.push("已禁用作用域插槽参数,插槽绑定将被忽略。");
9040
9255
  const fallbackContent = node.children.map((child) => transformNode(child, context)).join("");
9041
9256
  const slotAttrs = [];
9257
+ if (context.slottedScopeId) slotAttrs.push(`${context.slottedScopeId}=""`);
9042
9258
  const nameAttr = renderSlotNameAttribute(slotNameInfo, context, "name");
9043
9259
  if (nameAttr) slotAttrs.push(nameAttr);
9044
9260
  const slotAttrString = slotAttrs.length ? ` ${slotAttrs.join(" ")}` : "";
@@ -9103,6 +9319,7 @@ function transformSlotElement(node, context, transformNode) {
9103
9319
  let fallbackContent = "";
9104
9320
  if (node.children.length > 0) fallbackContent = node.children.map((child) => transformNode(child, context)).join("");
9105
9321
  const slotAttrs = [];
9322
+ if (context.slottedScopeId) slotAttrs.push(`${context.slottedScopeId}=""`);
9106
9323
  const nameAttr = renderSlotNameAttribute(slotNameInfo, context, "name");
9107
9324
  if (nameAttr) slotAttrs.push(nameAttr);
9108
9325
  const slotAttrString = slotAttrs.length ? ` ${slotAttrs.join(" ")}` : "";
@@ -9122,6 +9339,7 @@ function transformSlotElement(node, context, transformNode) {
9122
9339
  `${WEVU_SLOT_OWNER_ID_ATTR}="${renderMustache(WEVU_SLOT_OWNER_ID_PROP, context)}"`,
9123
9340
  `${WEVU_SLOT_PROPS_ATTR}="${renderMustache(slotPropsExp, context)}"`
9124
9341
  ];
9342
+ if (context.slottedScopeId) scopedAttrs.push(`${context.slottedScopeId}=""`);
9125
9343
  if (context.slotMultipleInstance) scopedAttrs.push(`${WEVU_SLOT_SCOPE_ATTR}="${renderMustache(WEVU_SLOT_SCOPE_KEY, context)}"`);
9126
9344
  const scopedTag = `<${genericKey}${scopedAttrs.length ? ` ${scopedAttrs.join(" ")}` : ""} />`;
9127
9345
  const nativeFallbackTag = context.forStack.length > 0 ? "" : context.platform.wrapIf(`!${WEVU_SLOT_OWNER_ID_PROP}`, slotTag, (exp) => renderMustache(exp, context));
@@ -9598,10 +9816,26 @@ function transformNormalElement(node, context, transformNode) {
9598
9816
  //#region src/plugins/vue/compiler/template/elements/tag-structural.ts
9599
9817
  const REGEX_SPECIAL_CHARS_RE = /[.*+?^${}()|[\]\\]/g;
9600
9818
  function resolveConditionExpression$1(rawExpValue, context, hint) {
9601
- return (context.rewriteScopedSlot || shouldFallbackToRuntimeBinding(rawExpValue) ? registerRuntimeBindingExpression(rawExpValue, context, { hint }) : null) ?? normalizeWxmlExpressionWithContext(rawExpValue, context);
9819
+ return (context.rewriteScopedSlot || shouldFallbackToRuntimeBinding(rawExpValue, context.templateSafeCallNames) ? registerRuntimeBindingExpression(rawExpValue, context, { hint }) : null) ?? normalizeWxmlExpressionWithContext(rawExpValue, context);
9602
9820
  }
9603
9821
  function resolveListExpression(rawExpValue, context, hint) {
9604
- return (context.rewriteScopedSlot || shouldFallbackToRuntimeBinding(rawExpValue) ? registerRuntimeBindingExpression(rawExpValue, context, { hint }) : null) ?? normalizeWxmlExpressionWithContext(rawExpValue, context);
9822
+ return (context.rewriteScopedSlot || shouldFallbackToRuntimeBinding(rawExpValue, context.templateSafeCallNames) ? registerRuntimeBindingExpression(rawExpValue, context, { hint }) : null) ?? normalizeWxmlExpressionWithContext(rawExpValue, context);
9823
+ }
9824
+ function requiresRuntimeForKeyProjection(node, context) {
9825
+ const forDirective = node.props.find((prop) => {
9826
+ return prop.type === NodeTypes.DIRECTIVE && prop.name === "for";
9827
+ });
9828
+ const keyDirective = node.props.find((prop) => {
9829
+ return prop.type === NodeTypes.DIRECTIVE && prop.name === "bind" && prop.arg?.type === NodeTypes.SIMPLE_EXPRESSION && prop.arg.content === "key";
9830
+ });
9831
+ if (forDirective?.exp?.type === NodeTypes.SIMPLE_EXPRESSION && keyDirective) {
9832
+ const forInfo = parseForExpression(forDirective.exp.content);
9833
+ const rawKeyExp = getBindDirectiveExpression(keyDirective).trim();
9834
+ if (rawKeyExp && !resolveNativeForKeyValue(rawKeyExp, forInfo, context.platform.keyThisValue)) return true;
9835
+ }
9836
+ return node.children.some((child) => {
9837
+ return child.type === NodeTypes.ELEMENT && requiresRuntimeForKeyProjection(child, context);
9838
+ });
9605
9839
  }
9606
9840
  function transformIfElement(node, context, transformNode) {
9607
9841
  const renderTemplateMustache = (exp) => renderMustache(exp, context);
@@ -9643,15 +9877,18 @@ function transformForElement(node, context, transformNode) {
9643
9877
  }));
9644
9878
  }
9645
9879
  }
9646
- if (context.classStyleRuntime === "js" && !forInfo.index) forInfo.index = `__wv_index_${context.forIndexSeed++}`;
9880
+ if ((context.classStyleRuntime === "js" || requiresRuntimeForKeyProjection(node, context)) && !forInfo.index) forInfo.index = `__wv_index_${context.forIndexSeed++}`;
9881
+ const rawListExp = forInfo.listExp?.trim();
9647
9882
  const listExp = forInfo.listExp ? resolveListExpression(forInfo.listExp, context, "v-for 列表") : void 0;
9648
9883
  const listExpAst = forInfo.listExp ? normalizeJsExpressionWithContext(forInfo.listExp, context, { hint: "v-for 列表" }) : void 0;
9649
9884
  const scopedForInfo = listExp ? {
9650
9885
  ...forInfo,
9651
9886
  listExp,
9887
+ rawListExp,
9652
9888
  listExpAst: listExpAst ?? void 0
9653
9889
  } : {
9654
9890
  ...forInfo,
9891
+ rawListExp,
9655
9892
  listExpAst: listExpAst ?? void 0
9656
9893
  };
9657
9894
  const scopeNames = [
@@ -9666,34 +9903,64 @@ function transformForElement(node, context, transformNode) {
9666
9903
  ...node,
9667
9904
  props: otherProps
9668
9905
  };
9669
- const extraAttrs = listExp ? context.platform.forAttrs(listExp, renderTemplateMustache, forInfo.item, forInfo.index) : [];
9670
- if (elementWithoutFor.tag === "slot") {
9671
- const keyDirective = elementWithoutFor.props.find((prop) => {
9672
- return prop.type === NodeTypes.DIRECTIVE && prop.name === "bind" && prop.arg?.type === NodeTypes.SIMPLE_EXPRESSION && prop.arg.content === "key";
9906
+ const keyDirective = otherProps.find((prop) => {
9907
+ return prop.type === NodeTypes.DIRECTIVE && prop.name === "bind" && prop.arg?.type === NodeTypes.SIMPLE_EXPRESSION && prop.arg.content === "key";
9908
+ });
9909
+ const keyProjection = keyDirective ? createForKeyProjection(keyDirective, scopedForInfo, context) : null;
9910
+ if (keyProjection) {
9911
+ scopedForInfo.itemAccess = keyProjection.itemAccess;
9912
+ const projectionContext = {
9913
+ ...context,
9914
+ forStack: context.forStack.map((forInfo) => ({
9915
+ ...forInfo,
9916
+ itemAccess: void 0
9917
+ }))
9918
+ };
9919
+ const projectedListExpAst = normalizeJsExpressionWithContext(keyProjection.listExp, projectionContext, {
9920
+ hint: "v-for 投影列表",
9921
+ runtimePropAccess: "helper",
9922
+ unrefMemberAccess: true,
9923
+ preserveForItems: true
9673
9924
  });
9925
+ scopedForInfo.projectedListExp = keyProjection.listExp;
9926
+ scopedForInfo.projectedListExpAst = projectedListExpAst ?? scopedForInfo.projectedListExpAst;
9927
+ const currentForInfo = context.forStack[context.forStack.length - 1];
9928
+ if (currentForInfo) {
9929
+ currentForInfo.itemAccess = keyProjection.itemAccess;
9930
+ currentForInfo.projectedListExp = scopedForInfo.projectedListExp;
9931
+ currentForInfo.projectedListExpAst = scopedForInfo.projectedListExpAst;
9932
+ }
9933
+ }
9934
+ const renderElement = keyProjection ? {
9935
+ ...elementWithoutFor,
9936
+ props: otherProps.filter((prop) => prop !== keyDirective)
9937
+ } : elementWithoutFor;
9938
+ const templateListExp = keyProjection?.listExp ?? listExp;
9939
+ const extraAttrs = templateListExp ? context.platform.forAttrs(templateListExp, renderTemplateMustache, forInfo.item, forInfo.index) : [];
9940
+ if (keyProjection) extraAttrs.push(keyProjection.keyAttr);
9941
+ if (renderElement.tag === "slot") {
9942
+ const slotKeyDirective = keyProjection ? void 0 : keyDirective;
9674
9943
  const content = transformSlotElement({
9675
- ...elementWithoutFor,
9676
- props: elementWithoutFor.props.filter((prop) => {
9677
- return prop !== keyDirective;
9678
- })
9944
+ ...renderElement,
9945
+ props: renderElement.props.filter((prop) => prop !== slotKeyDirective)
9679
9946
  }, context, transformNode);
9680
- const keyAttr = keyDirective ? transformBindDirective(keyDirective, context, forInfo) : null;
9947
+ const keyAttr = slotKeyDirective ? transformBindDirective(slotKeyDirective, context, scopedForInfo) : null;
9681
9948
  if (keyAttr) extraAttrs.push(keyAttr);
9682
9949
  const attrString = extraAttrs.length ? ` ${extraAttrs.join(" ")}` : "";
9683
9950
  return attrString ? `<block${attrString}>${content}</block>` : content;
9684
9951
  }
9685
- const resolvedTag = resolveTemplateTagName(elementWithoutFor.tag, context);
9686
- if (shouldTransformAsComponentWithSlots(elementWithoutFor, context, resolvedTag)) return transformComponentWithSlots(elementWithoutFor, context, transformNode, {
9952
+ const resolvedTag = resolveTemplateTagName(renderElement.tag, context);
9953
+ if (shouldTransformAsComponentWithSlots(renderElement, context, resolvedTag)) return transformComponentWithSlots(renderElement, context, transformNode, {
9687
9954
  extraAttrs,
9688
- forInfo
9955
+ forInfo: scopedForInfo
9689
9956
  });
9690
- const { attrs, vTextExp } = collectElementAttributes(elementWithoutFor, context, {
9691
- forInfo,
9957
+ const { attrs, vTextExp } = collectElementAttributes(renderElement, context, {
9958
+ forInfo: scopedForInfo,
9692
9959
  extraAttrs,
9693
9960
  resolvedTag
9694
9961
  });
9695
9962
  let children = "";
9696
- if (elementWithoutFor.children.length > 0) children = elementWithoutFor.children.map((child) => transformNode(child, context)).join("");
9963
+ if (renderElement.children.length > 0) children = renderElement.children.map((child) => transformNode(child, context)).join("");
9697
9964
  if (vTextExp !== void 0) children = renderMustache(vTextExp, context);
9698
9965
  const tag = resolvedTag;
9699
9966
  const attrString = attrs.length ? ` ${attrs.join(" ")}` : "";
@@ -9705,7 +9972,7 @@ function transformForElement(node, context, transformNode) {
9705
9972
  const TEMPLATE_OPEN_RE = /<template/g;
9706
9973
  const TEMPLATE_CLOSE_RE = /<\/template>/g;
9707
9974
  function resolveConditionExpression(rawExpValue, context, hint) {
9708
- return (context.rewriteScopedSlot || shouldFallbackToRuntimeBinding(rawExpValue) ? registerRuntimeBindingExpression(rawExpValue, context, { hint }) : null) ?? normalizeWxmlExpressionWithContext(rawExpValue, context);
9975
+ return (context.rewriteScopedSlot || shouldFallbackToRuntimeBinding(rawExpValue, context.templateSafeCallNames) ? registerRuntimeBindingExpression(rawExpValue, context, { hint }) : null) ?? normalizeWxmlExpressionWithContext(rawExpValue, context);
9709
9976
  }
9710
9977
  function transformTransitionElement(node, context, transformNode) {
9711
9978
  context.warnings.push("<transition> 组件:过渡效果需要动画库或运行时支持,仅渲染子节点。");
@@ -9792,13 +10059,6 @@ function transformElement(node, context, transformNode) {
9792
10059
  }
9793
10060
  //#endregion
9794
10061
  //#region src/plugins/vue/compiler/template/nodes.ts
9795
- const AMP_RE = /&/g;
9796
- const LT_RE = /</g;
9797
- const GT_RE = />/g;
9798
- function escapeWxmlText(value) {
9799
- if (!value) return "";
9800
- return value.replace(AMP_RE, "&amp;").replace(LT_RE, "&lt;").replace(GT_RE, "&gt;");
9801
- }
9802
10062
  function transformText(node, _context) {
9803
10063
  return escapeWxmlText(node.content);
9804
10064
  }
@@ -9806,7 +10066,7 @@ function transformInterpolation(node, context) {
9806
10066
  const { content } = node;
9807
10067
  if (content.type === NodeTypes.SIMPLE_EXPRESSION) {
9808
10068
  const rawExpValue = content.content;
9809
- return renderMustache((shouldFallbackToRuntimeBinding(rawExpValue) ? registerRuntimeBindingExpression(rawExpValue, context, { hint: "插值表达式" }) : null) ?? normalizeWxmlExpressionWithContext(rawExpValue, context), context);
10069
+ return renderMustache((shouldFallbackToRuntimeBinding(rawExpValue, context.templateSafeCallNames) ? registerRuntimeBindingExpression(rawExpValue, context, { hint: "插值表达式" }) : null) ?? normalizeWxmlExpressionWithContext(rawExpValue, context), context);
9810
10070
  }
9811
10071
  /* istanbul ignore next */
9812
10072
  return renderMustache("", context);
@@ -9929,8 +10189,12 @@ function compileVueTemplateToWxml(template, filename, options) {
9929
10189
  inlineExpressionSeed: 0,
9930
10190
  functionPropPaths: /* @__PURE__ */ new Set(),
9931
10191
  functionPropNames: Array.from(options?.functionPropNames ?? []),
10192
+ templateSafeCallNames: new Set(options?.templateSafeCallNames ?? []),
9932
10193
  wevuComponentTags: options?.wevuComponentTags ? new Set(options.wevuComponentTags) : void 0,
9933
- miniProgramComponentTags: options?.miniProgramComponentTags ? new Set(options.miniProgramComponentTags) : void 0
10194
+ miniProgramComponentTags: options?.miniProgramComponentTags ? new Set(options.miniProgramComponentTags) : void 0,
10195
+ scopeId: options?.scopeId,
10196
+ slottedScopeId: options?.slottedScopeId,
10197
+ cssVars: options?.cssVars
9934
10198
  };
9935
10199
  let wxml = ast.children.map((child) => transformNode(child, context)).join("");
9936
10200
  if (context.classStyleWxs) wxml = `${buildClassStyleWxsTag(context.classStyleWxsExtension || "wxs", context.classStyleWxsSrc)}\n${wxml}`;
@@ -9961,6 +10225,25 @@ function compileVueTemplateToWxml(template, filename, options) {
9961
10225
  }
9962
10226
  }
9963
10227
  //#endregion
10228
+ //#region src/plugins/vue/transform/scopedId.ts
10229
+ const SOURCE_ROOT_RE = /(?:^|\/)src\/(.+)$/;
10230
+ function normalizeScopedIdInput(filename) {
10231
+ const normalized = filename.replace(/\\/g, "/");
10232
+ return normalized.match(SOURCE_ROOT_RE)?.[1] ?? normalized.replace(/^.*?\/(pages|components|layouts)\//, "$1/");
10233
+ }
10234
+ /**
10235
+ * 根据项目内相对路径生成跨机器稳定的 scoped ID。
10236
+ */
10237
+ function generateScopedId(filename) {
10238
+ const input = normalizeScopedIdInput(filename);
10239
+ let hash = 2166136261;
10240
+ for (let index = 0; index < input.length; index += 1) {
10241
+ hash ^= input.charCodeAt(index);
10242
+ hash = Math.imul(hash, 16777619);
10243
+ }
10244
+ return (hash >>> 0).toString(36);
10245
+ }
10246
+ //#endregion
9964
10247
  //#region src/ast/native.ts
9965
10248
  const require = createRequire(import.meta.url);
9966
10249
  let binding;
@@ -10568,6 +10851,10 @@ const OBJECT_TO_STRING = Object.prototype.toString;
10568
10851
  function isIdentifierLikeKey(key) {
10569
10852
  return IDENTIFIER_LIKE_KEY_RE.test(key);
10570
10853
  }
10854
+ function resolveRuntimeMarkerIdentifier(value, scopeValues) {
10855
+ if (value[WEAPP_I18N_RUNTIME_MARKER] !== true) return;
10856
+ return Object.entries(scopeValues).find(([name, scopeValue]) => isIdentifierLikeKey(name) && scopeValue === value)?.[0];
10857
+ }
10571
10858
  function getObjectTag(value) {
10572
10859
  return OBJECT_TO_STRING.call(value);
10573
10860
  }
@@ -10665,6 +10952,8 @@ function serializeStaticValueToExpression(value, seen = /* @__PURE__ */ new Weak
10665
10952
  if (getObjectTag(value) === "[object RegExp]") return value.toString();
10666
10953
  if (Array.isArray(value)) return `[${value.map((item) => serializeStaticValueToExpression(item, seen, scopeValues)).join(", ")}]`;
10667
10954
  if (value && typeof value === "object") {
10955
+ const runtimeIdentifier = resolveRuntimeMarkerIdentifier(value, scopeValues);
10956
+ if (runtimeIdentifier) return runtimeIdentifier;
10668
10957
  if (seen.has(value)) throw new Error("defineOptions 的参数中不支持循环引用。");
10669
10958
  seen.add(value);
10670
10959
  const proto = Object.getPrototypeOf(value);
@@ -11311,7 +11600,7 @@ async function compileScriptPhase(descriptor, descriptorForCompile, filename, op
11311
11600
  let propsDerivedKeys;
11312
11601
  if (descriptor.script || descriptor.scriptSetup) {
11313
11602
  const scriptCompiled = precompiledScript ?? compileScript(descriptorForCompile, {
11314
- id: filename,
11603
+ id: generateScopedId(filename),
11315
11604
  isProd: false
11316
11605
  });
11317
11606
  warnReservedScriptSetupProps(descriptorForCompile.scriptSetup?.content, options?.warn, {
@@ -11356,6 +11645,7 @@ async function compileScriptPhase(descriptor, descriptorForCompile, filename, op
11356
11645
  functionPropPaths: templateCompiled?.functionPropPaths,
11357
11646
  propsAliases,
11358
11647
  propsDerivedKeys,
11648
+ cssModules: precomputedScriptPhaseInfo?.cssModules,
11359
11649
  relaxStructuredTypeOnlyProps,
11360
11650
  scopedSlotHostProperties: Boolean(templateCompiled?.componentGenerics && Object.keys(templateCompiled.componentGenerics).length > 0)
11361
11651
  });
@@ -11376,42 +11666,29 @@ async function compileScriptPhase(descriptor, descriptorForCompile, filename, op
11376
11666
  };
11377
11667
  }
11378
11668
  //#endregion
11379
- //#region src/plugins/vue/transform/scopedId.ts
11380
- /**
11381
- * 生成 scoped ID
11382
- */
11383
- function generateScopedId(filename) {
11384
- const hash = filename.split("").reduce((acc, char) => {
11385
- return (acc << 5) - acc + char.charCodeAt(0);
11386
- }, 0);
11387
- return Math.abs(hash).toString(36);
11388
- }
11389
- //#endregion
11390
11669
  //#region src/plugins/vue/transform/compileVueFile/style.ts
11391
- function compileStylePhase(descriptor, filename, result, options) {
11392
- if (descriptor.styles.length === 0) return;
11670
+ async function compileStylePhase(descriptor, filename, result, options) {
11671
+ if (descriptor.styles.length === 0) return { usesSlotted: false };
11393
11672
  const scopedId = generateScopedId(filename);
11394
- const compiledStyles = descriptor.styles.map((styleBlock) => {
11395
- return compileVueStyleToWxss(styleBlock, {
11673
+ const compiledStyles = await Promise.all(descriptor.styles.map(async (styleBlock) => {
11674
+ return await compileVueStyleToWxss(styleBlock, {
11396
11675
  id: scopedId,
11676
+ filename,
11397
11677
  scoped: styleBlock.scoped,
11398
11678
  modules: styleBlock.module,
11679
+ preprocessOptions: options?.preprocessOptions?.[styleBlock.lang || "css"],
11399
11680
  preserveDeepSelectors: options?.preserveDeepSelectors,
11400
11681
  transformScoped: options?.transformScoped
11401
11682
  });
11402
- });
11683
+ }));
11403
11684
  result.style = compiledStyles.map((s) => s.code.trim()).filter(Boolean).join("\n\n");
11404
- if (!compiledStyles.some((s) => s.modules)) return;
11685
+ if (!compiledStyles.some((s) => s.modules)) return { usesSlotted: compiledStyles.some((style) => style.usesSlotted) };
11405
11686
  const modulesMap = {};
11406
11687
  compiledStyles.forEach((compiled) => {
11407
11688
  if (compiled.modules) Object.assign(modulesMap, compiled.modules);
11408
11689
  });
11409
11690
  result.cssModules = modulesMap;
11410
- if (result.script !== void 0) result.script = `
11411
- // 模块化样式(CSS Modules)
11412
- const __cssModules = ${JSON.stringify(modulesMap, null, 2)}
11413
- ${result.script}
11414
- `;
11691
+ return { usesSlotted: compiledStyles.some((style) => style.usesSlotted) };
11415
11692
  }
11416
11693
  //#endregion
11417
11694
  //#region src/plugins/vue/transform/compileVueFile/template.ts
@@ -11471,6 +11748,7 @@ async function refreshVueFileJsonConfig(source, filename, cachedResult, options)
11471
11748
  */
11472
11749
  async function compileVueFile(source, filename, options) {
11473
11750
  const parsed = await parseVueFile(source, filename, options);
11751
+ const sfcId = generateScopedId(filename);
11474
11752
  const result = { meta: {
11475
11753
  ...parsed.meta,
11476
11754
  styleBlocks: parsed.descriptor.styles
@@ -11486,24 +11764,32 @@ async function compileVueFile(source, filename, options) {
11486
11764
  autoImportTags
11487
11765
  });
11488
11766
  const scriptCompiled = parsed.descriptor.script || parsed.descriptor.scriptSetup ? compileScript(parsed.descriptorForCompile, {
11489
- id: filename,
11767
+ id: sfcId,
11490
11768
  isProd: false
11491
11769
  }) : void 0;
11492
11770
  const propsAliases = scriptCompiled ? resolveScriptSetupPropsAliases(scriptCompiled.bindings) : void 0;
11493
11771
  const propsDerivedKeys = scriptCompiled ? resolveEffectivePropsDerivedKeys(scriptCompiled.bindings, scriptCompiled.content) : void 0;
11772
+ const styleCompiled = await compileStylePhase(parsed.descriptor, filename, result, options?.style);
11773
+ const scopedId = parsed.descriptor.styles.some((style) => style.scoped) ? `data-v-${sfcId}` : void 0;
11494
11774
  const baseTemplateOptions = parsed.isAppFile ? {
11495
11775
  ...options?.template,
11496
11776
  isPage: options?.isPage,
11497
11777
  propsAliases,
11498
11778
  propsDerivedKeys,
11499
11779
  scriptSetupBindings: scriptCompiled?.bindings,
11500
- scopedSlotsRequireProps: true
11780
+ scopedSlotsRequireProps: true,
11781
+ scopeId: scopedId,
11782
+ slottedScopeId: scopedId && styleCompiled.usesSlotted ? `${scopedId}-s` : void 0,
11783
+ cssVars: parsed.descriptor.cssVars.length > 0
11501
11784
  } : {
11502
11785
  ...options?.template,
11503
11786
  isPage: options?.isPage,
11504
11787
  propsAliases,
11505
11788
  propsDerivedKeys,
11506
- scriptSetupBindings: scriptCompiled?.bindings
11789
+ scriptSetupBindings: scriptCompiled?.bindings,
11790
+ scopeId: scopedId,
11791
+ slottedScopeId: scopedId && styleCompiled.usesSlotted ? `${scopedId}-s` : void 0,
11792
+ cssVars: parsed.descriptor.cssVars.length > 0
11507
11793
  };
11508
11794
  const templateOptions = componentSourceInfo.wevuComponentTags.size ? {
11509
11795
  ...baseTemplateOptions,
@@ -11519,12 +11805,12 @@ async function compileVueFile(source, filename, options) {
11519
11805
  const templateCompiled = compileTemplatePhase(parsed.descriptor, filename, templateOptions, result);
11520
11806
  const scriptPhase = await compileScriptPhase(parsed.descriptor, parsed.descriptorForCompile, filename, options, autoUsingComponents, templateCompiled, parsed.isAppFile, componentSourceInfo, scriptCompiled, {
11521
11807
  propsAliases,
11522
- propsDerivedKeys
11808
+ propsDerivedKeys,
11809
+ cssModules: result.cssModules
11523
11810
  });
11524
11811
  result.script = scriptPhase.script;
11525
11812
  result.scriptMap = scriptPhase.scriptMap;
11526
11813
  if (scriptPhase.template) result.template = scriptPhase.template;
11527
- compileStylePhase(parsed.descriptor, filename, result, options?.style);
11528
11814
  await compileConfigPhase({
11529
11815
  descriptor: parsed.descriptor,
11530
11816
  filename,