@wevu/compiler 6.18.7 → 6.19.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.d.mts CHANGED
@@ -272,6 +272,7 @@ interface ScopedSlotComponentAsset {
272
272
  classStyleBindings?: ClassStyleBinding[];
273
273
  classStyleWxs?: boolean;
274
274
  inlineExpressions?: InlineExpressionAsset[];
275
+ templateRefs?: TemplateRefBinding[];
275
276
  }
276
277
  /**
277
278
  * 内联表达式资源描述。
@@ -566,6 +567,10 @@ interface CompileVueFileOptions {
566
567
  astEngine?: AstEngineName$1;
567
568
  isPage?: boolean;
568
569
  isApp?: boolean;
570
+ /**
571
+ * 是否把组件注册交给上层逻辑入口,当前模块仅导出组件选项。
572
+ */
573
+ skipComponentTransform?: boolean;
569
574
  /**
570
575
  * 是否压缩生成的 wevu 脚本输出。
571
576
  */
@@ -578,6 +583,16 @@ interface CompileVueFileOptions {
578
583
  autoUsingComponents?: AutoUsingComponentsOptions;
579
584
  autoImportTags?: AutoImportTagsOptions;
580
585
  template?: TemplateCompileOptions;
586
+ style?: {
587
+ /**
588
+ * 保留 Vue deep 选择器,交由目标平台的最终 CSS 阶段处理。
589
+ */
590
+ preserveDeepSelectors?: boolean;
591
+ /**
592
+ * 是否在当前阶段改写 scoped 选择器。预处理语言应由最终 CSS 管线完成隔离时可关闭。
593
+ */
594
+ transformScoped?: boolean;
595
+ };
581
596
  json?: {
582
597
  kind?: 'app' | 'page' | 'component';
583
598
  defaults?: JsonConfig['defaults'];
@@ -597,6 +612,32 @@ interface CompileVueFileOptions {
597
612
  */
598
613
  declare function compileJsxFile(source: string, filename: string, options?: CompileVueFileOptions): Promise<VueTransformResult>;
599
614
  //#endregion
615
+ //#region src/plugins/uniApp/index.d.ts
616
+ type UniAppCompatibilityTarget = 'h5' | 'mp-weixin';
617
+ interface TransformUniAppSourceOptions {
618
+ blockType?: 'script' | 'sfc' | 'style' | 'template';
619
+ filename: string;
620
+ target: UniAppCompatibilityTarget;
621
+ }
622
+ /**
623
+ * 按目标平台移除 uni-app 条件编译分支,并保留原始换行以稳定错误位置。
624
+ */
625
+ declare function transformUniAppConditionalCode(source: string, options: TransformUniAppSourceOptions): {
626
+ changed: boolean;
627
+ code: string;
628
+ };
629
+ /**
630
+ * 转换单个受控 uni-app 源文件;未命中语法时返回原文。
631
+ */
632
+ declare function transformUniAppSource(source: string, options: TransformUniAppSourceOptions): {
633
+ changed: boolean;
634
+ code: string;
635
+ };
636
+ /**
637
+ * 判断文件是否属于项目源码或显式允许的 npm 包。
638
+ */
639
+ declare function isUniAppCompatibilityFile(filename: string, srcRoot: string, include: readonly string[]): boolean;
640
+ //#endregion
600
641
  //#region src/plugins/utils/cache.d.ts
601
642
  declare const mtimeCache: Map<string, {
602
643
  ctimeMs: number;
@@ -630,7 +671,14 @@ declare function invalidateFileCache(id: string): void;
630
671
  */
631
672
  declare function clearFileCaches(): void;
632
673
  //#endregion
674
+ //#region src/plugins/vue/compiler/wxss.d.ts
675
+ /**
676
+ * 压平 WXSS 不接受的嵌套 CSS 变量回退值。
677
+ */
678
+ declare function transformNestedWxssVars(source: string): string;
679
+ //#endregion
633
680
  //#region src/plugins/vue/compiler/style.d.ts
681
+ declare function transformVueDeepSelectors(source: string): string;
634
682
  /**
635
683
  * 样式编译结果。
636
684
  */
@@ -646,8 +694,10 @@ interface StyleCompileResult {
646
694
  interface StyleCompileOptions {
647
695
  id: string;
648
696
  scoped?: boolean;
697
+ transformScoped?: boolean;
649
698
  modules?: boolean | string;
650
699
  preprocessOptions?: Record<string, any>;
700
+ preserveDeepSelectors?: boolean;
651
701
  }
652
702
  /**
653
703
  * 将 Vue SFC 的 style 块转换为 WXSS
@@ -786,6 +836,11 @@ interface TransformResult {
786
836
  map?: EncodedSourceMapLike | null;
787
837
  }
788
838
  interface TransformScriptOptions {
839
+ /**
840
+ * 输入是否来自 TypeScript SFC 区块。
841
+ * TypeScript 输入必须经过 AST 路径清理类型语法,不能使用仅重排文本的 script setup 快速路径。
842
+ */
843
+ isTypeScript?: boolean;
789
844
  /**
790
845
  * 是否跳过组件转换(不添加 createWevuComponent 调用)
791
846
  * 用于 app.vue 等入口文件
@@ -1040,4 +1095,4 @@ interface CollectVueTemplateTagsOptions {
1040
1095
  */
1041
1096
  declare function collectVueTemplateTags(template: string, options: CollectVueTemplateTagsOptions): Set<string>;
1042
1097
  //#endregion
1043
- export { type AstEngineName, type AutoImportTagsOptions, type AutoUsingComponentsOptions, CLASS_STYLE_WXS_FILE, CLASS_STYLE_WXS_MODULE, type ClassStyleBinding, type ClassStyleRuntime, type CollectVueTemplateTagsOptions, type CompileVueFileOptions, type ForParseResult, type InlineExpressionAsset, type JsLikeLang, type JsonConfig, type JsonMergeContext, type JsonMergeStage, type JsonMergeStrategy, type MiniProgramPlatform, type ModuleResolver, type MpPlatform, RESERVED_VUE_COMPONENT_TAGS, type ReadAndParseSfcOptions, type ResolveSfcBlockSrcOptions, type ResolvedUsingComponentInfo, type ResolvedUsingComponentPath, type ScopedSlotComponentAsset, type SlotFallbackWrapperComponentAsset, type SlotFallbackWrapperStrategy, type StyleCompileOptions, type StyleCompileResult, type TemplateCompileOptions, type TemplateCompileResult, type TemplateRefBinding, type TransformResult, type TransformScriptOptions, VUE_COMPONENT_TAG_RE, type VueTransformResult, WE_VU_COMPILER_REACTIVITY_MODULE_ID, WE_VU_COMPILER_RUNTIME_MODULE_ID, WE_VU_COMPILER_TEMPLATE_MODULE_ID, WE_VU_INTERNAL_REACTIVITY_APIS, WE_VU_INTERNAL_REACTIVITY_MODULE_ID, WE_VU_INTERNAL_RUNTIME_MODULE_ID, WE_VU_INTERNAL_TEMPLATE_APIS, WE_VU_INTERNAL_TEMPLATE_MODULE_ID, WE_VU_MODULE_ID, WE_VU_PAGE_HOOK_TO_FEATURE, WE_VU_RUNTIME_APIS, WE_VU_RUNTIME_MODULE_IDS, type WevuDefaults, WevuPageFeatureFlag, WevuPageHookName, WevuRuntimeApiName, alipayPlatform, buildClassStyleComputedCode, buildClassStyleWxsTag, builtinComponentsSet, clearFileCaches, collectTargetOptionsObjectsFromCode, collectVueTemplateTags, collectWevuFeaturesFromCodeReachableImports, collectWevuPageFeatureFlags, collectWevuPageFeatureFlagsFromCode, compileConfigBlocks, compileJsxFile, compileVueFile as compileSfc, compileVueFile, compileVueStyleToWxss as compileStyle, compileVueStyleToWxss, compileVueTemplateToWxml as compileTemplate, compileVueTemplateToWxml, createJsonMerger, createPageEntryMatcher, defaultMiniProgramPlatform, defaultMiniProgramTemplatePlatform, defaultPlatform, evaluateJsLikeConfig, extractJsonMacroFromScriptSetup, generateScopedId, getClassStyleWxsSource, getDefaultMiniProgramPlatform, getDefaultMiniProgramTemplatePlatform, getMiniProgramTemplatePlatform, getSfcCheckMtime, injectWevuPageFeatureFlagsIntoOptionsObject, injectWevuPageFeaturesInJs, injectWevuPageFeaturesInJsWithResolver, invalidateFileCache, isAutoImportCandidateTag, isBuiltinComponent, isInvalidate, isJsonLikeLang, isWevuRuntimeModuleId, loadCache, mayContainJsonMacro, mergeJsonWithStrategy, mtimeCache, normalizeConfigLang, pathExists, preprocessScriptSetupSrc, preprocessScriptSrc, readAndParseSfc, readFile, refreshVueFileJsonConfig, resolveClassStyleWxsLocation, resolveJsLikeLang, resolveSfcBlockSrc, resolveWevuInternalImportModuleId, restoreScriptSetupSrc, restoreScriptSrc, stripJsonMacroCallsFromCode, swanPlatform, transformScript, transformScript as transformSfcScript, ttPlatform, wechatPlatform };
1098
+ export { type AstEngineName, type AutoImportTagsOptions, type AutoUsingComponentsOptions, CLASS_STYLE_WXS_FILE, CLASS_STYLE_WXS_MODULE, type ClassStyleBinding, type ClassStyleRuntime, type CollectVueTemplateTagsOptions, type CompileVueFileOptions, type ForParseResult, type InlineExpressionAsset, type JsLikeLang, type JsonConfig, type JsonMergeContext, type JsonMergeStage, type JsonMergeStrategy, type MiniProgramPlatform, type ModuleResolver, type MpPlatform, RESERVED_VUE_COMPONENT_TAGS, type ReadAndParseSfcOptions, type ResolveSfcBlockSrcOptions, type ResolvedUsingComponentInfo, type ResolvedUsingComponentPath, type ScopedSlotComponentAsset, type SlotFallbackWrapperComponentAsset, type SlotFallbackWrapperStrategy, type StyleCompileOptions, type StyleCompileResult, type TemplateCompileOptions, type TemplateCompileResult, type TemplateRefBinding, type TransformResult, type TransformScriptOptions, type TransformUniAppSourceOptions, type UniAppCompatibilityTarget, VUE_COMPONENT_TAG_RE, type VueTransformResult, WE_VU_COMPILER_REACTIVITY_MODULE_ID, WE_VU_COMPILER_RUNTIME_MODULE_ID, WE_VU_COMPILER_TEMPLATE_MODULE_ID, WE_VU_INTERNAL_REACTIVITY_APIS, WE_VU_INTERNAL_REACTIVITY_MODULE_ID, WE_VU_INTERNAL_RUNTIME_MODULE_ID, WE_VU_INTERNAL_TEMPLATE_APIS, WE_VU_INTERNAL_TEMPLATE_MODULE_ID, WE_VU_MODULE_ID, WE_VU_PAGE_HOOK_TO_FEATURE, WE_VU_RUNTIME_APIS, WE_VU_RUNTIME_MODULE_IDS, type WevuDefaults, WevuPageFeatureFlag, WevuPageHookName, WevuRuntimeApiName, alipayPlatform, buildClassStyleComputedCode, buildClassStyleWxsTag, builtinComponentsSet, clearFileCaches, collectTargetOptionsObjectsFromCode, collectVueTemplateTags, collectWevuFeaturesFromCodeReachableImports, collectWevuPageFeatureFlags, collectWevuPageFeatureFlagsFromCode, compileConfigBlocks, compileJsxFile, compileVueFile as compileSfc, compileVueFile, compileVueStyleToWxss as compileStyle, compileVueStyleToWxss, compileVueTemplateToWxml as compileTemplate, compileVueTemplateToWxml, createJsonMerger, createPageEntryMatcher, defaultMiniProgramPlatform, defaultMiniProgramTemplatePlatform, defaultPlatform, evaluateJsLikeConfig, extractJsonMacroFromScriptSetup, generateScopedId, getClassStyleWxsSource, getDefaultMiniProgramPlatform, getDefaultMiniProgramTemplatePlatform, getMiniProgramTemplatePlatform, getSfcCheckMtime, injectWevuPageFeatureFlagsIntoOptionsObject, injectWevuPageFeaturesInJs, injectWevuPageFeaturesInJsWithResolver, invalidateFileCache, isAutoImportCandidateTag, isBuiltinComponent, isInvalidate, isJsonLikeLang, isUniAppCompatibilityFile, isWevuRuntimeModuleId, loadCache, mayContainJsonMacro, mergeJsonWithStrategy, mtimeCache, normalizeConfigLang, pathExists, preprocessScriptSetupSrc, preprocessScriptSrc, readAndParseSfc, readFile, refreshVueFileJsonConfig, resolveClassStyleWxsLocation, resolveJsLikeLang, resolveSfcBlockSrc, resolveWevuInternalImportModuleId, restoreScriptSetupSrc, restoreScriptSrc, stripJsonMacroCallsFromCode, swanPlatform, transformNestedWxssVars, transformScript, transformScript as transformSfcScript, transformUniAppConditionalCode, transformUniAppSource, transformVueDeepSelectors, ttPlatform, wechatPlatform };
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
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_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_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";
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_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
3
  import { getMiniProgramRuntimeGlobalKeys, getMiniProgramTemplatePreset, removeExtensionDeep } from "@weapp-core/shared";
4
4
  import path from "pathe";
5
5
  import { NodeTypes, baseParse } from "@vue/compiler-core";
@@ -17,6 +17,8 @@ import { LRUCache } from "lru-cache";
17
17
  import { collectJsxImportedComponentsAndDefaultExportFromBabelAst, collectJsxTemplateTagsFromBabelExpression, getRenderPropertyFromComponentOptions, parseJsLikeWithEngine, resolveRenderExpressionFromComponentOptions, toStaticObjectKey, unwrapTypeScriptExpression } from "@weapp-vite/ast";
18
18
  import { compileScript, parse } from "vue/compiler-sfc";
19
19
  import { fileURLToPath } from "node:url";
20
+ import postcss from "postcss";
21
+ import selectorParser from "postcss-selector-parser";
20
22
  import { parse as parse$1 } from "@vue/compiler-dom";
21
23
  import { parse as parse$2 } from "comment-json";
22
24
  import vm from "node:vm";
@@ -2248,7 +2250,7 @@ const JSON_MACRO_RE = /\bdefine(?:App|Page|Component|Sitemap|Theme)Json\s*\(/;
2248
2250
  const PAGE_META_RE = /\bdefinePageMeta\s*\(/;
2249
2251
  function hasMetadataInjectionOptions(options) {
2250
2252
  const hasWevuDefaults = options?.wevuDefaults && Object.keys(options.wevuDefaults).length > 0;
2251
- return Boolean(options?.isApp || options?.skipComponentTransform || options?.minify || options?.sourceMap !== false || options?.templateComponentMeta || hasWevuDefaults || options?.classStyleBindings?.length || options?.templateRefs?.length || options?.layoutHosts?.length || options?.inlineExpressions?.length || options?.functionPropPaths?.length || options?.propsAliases || options?.propsDerivedKeys?.length || options?.relaxStructuredTypeOnlyProps || options?.scopedSlotHostProperties);
2253
+ return Boolean(options?.isTypeScript || options?.isApp || options?.skipComponentTransform || options?.minify || options?.sourceMap !== false || options?.templateComponentMeta || hasWevuDefaults || options?.classStyleBindings?.length || options?.templateRefs?.length || options?.layoutHosts?.length || options?.inlineExpressions?.length || options?.functionPropPaths?.length || options?.propsAliases || options?.propsDerivedKeys?.length || options?.relaxStructuredTypeOnlyProps || options?.scopedSlotHostProperties);
2252
2254
  }
2253
2255
  function findMatchingCallEnd(source, openParenIndex) {
2254
2256
  let depth = 0;
@@ -2302,7 +2304,7 @@ function findMatchingCallEnd(source, openParenIndex) {
2302
2304
  return -1;
2303
2305
  }
2304
2306
  function stripCompiledScriptSetupMarkers(optionsSource) {
2305
- return optionsSource.replace(/^\s*__name:\s*['"][^'"]+['"],?\n?/m, "").replace(/\{\s*expose:\s*__expose\s*\}/g, "{ expose }").replace(/\b__expose\s*\(\s*\);?/g, "expose();").replace(/^\s*Object\.defineProperty\(\s*__returned__\s*,\s*['"]__isScriptSetup['"]\s*,\s*\{\s*enumerable:\s*false\s*,\s*value:\s*true\s*\}\s*\);?\n?/m, "");
2307
+ return optionsSource.replace(/^\s*__name:\s*['"][^'"]+['"],?\n?/m, "").replace(/\{\s*expose:\s*__expose\s*\}/g, "{ expose }").replace(/\b__expose(?=\s*\()/g, "expose").replace(/^\s*Object\.defineProperty\(\s*__returned__\s*,\s*['"]__isScriptSetup['"]\s*,\s*\{\s*enumerable:\s*false\s*,\s*value:\s*true\s*\}\s*\);?\n?/m, "");
2306
2308
  }
2307
2309
  /**
2308
2310
  * 转换 Vue compileScript 产出的标准 `<script setup>` 脚本。
@@ -2327,7 +2329,7 @@ function tryFastTransformCompiledScriptSetup(source, options) {
2327
2329
  const trailing = afterImport.slice(callEnd + 1).trim();
2328
2330
  if (trailing && trailing !== ";") return;
2329
2331
  const componentOptions = stripCompiledScriptSetupMarkers(afterImport.slice(openParenIndex + 1, callEnd).trim());
2330
- const pageMarker = options?.isPage ? " __wevu_isPage: true,\n" : "";
2332
+ const pageMarker = ` __wevu_isPage: ${options?.isPage === true},\n`;
2331
2333
  return {
2332
2334
  code: [
2333
2335
  `import { ${WE_VU_RUNTIME_APIS.createWevuComponent} } from "${RUNTIME_IMPORT_PATH}";`,
@@ -2968,6 +2970,13 @@ function buildObjectMapExpression(binding, forStack, level, listId, helpers) {
2968
2970
  t.returnStatement(resId)
2969
2971
  ]);
2970
2972
  }
2973
+ function buildNumericListNormalization(level, listId) {
2974
+ const indexId = t.identifier(`__wv_numeric_index_${level}`);
2975
+ const numberCheck = t.logicalExpression("&&", t.binaryExpression("===", t.unaryExpression("typeof", listId), t.stringLiteral("number")), t.callExpression(t.memberExpression(t.identifier("Number"), t.identifier("isFinite")), [listId]));
2976
+ const length = t.callExpression(t.memberExpression(t.identifier("Math"), t.identifier("max")), [t.numericLiteral(0), t.callExpression(t.memberExpression(t.identifier("Math"), t.identifier("floor")), [listId])]);
2977
+ const normalized = t.callExpression(t.memberExpression(t.identifier("Array"), t.identifier("from")), [t.objectExpression([t.objectProperty(t.identifier("length"), length)]), t.arrowFunctionExpression([t.identifier("_"), indexId], indexId)]);
2978
+ return t.ifStatement(numberCheck, t.blockStatement([t.expressionStatement(t.assignmentExpression("=", listId, normalized))]));
2979
+ }
2971
2980
  function buildForExpression(binding, forStack, level, helpers) {
2972
2981
  if (level >= forStack.length) return buildNormalizedExpression(binding, helpers);
2973
2982
  const info = forStack[level];
@@ -2985,6 +2994,7 @@ function buildForExpression(binding, forStack, level, helpers) {
2985
2994
  const body = t.blockStatement([
2986
2995
  listDecl,
2987
2996
  listSafeAssign,
2997
+ buildNumericListNormalization(level, listId),
2988
2998
  t.ifStatement(arrayCheck, t.blockStatement([t.returnStatement(arrayMap)]), t.ifStatement(objectCheck, objectBlock, t.blockStatement([fallbackReturn])))
2989
2999
  ]);
2990
3000
  return t.callExpression(t.arrowFunctionExpression([], body), []);
@@ -3242,6 +3252,40 @@ const BABEL_GENERATE_MINI_PROGRAM_OPTIONS = {
3242
3252
  minimal: true
3243
3253
  }
3244
3254
  };
3255
+ function stripPatternTypes(node) {
3256
+ if (!node || typeof node !== "object") return;
3257
+ if ("typeAnnotation" in node) node.typeAnnotation = null;
3258
+ if ("optional" in node) node.optional = false;
3259
+ if (node.type === "AssignmentPattern") stripPatternTypes(node.left);
3260
+ else if (node.type === "RestElement") stripPatternTypes(node.argument);
3261
+ else if (node.type === "ObjectPattern") for (const property of node.properties) stripPatternTypes(property.type === "RestElement" ? property.argument : property.value);
3262
+ else if (node.type === "ArrayPattern") for (const element of node.elements) stripPatternTypes(element);
3263
+ }
3264
+ function stripTypeScriptExpression(ast) {
3265
+ traverse(ast, {
3266
+ TSAsExpression(path) {
3267
+ path.replaceWith(path.node.expression);
3268
+ },
3269
+ TSNonNullExpression(path) {
3270
+ path.replaceWith(path.node.expression);
3271
+ },
3272
+ TSTypeAssertion(path) {
3273
+ path.replaceWith(path.node.expression);
3274
+ },
3275
+ Function(path) {
3276
+ path.node.typeParameters = null;
3277
+ path.node.returnType = null;
3278
+ for (const param of path.node.params) stripPatternTypes(param);
3279
+ }
3280
+ });
3281
+ return ast;
3282
+ }
3283
+ function parseTypeScriptExpression(exp) {
3284
+ return stripTypeScriptExpression(parse$3(`(${exp})`, {
3285
+ sourceType: "module",
3286
+ plugins: ["typescript"]
3287
+ }));
3288
+ }
3245
3289
  function generateExpression(node) {
3246
3290
  const { code } = generate(node, BABEL_GENERATE_MINI_PROGRAM_OPTIONS);
3247
3291
  return code;
@@ -3250,10 +3294,7 @@ function parseBabelExpression(exp) {
3250
3294
  const cached = babelExpressionCache.get(exp);
3251
3295
  if (cached !== void 0) return cached === false ? null : cached;
3252
3296
  try {
3253
- const stmt = parse$3(`(${exp})`, {
3254
- sourceType: "module",
3255
- plugins: ["typescript"]
3256
- }).program.body[0];
3297
+ const stmt = parseTypeScriptExpression(exp).program.body[0];
3257
3298
  if (!stmt || !("expression" in stmt)) {
3258
3299
  babelExpressionCache.set(exp, false);
3259
3300
  return null;
@@ -3268,10 +3309,7 @@ function parseBabelExpression(exp) {
3268
3309
  }
3269
3310
  function parseBabelExpressionFile(exp) {
3270
3311
  try {
3271
- const ast = parse$3(`(${exp})`, {
3272
- sourceType: "module",
3273
- plugins: ["typescript"]
3274
- });
3312
+ const ast = parseTypeScriptExpression(exp);
3275
3313
  const stmt = ast.program.body[0];
3276
3314
  if (!stmt || !("expression" in stmt)) return null;
3277
3315
  return {
@@ -3676,8 +3714,8 @@ function rewriteDefaultExport(ast, state, options, enabledPageFeatures, serializ
3676
3714
  const componentExpr = resolveComponentExpression(exportPath.node.declaration, state.defineComponentDecls, state.defineComponentAliases);
3677
3715
  const componentOptionsObject = resolveComponentOptionsObject(componentExpr);
3678
3716
  const hasPageMarker = componentExpr ? hasStaticPropertyInComponentExpression(componentExpr, WEVU_IS_PAGE_KEY, ast.program) : false;
3679
- if (componentOptionsObject && options?.isPage && !options?.isApp && !hasPageMarker) {
3680
- componentOptionsObject.properties.splice(0, 0, t.objectProperty(t.identifier(WEVU_IS_PAGE_KEY), t.booleanLiteral(true)));
3717
+ if (componentOptionsObject && !options?.isApp && !hasPageMarker) {
3718
+ componentOptionsObject.properties.splice(0, 0, t.objectProperty(t.identifier(WEVU_IS_PAGE_KEY), t.booleanLiteral(options?.isPage === true)));
3681
3719
  transformed = true;
3682
3720
  }
3683
3721
  if (componentOptionsObject && enabledPageFeatures.size) transformed = injectWevuPageFeatureFlagsIntoOptionsObject(componentOptionsObject, enabledPageFeatures) || transformed;
@@ -3870,8 +3908,35 @@ const EMPTY_STRING_CONCAT_LEFT_RE = /'\s*\+\s*''/g;
3870
3908
  const EMPTY_STRING_CONCAT_RIGHT_RE = /''\s*\+\s*'/g;
3871
3909
  const LEADING_EMPTY_CONCAT_RE = /^\s*''\s*\+\s*/g;
3872
3910
  const TRAILING_EMPTY_CONCAT_RE = /\s*\+\s*''\s*$/g;
3911
+ function rewriteVueSlotsExpression(ast) {
3912
+ traverse(ast, {
3913
+ MemberExpression: { exit(path) {
3914
+ const node = path.node;
3915
+ if (!t.isIdentifier(node.object, { name: "$slots" })) return;
3916
+ const access = t.memberExpression(t.identifier("vueSlots"), t.cloneNode(node.property), node.computed);
3917
+ path.replaceWith(t.logicalExpression("&&", t.identifier("vueSlots"), access));
3918
+ path.skip();
3919
+ } },
3920
+ OptionalMemberExpression: { exit(path) {
3921
+ const node = path.node;
3922
+ if (!t.isIdentifier(node.object, { name: "$slots" })) return;
3923
+ const access = t.memberExpression(t.identifier("vueSlots"), t.cloneNode(node.property), node.computed);
3924
+ path.replaceWith(t.logicalExpression("&&", t.identifier("vueSlots"), access));
3925
+ path.skip();
3926
+ } },
3927
+ Identifier: { exit(path) {
3928
+ if (!path.isReferencedIdentifier() || path.node.name !== "$slots") return;
3929
+ const parent = path.parentPath.node;
3930
+ if ((t.isMemberExpression(parent) || t.isOptionalMemberExpression(parent)) && parent.object === path.node) return;
3931
+ path.replaceWith(t.identifier("vueSlots"));
3932
+ path.skip();
3933
+ } }
3934
+ });
3935
+ }
3873
3936
  function normalizeWxmlExpression(exp) {
3874
- if (!exp.includes("`") && !exp.includes("??") && !exp.includes("?.")) return exp;
3937
+ const hasTypeScriptSyntax = /\s(?:as|satisfies)\s/.test(exp) || /[\w$)\]]!(?=[.[\s,);:?]|$)/.test(exp) || /^\s*<[^>]+>/.test(exp);
3938
+ const needsVueSlotsRewrite = exp.includes("$slots");
3939
+ if (!exp.includes("`") && !exp.includes("??") && !exp.includes("?.") && !hasTypeScriptSyntax && !needsVueSlotsRewrite) return exp;
3875
3940
  try {
3876
3941
  const ast = parse$3(`(${exp})`, {
3877
3942
  sourceType: "module",
@@ -3879,7 +3944,17 @@ function normalizeWxmlExpression(exp) {
3879
3944
  });
3880
3945
  const stmt = ast.program.body[0];
3881
3946
  if (!stmt || !("expression" in stmt)) return exp;
3947
+ if (needsVueSlotsRewrite) rewriteVueSlotsExpression(ast);
3882
3948
  traverse(ast, {
3949
+ TSAsExpression(path) {
3950
+ path.replaceWith(path.node.expression);
3951
+ },
3952
+ TSNonNullExpression(path) {
3953
+ path.replaceWith(path.node.expression);
3954
+ },
3955
+ TSTypeAssertion(path) {
3956
+ path.replaceWith(path.node.expression);
3957
+ },
3883
3958
  OptionalMemberExpression: { exit(path) {
3884
3959
  if (isOptionalChainNode(path.parentPath.node)) return;
3885
3960
  path.replaceWith(lowerOptionalChain(path.node));
@@ -4912,7 +4987,7 @@ async function compileJsxFile(source, filename, options) {
4912
4987
  }
4913
4988
  const normalizedScriptSource = stripRenderOptionFromScript(scriptSource, filename, options?.warn);
4914
4989
  const transformedScript = transformScript(normalizedScriptSource, {
4915
- skipComponentTransform: options?.isApp,
4990
+ skipComponentTransform: options?.skipComponentTransform ?? options?.isApp,
4916
4991
  isApp: options?.isApp,
4917
4992
  isPage: options?.isPage,
4918
4993
  minify: options?.minify,
@@ -4951,6 +5026,276 @@ async function compileJsxFile(source, filename, options) {
4951
5026
  };
4952
5027
  }
4953
5028
  //#endregion
5029
+ //#region src/plugins/uniApp/index.ts
5030
+ const DIRECTIVE_TOKEN_RE = /\/\/\s*#(?:ifdef|ifndef|else|endif)\b[^\r\n]*|\/\*+\s*#(?:ifdef|ifndef|else|endif)\b[\s\S]*?\*\/|<!--\s*#(?:ifdef|ifndef|else|endif)\b[\s\S]*?-->/g;
5031
+ const SCRIPT_EXT_RE = /\.[cm]?[jt]sx?$/i;
5032
+ const STYLE_EXT_RE = /\.(?:css|less|sass|scss|styl|stylus)$/i;
5033
+ const UNI_APP_RUNTIME_MODULE = "@dcloudio/uni-app";
5034
+ function resolveRuntimeImport(source) {
5035
+ if (source === "vue" || source === UNI_APP_RUNTIME_MODULE) return "wevu";
5036
+ }
5037
+ function evaluateCondition(expression, defines, filename, line) {
5038
+ const normalized = expression.replace(/(?:\*\/|-->)\s*$/, "").trim();
5039
+ const tokens = normalized.match(/[A-Z][A-Z0-9_-]*|&&|\|\||[()!]/g) ?? [];
5040
+ if (!tokens.length || tokens.join("") !== normalized.replace(/\s/g, "")) throw new Error(`[uni-app] ${filename}:${line} 包含无效的条件表达式 "${normalized}"`);
5041
+ let index = 0;
5042
+ const parser = {
5043
+ parseAnd() {
5044
+ let value = parser.parsePrimary();
5045
+ while (tokens[index] === "&&") {
5046
+ index += 1;
5047
+ const right = parser.parsePrimary();
5048
+ value = value && right;
5049
+ }
5050
+ return value;
5051
+ },
5052
+ parseOr() {
5053
+ let value = parser.parseAnd();
5054
+ while (tokens[index] === "||") {
5055
+ index += 1;
5056
+ const right = parser.parseAnd();
5057
+ value = value || right;
5058
+ }
5059
+ return value;
5060
+ },
5061
+ parsePrimary() {
5062
+ const token = tokens[index];
5063
+ if (token === "!") {
5064
+ index += 1;
5065
+ return !parser.parsePrimary();
5066
+ }
5067
+ if (token === "(") {
5068
+ index += 1;
5069
+ const value = parser.parseOr();
5070
+ if (tokens[index] !== ")") throw new Error(`[uni-app] ${filename}:${line} 包含无效的条件表达式 "${normalized}"`);
5071
+ index += 1;
5072
+ return value;
5073
+ }
5074
+ if (!token || !/^[A-Z][A-Z0-9_-]*$/.test(token)) throw new Error(`[uni-app] ${filename}:${line} 包含无效的条件表达式 "${normalized}"`);
5075
+ index += 1;
5076
+ return defines.has(token);
5077
+ }
5078
+ };
5079
+ const value = parser.parseOr();
5080
+ if (index !== tokens.length) throw new Error(`[uni-app] ${filename}:${line} 包含无效的条件表达式 "${normalized}"`);
5081
+ return value;
5082
+ }
5083
+ /**
5084
+ * 按目标平台移除 uni-app 条件编译分支,并保留原始换行以稳定错误位置。
5085
+ */
5086
+ function transformUniAppConditionalCode(source, options) {
5087
+ const defines = new Set(options.target === "h5" ? ["H5", "VUE3"] : [
5088
+ "MP",
5089
+ "MP-WEIXIN",
5090
+ "VUE3"
5091
+ ]);
5092
+ const frames = [];
5093
+ let active = true;
5094
+ let changed = false;
5095
+ let cursor = 0;
5096
+ let line = 1;
5097
+ let code = "";
5098
+ for (const match of source.matchAll(DIRECTIVE_TOKEN_RE)) {
5099
+ const offset = match.index;
5100
+ const segment = source.slice(cursor, offset);
5101
+ code += active ? segment : segment.replace(/[^\r\n]/g, "");
5102
+ line += segment.split("\n").length - 1;
5103
+ const directiveSource = match[0].slice(match[0].indexOf("#"));
5104
+ const directiveMatch = directiveSource.match(/^#(ifdef|ifndef|else|endif)\b/);
5105
+ if (!directiveMatch) continue;
5106
+ changed = true;
5107
+ const directive = directiveMatch[1];
5108
+ if (directive === "ifdef" || directive === "ifndef") {
5109
+ const condition = evaluateCondition(directiveSource.slice(directiveMatch[0].length), defines, options.filename, line);
5110
+ frames.push({
5111
+ condition,
5112
+ elseSeen: false,
5113
+ parentActive: active
5114
+ });
5115
+ active = active && (directive === "ifdef" ? condition : !condition);
5116
+ } else {
5117
+ const frame = frames[frames.length - 1];
5118
+ if (!frame) throw new Error(`[uni-app] ${options.filename}:${line} 存在未配对的 #${directive}`);
5119
+ if (directive === "else") {
5120
+ if (frame.elseSeen) throw new Error(`[uni-app] ${options.filename}:${line} 同一条件块不能出现多个 #else`);
5121
+ frame.elseSeen = true;
5122
+ active = frame.parentActive && !frame.condition;
5123
+ } else {
5124
+ frames.pop();
5125
+ active = frame.parentActive;
5126
+ }
5127
+ }
5128
+ code += match[0].replace(/[^\r\n]/g, "");
5129
+ line += match[0].split("\n").length - 1;
5130
+ cursor = offset + match[0].length;
5131
+ }
5132
+ const trailing = source.slice(cursor);
5133
+ code += active ? trailing : trailing.replace(/[^\r\n]/g, "");
5134
+ if (frames.length) throw new Error(`[uni-app] ${options.filename} 存在未闭合的条件编译块`);
5135
+ return {
5136
+ changed,
5137
+ code
5138
+ };
5139
+ }
5140
+ function normalizeAuxiliaryWxsScripts(source) {
5141
+ const wxsBlocks = [];
5142
+ const withoutScripts = source.replace(/<script\b([^>]*)>([\s\S]*?)<\/script>/gi, (block, attributes, content) => {
5143
+ const src = attributes.match(/\bsrc\s*=\s*["']([^"']+)["']/i)?.[1];
5144
+ const moduleName = attributes.match(/\bmodule\s*=\s*["']([^"']+)["']/i)?.[1];
5145
+ if (!(/\blang\s*=\s*["']wxs["']/i.test(attributes) || src?.endsWith(".wxs")) || !moduleName) return block;
5146
+ wxsBlocks.push(src ? `<wxs module="${moduleName}" src="${src}" />` : `<wxs module="${moduleName}">${content}</wxs>`);
5147
+ return block.replace(/[^\r\n]/g, "");
5148
+ });
5149
+ if (!wxsBlocks.length) return source;
5150
+ return withoutScripts.replace(/<template\b[^>]*>/i, (match) => `${match}\n${wxsBlocks.join("\n")}`);
5151
+ }
5152
+ function analyzeScript(source, filename) {
5153
+ if (!source.trim()) return {
5154
+ source,
5155
+ importSources: [],
5156
+ importEnd: 0,
5157
+ usesFreeUni: false,
5158
+ virtualHostTrueRanges: []
5159
+ };
5160
+ const ast = parse$3(source, {
5161
+ sourceType: "module",
5162
+ plugins: [
5163
+ "typescript",
5164
+ "decorators-legacy",
5165
+ .../\.[cm]?[jt]sx$/i.test(filename) ? ["jsx"] : []
5166
+ ]
5167
+ });
5168
+ const importSources = [];
5169
+ let importEnd = 0;
5170
+ let usesFreeUni = false;
5171
+ const virtualHostTrueRanges = [];
5172
+ traverse(ast, {
5173
+ ImportDeclaration(path) {
5174
+ const sourceNode = path.node.source;
5175
+ if (typeof path.node.end === "number") importEnd = Math.max(importEnd, path.node.end);
5176
+ const replacement = t.isStringLiteral(sourceNode) ? resolveRuntimeImport(sourceNode.value) : void 0;
5177
+ if (replacement) importSources.push({
5178
+ start: sourceNode.start,
5179
+ end: sourceNode.end,
5180
+ replacement
5181
+ });
5182
+ },
5183
+ ExportAllDeclaration(path) {
5184
+ const sourceNode = path.node.source;
5185
+ const replacement = t.isStringLiteral(sourceNode) ? resolveRuntimeImport(sourceNode.value) : void 0;
5186
+ if (replacement) importSources.push({
5187
+ start: sourceNode.start,
5188
+ end: sourceNode.end,
5189
+ replacement
5190
+ });
5191
+ },
5192
+ ExportNamedDeclaration(path) {
5193
+ const sourceNode = path.node.source;
5194
+ const replacement = t.isStringLiteral(sourceNode) ? resolveRuntimeImport(sourceNode.value) : void 0;
5195
+ if (replacement) importSources.push({
5196
+ start: sourceNode.start,
5197
+ end: sourceNode.end,
5198
+ replacement
5199
+ });
5200
+ },
5201
+ ReferencedIdentifier(path) {
5202
+ if (path.node.name === "uni" && !path.scope.hasBinding("uni")) usesFreeUni = true;
5203
+ },
5204
+ ObjectProperty(path) {
5205
+ const key = path.node.key;
5206
+ if (!(!path.node.computed && (t.isIdentifier(key, { name: "virtualHost" }) || t.isStringLiteral(key, { value: "virtualHost" }))) || !t.isBooleanLiteral(path.node.value, { value: true }) || !path.parentPath?.isObjectExpression()) return;
5207
+ const optionsProperty = path.parentPath.parentPath;
5208
+ if (!optionsProperty?.isObjectProperty() || optionsProperty.node.computed || !(t.isIdentifier(optionsProperty.node.key, { name: "options" }) || t.isStringLiteral(optionsProperty.node.key, { value: "options" }))) return;
5209
+ const { start, end } = path.node.value;
5210
+ if (typeof start === "number" && typeof end === "number") virtualHostTrueRanges.push({
5211
+ start,
5212
+ end
5213
+ });
5214
+ }
5215
+ });
5216
+ return {
5217
+ source,
5218
+ importSources,
5219
+ importEnd,
5220
+ usesFreeUni,
5221
+ virtualHostTrueRanges
5222
+ };
5223
+ }
5224
+ function renderScript(analysis, injectUni, disableVirtualHost) {
5225
+ const output = new MagicString(analysis.source);
5226
+ for (const source of analysis.importSources) output.overwrite(source.start, source.end, JSON.stringify(source.replacement));
5227
+ if (injectUni) {
5228
+ const insertion = analysis.importEnd > 0 ? analysis.importEnd : 0;
5229
+ output.prepend(`import { createUniAppHost as __wevuCreateUniAppHost } from 'wevu/internal-runtime'\n`);
5230
+ output.appendLeft(insertion, `${insertion > 0 ? "\n" : ""}const uni = __wevuCreateUniAppHost(wx)\n`);
5231
+ }
5232
+ if (disableVirtualHost) for (const range of analysis.virtualHostTrueRanges) output.overwrite(range.start, range.end, "false");
5233
+ return output.toString();
5234
+ }
5235
+ function transformVueSfc(source, filename, target) {
5236
+ const normalizedSource = normalizeAuxiliaryWxsScripts(source);
5237
+ const { descriptor, errors } = parse(normalizedSource, { filename });
5238
+ if (errors.length) {
5239
+ const error = errors[0];
5240
+ throw new Error(`[uni-app] 解析 ${filename} 失败:${error.message}`);
5241
+ }
5242
+ const blocks = [descriptor.script, descriptor.scriptSetup].filter(Boolean);
5243
+ const analyses = blocks.map((block) => {
5244
+ const lang = block.lang ?? "js";
5245
+ return analyzeScript(block.content, `${filename}.${lang}`);
5246
+ });
5247
+ const injectIndex = analyses.findIndex((analysis) => analysis.usesFreeUni);
5248
+ const output = new MagicString(normalizedSource);
5249
+ for (let index = blocks.length - 1; index >= 0; index -= 1) {
5250
+ const block = blocks[index];
5251
+ const analysis = analyses[index];
5252
+ const code = renderScript(analysis, index === injectIndex, target === "mp-weixin");
5253
+ output.overwrite(block.loc.start.offset, block.loc.end.offset, code);
5254
+ }
5255
+ return output.toString();
5256
+ }
5257
+ /**
5258
+ * 转换单个受控 uni-app 源文件;未命中语法时返回原文。
5259
+ */
5260
+ function transformUniAppSource(source, options) {
5261
+ const conditional = transformUniAppConditionalCode(source, options);
5262
+ const filename = options.filename.split("?", 1)[0];
5263
+ const blockType = options.blockType ?? (filename.endsWith(".vue") ? "sfc" : SCRIPT_EXT_RE.test(filename) ? "script" : STYLE_EXT_RE.test(filename) ? "style" : void 0);
5264
+ if (blockType === "sfc") {
5265
+ const code = transformVueSfc(conditional.code, filename, options.target);
5266
+ return {
5267
+ changed: conditional.changed || code !== source,
5268
+ code
5269
+ };
5270
+ }
5271
+ if (blockType === "script") {
5272
+ const analysis = analyzeScript(conditional.code, filename);
5273
+ const code = renderScript(analysis, analysis.usesFreeUni, options.target === "mp-weixin" && filename.endsWith(".vue"));
5274
+ return {
5275
+ changed: conditional.changed || code !== source,
5276
+ code
5277
+ };
5278
+ }
5279
+ if (blockType === "style" || blockType === "template") return conditional;
5280
+ return {
5281
+ changed: false,
5282
+ code: source
5283
+ };
5284
+ }
5285
+ /**
5286
+ * 判断文件是否属于项目源码或显式允许的 npm 包。
5287
+ */
5288
+ function isUniAppCompatibilityFile(filename, srcRoot, include) {
5289
+ const clean = filename.split("?", 1)[0];
5290
+ const relative = path.relative(srcRoot, clean);
5291
+ if (relative === "" || !relative.startsWith("..") && !path.isAbsolute(relative)) return true;
5292
+ const normalized = clean.replace(/\\/g, "/");
5293
+ return include.some((packageName) => {
5294
+ const packagePath = packageName.replace(/^\/+|\/+$/g, "");
5295
+ return normalized.includes(`/node_modules/${packagePath}/`);
5296
+ });
5297
+ }
5298
+ //#endregion
4954
5299
  //#region src/utils/text.ts
4955
5300
  const CRLF_RE = /\r\n?/g;
4956
5301
  /**
@@ -5302,9 +5647,214 @@ function getSfcCheckMtime(config) {
5302
5647
  return getReadFileCheckMtime(config);
5303
5648
  }
5304
5649
  //#endregion
5650
+ //#region src/plugins/vue/compiler/template/htmlTagMapping.ts
5651
+ const DEFAULT_HTML_TO_WXML_TAG_MAP = {
5652
+ a: "navigator",
5653
+ article: "view",
5654
+ aside: "view",
5655
+ b: "text",
5656
+ blockquote: "view",
5657
+ br: "view",
5658
+ button: "button",
5659
+ code: "text",
5660
+ dd: "view",
5661
+ div: "view",
5662
+ dl: "view",
5663
+ dt: "view",
5664
+ em: "text",
5665
+ figcaption: "view",
5666
+ figure: "view",
5667
+ footer: "view",
5668
+ form: "form",
5669
+ h1: "view",
5670
+ h2: "view",
5671
+ h3: "view",
5672
+ h4: "view",
5673
+ h5: "view",
5674
+ h6: "view",
5675
+ header: "view",
5676
+ hr: "view",
5677
+ i: "text",
5678
+ img: "image",
5679
+ input: "input",
5680
+ label: "label",
5681
+ li: "view",
5682
+ main: "view",
5683
+ nav: "view",
5684
+ ol: "view",
5685
+ p: "view",
5686
+ pre: "view",
5687
+ section: "view",
5688
+ small: "text",
5689
+ span: "text",
5690
+ strong: "text",
5691
+ table: "view",
5692
+ tbody: "view",
5693
+ td: "view",
5694
+ textarea: "textarea",
5695
+ tfoot: "view",
5696
+ th: "view",
5697
+ thead: "view",
5698
+ tr: "view",
5699
+ u: "text",
5700
+ ul: "view"
5701
+ };
5702
+ function resolveHtmlTagToWxmlMap(value) {
5703
+ if (value === false) return;
5704
+ if (value === true || value === void 0) return { ...DEFAULT_HTML_TO_WXML_TAG_MAP };
5705
+ return {
5706
+ ...DEFAULT_HTML_TO_WXML_TAG_MAP,
5707
+ ...Object.fromEntries(Object.entries(value).map(([key, mapped]) => [key.toLowerCase(), mapped]))
5708
+ };
5709
+ }
5710
+ function resolveTemplateTagName(tag, context) {
5711
+ if (!tag) return tag;
5712
+ const lowerTag = tag.toLowerCase();
5713
+ if (tag !== lowerTag) return tag;
5714
+ return context.htmlTagToWxmlMap?.[lowerTag] ?? tag;
5715
+ }
5716
+ function resolveMappedHtmlTagClassName(tag, context, resolvedTag) {
5717
+ if (!context.htmlTagToWxmlTagClass || !tag) return;
5718
+ const lowerTag = tag.toLowerCase();
5719
+ if (tag !== lowerTag) return;
5720
+ const mappedTag = context.htmlTagToWxmlMap?.[lowerTag];
5721
+ if (!mappedTag || (resolvedTag ?? mappedTag ?? tag) === lowerTag) return;
5722
+ return lowerTag;
5723
+ }
5724
+ //#endregion
5725
+ //#region src/plugins/vue/compiler/wxss.ts
5726
+ function findClosingParenthesis(source, openIndex) {
5727
+ let depth = 0;
5728
+ let quote;
5729
+ for (let index = openIndex; index < source.length; index += 1) {
5730
+ const char = source[index];
5731
+ if (quote) {
5732
+ if (char === quote && source[index - 1] !== "\\") quote = void 0;
5733
+ continue;
5734
+ }
5735
+ if (char === "\"" || char === "'") {
5736
+ quote = char;
5737
+ continue;
5738
+ }
5739
+ if (char === "(") depth += 1;
5740
+ else if (char === ")" && --depth === 0) return index;
5741
+ }
5742
+ return -1;
5743
+ }
5744
+ function findTopLevelComma(source) {
5745
+ let depth = 0;
5746
+ let quote;
5747
+ for (let index = 0; index < source.length; index += 1) {
5748
+ const char = source[index];
5749
+ if (quote) {
5750
+ if (char === quote && source[index - 1] !== "\\") quote = void 0;
5751
+ continue;
5752
+ }
5753
+ if (char === "\"" || char === "'") quote = char;
5754
+ else if (char === "(") depth += 1;
5755
+ else if (char === ")") depth -= 1;
5756
+ else if (char === "," && depth === 0) return index;
5757
+ }
5758
+ return -1;
5759
+ }
5760
+ function resolveWxssVarFallback(source) {
5761
+ const openIndex = source.indexOf("(");
5762
+ const closeIndex = openIndex >= 0 ? findClosingParenthesis(source, openIndex) : -1;
5763
+ if (openIndex < 0 || closeIndex < 0) return "initial";
5764
+ const content = source.slice(openIndex + 1, closeIndex);
5765
+ const commaIndex = findTopLevelComma(content);
5766
+ if (commaIndex < 0) return "initial";
5767
+ return flattenWxssVarFallbacks(content.slice(commaIndex + 1));
5768
+ }
5769
+ function flattenWxssVarFallbacks(source) {
5770
+ let result = "";
5771
+ let cursor = 0;
5772
+ while (cursor < source.length) {
5773
+ const varIndex = source.indexOf("var(", cursor);
5774
+ if (varIndex < 0) {
5775
+ result += source.slice(cursor);
5776
+ break;
5777
+ }
5778
+ result += source.slice(cursor, varIndex);
5779
+ const closeIndex = findClosingParenthesis(source, varIndex + 3);
5780
+ if (closeIndex < 0) {
5781
+ result += source.slice(varIndex);
5782
+ break;
5783
+ }
5784
+ result += resolveWxssVarFallback(source.slice(varIndex, closeIndex + 1));
5785
+ cursor = closeIndex + 1;
5786
+ }
5787
+ return result;
5788
+ }
5789
+ function lowerNestedWxssVarsInValue(source) {
5790
+ let result = "";
5791
+ let cursor = 0;
5792
+ let changed = false;
5793
+ while (cursor < source.length) {
5794
+ const varIndex = source.indexOf("var(", cursor);
5795
+ if (varIndex < 0) {
5796
+ result += source.slice(cursor);
5797
+ break;
5798
+ }
5799
+ result += source.slice(cursor, varIndex);
5800
+ const closeIndex = findClosingParenthesis(source, varIndex + 3);
5801
+ if (closeIndex < 0) {
5802
+ result += source.slice(varIndex);
5803
+ break;
5804
+ }
5805
+ const functionSource = source.slice(varIndex, closeIndex + 1);
5806
+ const content = functionSource.slice(4, -1);
5807
+ const commaIndex = findTopLevelComma(content);
5808
+ if (commaIndex >= 0 && content.slice(commaIndex + 1).includes("var(")) {
5809
+ const name = content.slice(0, commaIndex).trim();
5810
+ const fallback = flattenWxssVarFallbacks(content.slice(commaIndex + 1)).trim();
5811
+ result += `var(${name}, ${fallback})`;
5812
+ changed = true;
5813
+ } else result += functionSource;
5814
+ cursor = closeIndex + 1;
5815
+ }
5816
+ return changed ? result : source;
5817
+ }
5818
+ /**
5819
+ * 压平 WXSS 不接受的嵌套 CSS 变量回退值。
5820
+ */
5821
+ function transformNestedWxssVars(source) {
5822
+ if (!source.includes("var(")) return source;
5823
+ const root = postcss.parse(source);
5824
+ root.walkDecls((declaration) => {
5825
+ declaration.value = lowerNestedWxssVarsInValue(declaration.value);
5826
+ });
5827
+ return root.toString();
5828
+ }
5829
+ //#endregion
5305
5830
  //#region src/plugins/vue/compiler/style.ts
5306
5831
  const CSS_RULE_RE = /([^{]+)(\{[^}]*\})/g;
5307
5832
  const CSS_CLASS_RE = /\.([a-z_][\w-]*)(?:\[[^\]]+\])?\s*\{/gi;
5833
+ function transformVueDeepSelectors(source) {
5834
+ if (!source.includes(":deep") && !source.includes("::v-deep")) return source;
5835
+ const root = postcss.parse(source);
5836
+ const processor = selectorParser((selectors) => {
5837
+ selectors.walkTags((tag) => {
5838
+ const name = tag.value.toLowerCase();
5839
+ if (DEFAULT_HTML_TO_WXML_TAG_MAP[name] !== name && DEFAULT_HTML_TO_WXML_TAG_MAP[name]) tag.replaceWith(selectorParser.className({ value: name }));
5840
+ });
5841
+ selectors.walkPseudos((pseudo) => {
5842
+ if (pseudo.value !== ":deep" && pseudo.value !== "::v-deep") return;
5843
+ const replacement = pseudo.nodes?.[0]?.nodes.map((node) => node.clone()) ?? [];
5844
+ if (replacement.length > 0) pseudo.replaceWith(...replacement);
5845
+ else {
5846
+ const previous = pseudo.prev();
5847
+ const next = pseudo.next();
5848
+ if (next?.type === "combinator" && (!previous || previous.type === "combinator")) next.remove();
5849
+ pseudo.remove();
5850
+ }
5851
+ });
5852
+ });
5853
+ root.walkRules((rule) => {
5854
+ if (rule.selector.includes(":deep") || rule.selector.includes("::v-deep")) rule.selector = processor.processSync(rule.selector);
5855
+ });
5856
+ return root.toString();
5857
+ }
5308
5858
  /**
5309
5859
  * 转换 scoped CSS
5310
5860
  * 为每个选择器添加特定的 scoped 属性
@@ -5365,18 +5915,18 @@ function transformCssModules(source, id) {
5365
5915
  * 将 Vue SFC 的 style 块转换为 WXSS
5366
5916
  */
5367
5917
  function compileVueStyleToWxss(styleBlock, options) {
5368
- const { id, scoped, modules } = options;
5918
+ const { id, scoped, modules, preserveDeepSelectors, transformScoped = true } = options;
5369
5919
  let code = styleBlock.content;
5370
- if (scoped || styleBlock.scoped) code = transformScopedCss(code, id);
5920
+ if (transformScoped && (scoped || styleBlock.scoped)) code = transformScopedCss(code, id);
5371
5921
  if (modules || styleBlock.module) {
5372
5922
  const moduleName = typeof styleBlock.module === "string" ? styleBlock.module : "$style";
5373
5923
  const moduleResult = transformCssModules(code, id);
5374
5924
  return {
5375
- code: moduleResult.code,
5925
+ code: preserveDeepSelectors ? moduleResult.code : transformVueDeepSelectors(moduleResult.code),
5376
5926
  modules: { [moduleName]: moduleResult.classes }
5377
5927
  };
5378
5928
  }
5379
- return { code };
5929
+ return { code: preserveDeepSelectors ? code : transformVueDeepSelectors(code) };
5380
5930
  }
5381
5931
  //#endregion
5382
5932
  //#region src/plugins/vue/compiler/template/classStyleRuntime.ts
@@ -5637,74 +6187,6 @@ function getClassStyleWxsSource(options = {}) {
5637
6187
  ].join("\n");
5638
6188
  }
5639
6189
  //#endregion
5640
- //#region src/plugins/vue/compiler/template/htmlTagMapping.ts
5641
- const DEFAULT_HTML_TO_WXML_TAG_MAP = {
5642
- a: "navigator",
5643
- article: "view",
5644
- aside: "view",
5645
- b: "text",
5646
- blockquote: "view",
5647
- br: "view",
5648
- button: "button",
5649
- code: "text",
5650
- dd: "view",
5651
- div: "view",
5652
- dl: "view",
5653
- dt: "view",
5654
- em: "text",
5655
- figcaption: "view",
5656
- figure: "view",
5657
- footer: "view",
5658
- form: "form",
5659
- h1: "view",
5660
- h2: "view",
5661
- h3: "view",
5662
- h4: "view",
5663
- h5: "view",
5664
- h6: "view",
5665
- header: "view",
5666
- hr: "view",
5667
- i: "text",
5668
- img: "image",
5669
- input: "input",
5670
- label: "label",
5671
- li: "view",
5672
- main: "view",
5673
- nav: "view",
5674
- ol: "view",
5675
- p: "view",
5676
- pre: "view",
5677
- section: "view",
5678
- small: "text",
5679
- span: "text",
5680
- strong: "text",
5681
- textarea: "textarea",
5682
- u: "text",
5683
- ul: "view"
5684
- };
5685
- function resolveHtmlTagToWxmlMap(value) {
5686
- if (value === false) return;
5687
- if (value === true || value === void 0) return { ...DEFAULT_HTML_TO_WXML_TAG_MAP };
5688
- return {
5689
- ...DEFAULT_HTML_TO_WXML_TAG_MAP,
5690
- ...Object.fromEntries(Object.entries(value).map(([key, mapped]) => [key.toLowerCase(), mapped]))
5691
- };
5692
- }
5693
- function resolveTemplateTagName(tag, context) {
5694
- if (!tag) return tag;
5695
- const lowerTag = tag.toLowerCase();
5696
- if (tag !== lowerTag) return tag;
5697
- return context.htmlTagToWxmlMap?.[lowerTag] ?? tag;
5698
- }
5699
- function resolveMappedHtmlTagClassName(tag, context, resolvedTag) {
5700
- if (!context.htmlTagToWxmlTagClass || !tag) return;
5701
- const lowerTag = tag.toLowerCase();
5702
- if (tag !== lowerTag) return;
5703
- const mappedTag = context.htmlTagToWxmlMap?.[lowerTag];
5704
- if (!mappedTag || (resolvedTag ?? mappedTag ?? tag) === lowerTag) return;
5705
- return lowerTag;
5706
- }
5707
- //#endregion
5708
6190
  //#region src/plugins/vue/compiler/template/elements/forExpression.ts
5709
6191
  const IDENTIFIER_RE$5 = /^[A-Z_$][\w$]*$/i;
5710
6192
  const FOR_ITEM_ALIAS_PLACEHOLDER = "__wv_for_item__";
@@ -6061,6 +6543,7 @@ const SCOPED_SLOT_GLOBALS = /* @__PURE__ */ new Set([
6061
6543
  "encodeURIComponent",
6062
6544
  "require",
6063
6545
  "arguments",
6546
+ "vueSlots",
6064
6547
  WEVU_SLOT_OWNER_KEY,
6065
6548
  WEVU_SLOT_PROPS_KEY,
6066
6549
  WEVU_SLOT_PROPS_DATA_KEY,
@@ -6523,19 +7006,6 @@ const JS_RUNTIME_GLOBALS = /* @__PURE__ */ new Set([
6523
7006
  "getCurrentPages",
6524
7007
  ...getMiniProgramRuntimeGlobalKeys()
6525
7008
  ]);
6526
- function parseJsExpressionFile(exp) {
6527
- try {
6528
- const ast = parseJsLike(`(${exp})`);
6529
- const stmt = ast.program.body[0];
6530
- if (!stmt || !("expression" in stmt)) return null;
6531
- return {
6532
- ast,
6533
- expression: stmt.expression
6534
- };
6535
- } catch {
6536
- return null;
6537
- }
6538
- }
6539
7009
  function createMemberAccess(target, prop) {
6540
7010
  if (!prop) return target;
6541
7011
  if (t.isValidIdentifier(prop)) return t.memberExpression(target, t.identifier(prop));
@@ -6589,11 +7059,8 @@ function createIdentifierAccessWithPropsFallback(name, context, useRuntimePropHe
6589
7059
  const hasUsablePropsValue = t.logicalExpression("&&", hasPropsObject, t.logicalExpression("||", hasDefinedPropsValue, hasPropsKey));
6590
7060
  const hasStateObject = t.binaryExpression("!=", stateObject, t.nullLiteral());
6591
7061
  const hasStateKey = createHasOwnPropertyCall(stateObject, name);
6592
- const hasThisMember = t.binaryExpression("in", t.stringLiteral(name), t.thisExpression());
6593
- const isPropsDerivedKey = Boolean(context.propsDerivedKeys?.includes(name));
6594
- const shouldUseStateAccess = isPropsDerivedKey ? t.booleanLiteral(false) : t.logicalExpression("&&", hasStateObject, hasStateKey);
6595
- const shouldUsePropsAccess = t.logicalExpression("&&", hasUsablePropsValue, isPropsDerivedKey ? t.booleanLiteral(true) : t.unaryExpression("!", hasThisMember));
6596
- return t.conditionalExpression(shouldUseStateAccess, thisAccess, t.conditionalExpression(shouldUsePropsAccess, propsAccess, thisAccess));
7062
+ const shouldUseStateAccess = Boolean(context.propsDerivedKeys?.includes(name)) ? t.booleanLiteral(false) : t.logicalExpression("&&", hasStateObject, hasStateKey);
7063
+ return t.conditionalExpression(shouldUseStateAccess, thisAccess, t.conditionalExpression(hasUsablePropsValue, propsAccess, thisAccess));
6597
7064
  }
6598
7065
  function createAliasedPropsAccess(name, propName) {
6599
7066
  return createResolvePropValueCall(propName, createThisMemberAccess(name), true);
@@ -6625,7 +7092,7 @@ function shouldUnrefMemberAccess(node, parent) {
6625
7092
  function normalizeJsExpressionWithContext(exp, context, options) {
6626
7093
  const trimmed = exp.trim();
6627
7094
  if (!trimmed) return null;
6628
- const parsed = parseJsExpressionFile(normalizeWxmlExpression(trimmed));
7095
+ const parsed = parseBabelExpressionFile(normalizeWxmlExpression(trimmed));
6629
7096
  if (!parsed) {
6630
7097
  const hint = options?.hint ? `${options.hint} ` : "";
6631
7098
  context.warnings.push(`${hint}模板表达式解析失败,已忽略:${exp}`);
@@ -6707,6 +7174,11 @@ function shouldFallbackToRuntimeBinding(exp) {
6707
7174
  OptionalCallExpression(path) {
6708
7175
  shouldFallback = true;
6709
7176
  path.stop();
7177
+ },
7178
+ UnaryExpression(path) {
7179
+ if (path.node.operator !== "typeof") return;
7180
+ shouldFallback = true;
7181
+ path.stop();
6710
7182
  }
6711
7183
  });
6712
7184
  return shouldFallback;
@@ -6928,7 +7400,9 @@ function createBindRuntimeAttr(argValue, rawExpValue, context) {
6928
7400
  return `${argValue}="${renderMustache(bindingRef, context)}"`;
6929
7401
  }
6930
7402
  function createInlineObjectLiteralAttr(argValue, rawExpValue, context) {
6931
- const expValue = normalizeWxmlExpressionWithContext(rawExpValue, context).trim();
7403
+ const normalized = normalizeWxmlExpressionWithContext(rawExpValue, context).trim();
7404
+ const parsed = parseBabelExpression(normalized);
7405
+ const expValue = parsed ? generateExpression(parsed) : normalized;
6932
7406
  if (context.mustacheInterpolation === "spaced") return `${argValue}="${renderMustache(expValue, context)}"`;
6933
7407
  return `${argValue}="{{ ${expValue} }}"`;
6934
7408
  }
@@ -7429,6 +7903,29 @@ function collectElementAttributes(node, context, options) {
7429
7903
  //#region src/plugins/vue/compiler/template/elements/slotProps.ts
7430
7904
  const BACKSLASH_RE = /\\/g;
7431
7905
  const SINGLE_QUOTE_RE = /'/g;
7906
+ function isFunctionBindingExpression(exp) {
7907
+ try {
7908
+ const stmt = parse$3(`(${exp})`, {
7909
+ sourceType: "module",
7910
+ plugins: ["typescript"]
7911
+ }).program.body[0];
7912
+ const expression = stmt && "expression" in stmt ? stmt.expression : void 0;
7913
+ return t.isArrowFunctionExpression(expression) || t.isFunctionExpression(expression);
7914
+ } catch {
7915
+ return false;
7916
+ }
7917
+ }
7918
+ function createSlotFunctionBinding(exp, context) {
7919
+ if (!isFunctionBindingExpression(exp)) return null;
7920
+ const inline = registerInlineExpression(`(${exp})(...$event)`, context);
7921
+ if (!inline) {
7922
+ context.warnings.push("作用域插槽函数参数编译失败。");
7923
+ return null;
7924
+ }
7925
+ const scopeBindings = `[${inline.scopeBindings.join(",")}]`;
7926
+ const indexBindings = `[${inline.indexBindings.join(",")}]`;
7927
+ return `[${toWxmlStringLiteral$1(WEVU_SLOT_FUNCTION_TOKEN)},${toWxmlStringLiteral$1(inline.id)},${scopeBindings},${indexBindings}]`;
7928
+ }
7432
7929
  function parseSlotPropsExpression(exp, context) {
7433
7930
  const trimmed = exp.trim();
7434
7931
  if (!trimmed) return {};
@@ -7488,7 +7985,7 @@ function collectSlotBindingExpression(node, context) {
7488
7985
  if (prop.arg.content === "name" || hasForDirective && prop.arg.content === "key") continue;
7489
7986
  if (rawExpValue) namedBindings.push({
7490
7987
  key: prop.arg.content,
7491
- value: normalizeWxmlExpressionWithContext(rawExpValue, context)
7988
+ value: createSlotFunctionBinding(rawExpValue, context) ?? normalizeWxmlExpressionWithContext(rawExpValue, context)
7492
7989
  });
7493
7990
  continue;
7494
7991
  }
@@ -7612,6 +8109,8 @@ function createScopedSlotComponent(context, slotKey, props, children, transformN
7612
8109
  forIndexSeed: 0,
7613
8110
  inlineExpressions: [],
7614
8111
  inlineExpressionSeed: 0,
8112
+ templateRefs: [],
8113
+ templateRefIndexSeed: 0,
7615
8114
  functionPropPaths: /* @__PURE__ */ new Set(),
7616
8115
  functionPropNames: context.functionPropNames
7617
8116
  };
@@ -7627,6 +8126,7 @@ function createScopedSlotComponent(context, slotKey, props, children, transformN
7627
8126
  asset.classStyleBindings = scopedContext.classStyleBindings.length ? scopedContext.classStyleBindings : void 0;
7628
8127
  asset.classStyleWxs = scopedContext.classStyleWxs || void 0;
7629
8128
  asset.inlineExpressions = scopedContext.inlineExpressions.length ? scopedContext.inlineExpressions : void 0;
8129
+ asset.templateRefs = scopedContext.templateRefs.length ? scopedContext.templateRefs : void 0;
7630
8130
  return {
7631
8131
  componentName,
7632
8132
  slotKey
@@ -7835,7 +8335,8 @@ function transformSlotElement(node, context, transformNode) {
7835
8335
  ];
7836
8336
  if (context.slotMultipleInstance) scopedAttrs.push(`${WEVU_SLOT_SCOPE_ATTR}="${renderMustache(WEVU_SLOT_SCOPE_KEY, context)}"`);
7837
8337
  const scopedTag = `<${genericKey}${scopedAttrs.length ? ` ${scopedAttrs.join(" ")}` : ""} />`;
7838
- const projectedContent = hasScopeBindings ? `${slotTag}${scopedTag}` : `${scopedTag}${context.platform.wrapElse(slotTag)}`;
8338
+ const nativeFallbackTag = context.forStack.length > 0 ? "" : context.platform.wrapIf(`!${WEVU_SLOT_OWNER_ID_PROP}`, slotTag, (exp) => renderMustache(exp, context));
8339
+ const projectedContent = hasScopeBindings ? `${scopedTag}${nativeFallbackTag}` : `${scopedTag}${context.platform.wrapElse(slotTag)}`;
7839
8340
  if (fallbackContent && slotPresentExp) return `${context.platform.wrapIf(slotPresentExp, projectedContent, (exp) => renderMustache(exp, context))}${context.platform.wrapElse(fallbackContent)}`;
7840
8341
  return projectedContent;
7841
8342
  }
@@ -7875,6 +8376,15 @@ function hasDirectWevuComponentSlotChild(children, context) {
7875
8376
  return isWevuComponentTag(element, context);
7876
8377
  });
7877
8378
  }
8379
+ function hasExplicitWevuComponentSlotDescendant(children, context) {
8380
+ if (!context.wevuComponentTags?.size) return false;
8381
+ return children.some((child) => {
8382
+ if (child.type !== NodeTypes.ELEMENT) return false;
8383
+ const element = child;
8384
+ if (element.tag !== "template" && !isBuiltinTag(resolveTemplateTagName(element.tag, context)) && context.wevuComponentTags.has(element.tag)) return true;
8385
+ return hasExplicitWevuComponentSlotDescendant(element.children, context);
8386
+ });
8387
+ }
7878
8388
  function hasMiniProgramComponentSlotDescendant(children, context) {
7879
8389
  const componentTags = context.miniProgramComponentTags;
7880
8390
  if (!componentTags?.size) return false;
@@ -7893,16 +8403,24 @@ function hasNativeComponentSlotDescendant(children, context) {
7893
8403
  return hasNativeComponentSlotDescendant(element.children, context);
7894
8404
  });
7895
8405
  }
8406
+ function hasForwardedSlotOutlet(children) {
8407
+ return children.some((child) => {
8408
+ if (child.type !== NodeTypes.ELEMENT) return false;
8409
+ const element = child;
8410
+ return element.tag === "slot" || hasForwardedSlotOutlet(element.children);
8411
+ });
8412
+ }
7896
8413
  function shouldAugmentPlainSlot(decl, context, ownerNode, hasScopedSlotPropsSibling) {
7897
8414
  if (context.scopedSlotsRequireProps) return false;
8415
+ if (hasForwardedSlotOutlet(decl.children)) return false;
7898
8416
  if (context.rewriteScopedSlot && !isWevuComponentTag(ownerNode, context)) return false;
7899
8417
  if (context.rewriteScopedSlot) {
7900
8418
  if (context.scopedSlotsCompiler === "augmented" && !decl.implicitDefault) return true;
7901
- return context.scopedSlotsCompiler === "augmented" ? hasMiniProgramComponentSlotDescendant(decl.children, context) : hasScopedSlotPropsSibling && hasDirectComponentSlotChild(decl.children, context);
8419
+ return context.scopedSlotsCompiler === "augmented" ? hasMiniProgramComponentSlotDescendant(decl.children, context) || hasExplicitWevuComponentSlotDescendant(decl.children, context) : hasScopedSlotPropsSibling && hasDirectComponentSlotChild(decl.children, context);
7902
8420
  }
7903
8421
  if (context.scopedSlotsCompiler === "augmented") {
7904
8422
  if (!decl.implicitDefault) return true;
7905
- return hasMiniProgramComponentSlotDescendant(decl.children, context) || !isWevuComponentTag(ownerNode, context) && hasNativeComponentSlotDescendant(decl.children, context);
8423
+ return hasMiniProgramComponentSlotDescendant(decl.children, context) || hasExplicitWevuComponentSlotDescendant(decl.children, context) || !isWevuComponentTag(ownerNode, context) && hasNativeComponentSlotDescendant(decl.children, context);
7906
8424
  }
7907
8425
  if (!isWevuComponentTag(ownerNode, context)) return false;
7908
8426
  return hasScopedSlotPropsSibling || hasDirectWevuComponentSlotChild(decl.children, context);
@@ -8146,7 +8664,7 @@ function transformComponentWithSlots(node, context, transformNode, options) {
8146
8664
  if (scopedSlotDeclarations.length) {
8147
8665
  const scopePropsExp = buildScopePropsExpression(context);
8148
8666
  if (scopePropsExp) mergedAttrs.push(`${WEVU_SLOT_SCOPE_ATTR}="${renderMustache(scopePropsExp, context)}"`);
8149
- const ownerIdExp = context.rewriteScopedSlot ? `${WEVU_SLOT_OWNER_ID_PROP} || ${WEVU_SLOT_OWNER_ID_KEY} || ''` : `${WEVU_SLOT_OWNER_ID_PROP} || ${WEVU_SLOT_OWNER_ID_KEY} || ''`;
8667
+ const ownerIdExp = context.rewriteScopedSlot ? `${WEVU_SLOT_OWNER_ID_PROP} || ${WEVU_SLOT_OWNER_ID_KEY} || ''` : `${WEVU_SLOT_OWNER_ID_KEY} || ''`;
8150
8668
  mergedAttrs.push(`${WEVU_SLOT_OWNER_ID_ATTR}="${renderMustache(ownerIdExp, context)}"`);
8151
8669
  }
8152
8670
  const attrString = mergedAttrs.length ? ` ${mergedAttrs.join(" ")}` : "";
@@ -8686,6 +9204,12 @@ function isVueSfcSource(source) {
8686
9204
  function pascalToKebab(name) {
8687
9205
  return name.replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1-$2").toLowerCase();
8688
9206
  }
9207
+ function kebabToCamel(name) {
9208
+ return name.replace(/-([a-z0-9])/g, (_, character) => character.toUpperCase());
9209
+ }
9210
+ function capitalize(name) {
9211
+ return name ? `${name.charAt(0).toUpperCase()}${name.slice(1)}` : name;
9212
+ }
8689
9213
  function extractStringPropertyFromObject(node, keyName) {
8690
9214
  for (const property of node.properties) {
8691
9215
  if (!t.isObjectProperty(property)) continue;
@@ -8790,24 +9314,41 @@ function mergeComponentSourceInfo(target, source) {
8790
9314
  }
8791
9315
  function collectTemplateComponentTagInfo(template, filename, warn) {
8792
9316
  const warnHandler = resolveWarnHandler(warn);
8793
- const tags = collectVueTemplateTags(template, {
9317
+ const autoImportTags = collectVueTemplateTags(template, {
8794
9318
  filename,
8795
9319
  warnLabel: "组件标签",
8796
9320
  warn: (message) => warnHandler(message),
8797
9321
  shouldCollect: isAutoImportCandidateTag
8798
9322
  });
8799
- const componentNames = new Set(tags);
8800
- for (const tag of tags) if (tag.includes("-")) {
8801
- const pascalName = tag.split("-").filter(Boolean).map((segment) => `${segment.charAt(0).toUpperCase()}${segment.slice(1)}`).join("");
8802
- if (pascalName) componentNames.add(pascalName);
9323
+ const templateTags = collectVueTemplateTags(template, {
9324
+ filename,
9325
+ warnLabel: "脚本导入组件标签",
9326
+ warn: (message) => warnHandler(message),
9327
+ shouldCollect: () => true
9328
+ });
9329
+ const componentNames = /* @__PURE__ */ new Set();
9330
+ const tagsByComponentName = /* @__PURE__ */ new Map();
9331
+ for (const tag of templateTags) {
9332
+ const camelName = kebabToCamel(tag);
9333
+ for (const componentName of [
9334
+ tag,
9335
+ camelName,
9336
+ capitalize(camelName)
9337
+ ]) {
9338
+ componentNames.add(componentName);
9339
+ const matchedTags = tagsByComponentName.get(componentName) ?? /* @__PURE__ */ new Set();
9340
+ matchedTags.add(tag);
9341
+ tagsByComponentName.set(componentName, matchedTags);
9342
+ }
8803
9343
  }
8804
9344
  return {
8805
- autoImportTags: tags,
8806
- componentNames
9345
+ autoImportTags,
9346
+ componentNames,
9347
+ tagsByComponentName
8807
9348
  };
8808
9349
  }
8809
9350
  async function collectScriptSetupUsingComponents(options) {
8810
- const { descriptor, descriptorForCompile, filename, compileOptions, autoUsingComponents, templateComponentNames, result } = options;
9351
+ const { descriptor, descriptorForCompile, filename, compileOptions, autoUsingComponents, templateComponentNames, templateTagsByComponentName, result } = options;
8811
9352
  if (!descriptor.scriptSetup || !descriptor.template) return;
8812
9353
  if (!templateComponentNames?.size) return;
8813
9354
  try {
@@ -8822,11 +9363,13 @@ async function collectScriptSetupUsingComponents(options) {
8822
9363
  if (!("local" in specifier) || !t.isIdentifier(specifier.local)) continue;
8823
9364
  const localName = specifier.local.name;
8824
9365
  if (!templateComponentNames.has(localName)) continue;
9366
+ const templateTags = [...templateTagsByComponentName?.get(localName) ?? [localName]];
8825
9367
  if (t.isImportDefaultSpecifier(specifier)) pending.push({
8826
9368
  localName,
8827
9369
  importSource,
8828
9370
  importedName: "default",
8829
- kind: "default"
9371
+ kind: "default",
9372
+ templateTags
8830
9373
  });
8831
9374
  else if (t.isImportSpecifier(specifier)) {
8832
9375
  const importedName = t.isIdentifier(specifier.imported) ? specifier.imported.name : t.isStringLiteral(specifier.imported) ? specifier.imported.value : void 0;
@@ -8834,12 +9377,13 @@ async function collectScriptSetupUsingComponents(options) {
8834
9377
  localName,
8835
9378
  importSource,
8836
9379
  importedName,
8837
- kind: "named"
9380
+ kind: "named",
9381
+ templateTags
8838
9382
  });
8839
9383
  }
8840
9384
  }
8841
9385
  } });
8842
- const resolvedComponents = await Promise.all(pending.map(async ({ localName, importSource, importedName, kind }) => {
9386
+ const resolvedComponents = await Promise.all(pending.map(async ({ localName, importSource, importedName, kind, templateTags }) => {
8843
9387
  let resolved = autoUsingComponents?.resolveUsingComponentPath ? normalizeResolvedUsingComponent(await autoUsingComponents.resolveUsingComponentPath(importSource, filename, {
8844
9388
  localName,
8845
9389
  importedName,
@@ -8861,12 +9405,13 @@ async function collectScriptSetupUsingComponents(options) {
8861
9405
  localName,
8862
9406
  importSource,
8863
9407
  resolved,
8864
- componentMeta
9408
+ componentMeta,
9409
+ templateTags
8865
9410
  };
8866
9411
  }));
8867
- for (const { localName, importSource, resolved, componentMeta } of resolvedComponents) {
9412
+ for (const { localName, importSource, resolved, componentMeta, templateTags } of resolvedComponents) {
8868
9413
  if (resolved?.from) {
8869
- result.autoUsingComponentsMap[localName] = resolved.from;
9414
+ for (const tag of templateTags) result.autoUsingComponentsMap[tag] = resolved.from;
8870
9415
  result.autoComponentMeta[localName] = resolved.from;
8871
9416
  }
8872
9417
  if (isVueSfcSource(importSource) || isWevuSfcComponent(resolved)) {
@@ -8874,7 +9419,9 @@ async function collectScriptSetupUsingComponents(options) {
8874
9419
  result.wevuComponentTags.add(pascalToKebab(localName));
8875
9420
  }
8876
9421
  registerComponentName(result, localName, componentMeta.componentName);
9422
+ for (const tag of templateTags) registerComponentName(result, tag, componentMeta.componentName);
8877
9423
  registerMiniProgramComponentTag(result, localName, componentMeta.isMiniProgramComponent);
9424
+ for (const tag of templateTags) registerMiniProgramComponentTag(result, tag, componentMeta.isMiniProgramComponent);
8878
9425
  }
8879
9426
  } catch (error) {
8880
9427
  const message = error instanceof Error ? error.message : String(error);
@@ -8929,6 +9476,7 @@ async function collectComponentSourceInfo(options) {
8929
9476
  compileOptions: options.compileOptions,
8930
9477
  autoUsingComponents: options.autoUsingComponents,
8931
9478
  templateComponentNames: templateComponentTagInfo?.componentNames,
9479
+ templateTagsByComponentName: templateComponentTagInfo?.tagsByComponentName,
8932
9480
  result: scriptSetupResult
8933
9481
  }), collectAutoImportWevuComponents({
8934
9482
  descriptor: options.descriptor,
@@ -9878,7 +10426,8 @@ async function compileScriptPhase(descriptor, descriptorForCompile, filename, op
9878
10426
  } else scriptCode = "export default {}";
9879
10427
  if (scriptCode) {
9880
10428
  const transformed = transformScript(scriptCode, {
9881
- skipComponentTransform: isAppFile,
10429
+ isTypeScript: descriptor.script?.lang === "ts" || descriptor.script?.lang === "tsx" || descriptor.scriptSetup?.lang === "ts" || descriptor.scriptSetup?.lang === "tsx",
10430
+ skipComponentTransform: options?.skipComponentTransform ?? isAppFile,
9882
10431
  isApp: isAppFile,
9883
10432
  isPage: options?.isPage === true,
9884
10433
  minify: options?.minify,
@@ -9924,14 +10473,16 @@ function generateScopedId(filename) {
9924
10473
  }
9925
10474
  //#endregion
9926
10475
  //#region src/plugins/vue/transform/compileVueFile/style.ts
9927
- function compileStylePhase(descriptor, filename, result) {
10476
+ function compileStylePhase(descriptor, filename, result, options) {
9928
10477
  if (descriptor.styles.length === 0) return;
9929
10478
  const scopedId = generateScopedId(filename);
9930
10479
  const compiledStyles = descriptor.styles.map((styleBlock) => {
9931
10480
  return compileVueStyleToWxss(styleBlock, {
9932
10481
  id: scopedId,
9933
10482
  scoped: styleBlock.scoped,
9934
- modules: styleBlock.module
10483
+ modules: styleBlock.module,
10484
+ preserveDeepSelectors: options?.preserveDeepSelectors,
10485
+ transformScoped: options?.transformScoped
9935
10486
  });
9936
10487
  });
9937
10488
  result.style = compiledStyles.map((s) => s.code.trim()).filter(Boolean).join("\n\n");
@@ -10057,7 +10608,7 @@ async function compileVueFile(source, filename, options) {
10057
10608
  });
10058
10609
  result.script = scriptPhase.script;
10059
10610
  result.scriptMap = scriptPhase.scriptMap;
10060
- compileStylePhase(parsed.descriptor, filename, result);
10611
+ compileStylePhase(parsed.descriptor, filename, result, options?.style);
10061
10612
  await compileConfigPhase({
10062
10613
  descriptor: parsed.descriptor,
10063
10614
  filename,
@@ -10082,4 +10633,4 @@ async function compileVueFile(source, filename, options) {
10082
10633
  return result;
10083
10634
  }
10084
10635
  //#endregion
10085
- export { CLASS_STYLE_WXS_FILE, CLASS_STYLE_WXS_MODULE, RESERVED_VUE_COMPONENT_TAGS, VUE_COMPONENT_TAG_RE, WE_VU_COMPILER_REACTIVITY_MODULE_ID, WE_VU_COMPILER_RUNTIME_MODULE_ID, WE_VU_COMPILER_TEMPLATE_MODULE_ID, WE_VU_INTERNAL_REACTIVITY_APIS, WE_VU_INTERNAL_REACTIVITY_MODULE_ID, WE_VU_INTERNAL_RUNTIME_MODULE_ID, WE_VU_INTERNAL_TEMPLATE_APIS, WE_VU_INTERNAL_TEMPLATE_MODULE_ID, WE_VU_MODULE_ID, WE_VU_PAGE_HOOK_TO_FEATURE, WE_VU_RUNTIME_APIS, WE_VU_RUNTIME_MODULE_IDS, alipayPlatform, buildClassStyleComputedCode, buildClassStyleWxsTag, builtinComponentsSet, clearFileCaches, collectTargetOptionsObjectsFromCode, collectVueTemplateTags, collectWevuFeaturesFromCodeReachableImports, collectWevuPageFeatureFlags, collectWevuPageFeatureFlagsFromCode, compileConfigBlocks, compileJsxFile, compileVueFile as compileSfc, compileVueFile, compileVueStyleToWxss as compileStyle, compileVueStyleToWxss, compileVueTemplateToWxml as compileTemplate, compileVueTemplateToWxml, createJsonMerger, createPageEntryMatcher, defaultMiniProgramPlatform, defaultMiniProgramTemplatePlatform, defaultPlatform, evaluateJsLikeConfig, extractJsonMacroFromScriptSetup, generateScopedId, getClassStyleWxsSource, getDefaultMiniProgramPlatform, getDefaultMiniProgramTemplatePlatform, getMiniProgramTemplatePlatform, getSfcCheckMtime, injectWevuPageFeatureFlagsIntoOptionsObject, injectWevuPageFeaturesInJs, injectWevuPageFeaturesInJsWithResolver, invalidateFileCache, isAutoImportCandidateTag, isBuiltinComponent, isInvalidate, isJsonLikeLang, isWevuRuntimeModuleId, loadCache, mayContainJsonMacro, mergeJsonWithStrategy, mtimeCache, normalizeConfigLang, pathExists, preprocessScriptSetupSrc, preprocessScriptSrc, readAndParseSfc, readFile, refreshVueFileJsonConfig, resolveClassStyleWxsLocation, resolveJsLikeLang, resolveSfcBlockSrc, resolveWevuInternalImportModuleId, restoreScriptSetupSrc, restoreScriptSrc, stripJsonMacroCallsFromCode, swanPlatform, transformScript, transformScript as transformSfcScript, ttPlatform, wechatPlatform };
10636
+ export { CLASS_STYLE_WXS_FILE, CLASS_STYLE_WXS_MODULE, RESERVED_VUE_COMPONENT_TAGS, VUE_COMPONENT_TAG_RE, WE_VU_COMPILER_REACTIVITY_MODULE_ID, WE_VU_COMPILER_RUNTIME_MODULE_ID, WE_VU_COMPILER_TEMPLATE_MODULE_ID, WE_VU_INTERNAL_REACTIVITY_APIS, WE_VU_INTERNAL_REACTIVITY_MODULE_ID, WE_VU_INTERNAL_RUNTIME_MODULE_ID, WE_VU_INTERNAL_TEMPLATE_APIS, WE_VU_INTERNAL_TEMPLATE_MODULE_ID, WE_VU_MODULE_ID, WE_VU_PAGE_HOOK_TO_FEATURE, WE_VU_RUNTIME_APIS, WE_VU_RUNTIME_MODULE_IDS, alipayPlatform, buildClassStyleComputedCode, buildClassStyleWxsTag, builtinComponentsSet, clearFileCaches, collectTargetOptionsObjectsFromCode, collectVueTemplateTags, collectWevuFeaturesFromCodeReachableImports, collectWevuPageFeatureFlags, collectWevuPageFeatureFlagsFromCode, compileConfigBlocks, compileJsxFile, compileVueFile as compileSfc, compileVueFile, compileVueStyleToWxss as compileStyle, compileVueStyleToWxss, compileVueTemplateToWxml as compileTemplate, compileVueTemplateToWxml, createJsonMerger, createPageEntryMatcher, defaultMiniProgramPlatform, defaultMiniProgramTemplatePlatform, defaultPlatform, evaluateJsLikeConfig, extractJsonMacroFromScriptSetup, generateScopedId, getClassStyleWxsSource, getDefaultMiniProgramPlatform, getDefaultMiniProgramTemplatePlatform, getMiniProgramTemplatePlatform, getSfcCheckMtime, injectWevuPageFeatureFlagsIntoOptionsObject, injectWevuPageFeaturesInJs, injectWevuPageFeaturesInJsWithResolver, invalidateFileCache, isAutoImportCandidateTag, isBuiltinComponent, isInvalidate, isJsonLikeLang, isUniAppCompatibilityFile, isWevuRuntimeModuleId, loadCache, mayContainJsonMacro, mergeJsonWithStrategy, mtimeCache, normalizeConfigLang, pathExists, preprocessScriptSetupSrc, preprocessScriptSrc, readAndParseSfc, readFile, refreshVueFileJsonConfig, resolveClassStyleWxsLocation, resolveJsLikeLang, resolveSfcBlockSrc, resolveWevuInternalImportModuleId, restoreScriptSetupSrc, restoreScriptSrc, stripJsonMacroCallsFromCode, swanPlatform, transformNestedWxssVars, transformScript, transformScript as transformSfcScript, transformUniAppConditionalCode, transformUniAppSource, transformVueDeepSelectors, ttPlatform, wechatPlatform };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@wevu/compiler",
3
3
  "type": "module",
4
- "version": "6.18.7",
4
+ "version": "6.19.0",
5
5
  "description": "wevu 编译器基础包,面向小程序模板的编译与转换",
6
6
  "author": "ice breaker <1324318532@qq.com>",
7
7
  "license": "MIT",
@@ -46,13 +46,15 @@
46
46
  "@vue/compiler-dom": "^3.5.40",
47
47
  "comment-json": "^5.0.0",
48
48
  "lru-cache": "^11.5.2",
49
- "magic-string": "^1.0.0",
49
+ "magic-string": "^1.1.0",
50
50
  "merge": "^2.1.1",
51
51
  "pathe": "^2.0.3",
52
+ "postcss": "^8.5.24",
53
+ "postcss-selector-parser": "^7.1.4",
52
54
  "vue": "^3.5.40",
53
- "@weapp-core/constants": "0.1.14",
54
- "@weapp-core/shared": "3.0.6",
55
- "@weapp-vite/ast": "6.18.7",
55
+ "@weapp-core/constants": "0.1.15",
56
+ "@weapp-core/shared": "3.1.0",
57
+ "@weapp-vite/ast": "6.19.0",
56
58
  "rolldown-require": "2.0.22"
57
59
  },
58
60
  "publishConfig": {