weapp-vite 6.16.40 → 6.16.41

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.
@@ -1,6 +1,6 @@
1
1
  import { n as applyWeappViteHostMeta } from "./pluginHost--CaeyWpA.mjs";
2
2
  import { n as configureLogger, r as logger_default } from "./logger-mt4mSTqV.mjs";
3
- import { _ as jsExtensions, a as findJsonEntry, b as vueExtensions, c as isJsOrTs, d as touch, g as configExtensions, i as findJsEntry, l as isTemplate, n as changeFileExtension, o as findTemplateEntry, p as inlineAutoRoutesImports, r as findCssEntry, s as findVueEntry, t as extractConfigFromVue, v as supportedCssLangs, y as templateExtensions } from "./file-SR4f8Kbb.mjs";
3
+ import { _ as jsExtensions, a as findJsonEntry, b as vueExtensions, c as isJsOrTs, d as touch, g as configExtensions, i as findJsEntry, l as isTemplate, n as changeFileExtension, o as findTemplateEntry, p as inlineAutoRoutesImports, r as findCssEntry, s as findVueEntry, t as extractConfigFromVue, v as supportedCssLangs, y as templateExtensions } from "./file-bzejjf0g.mjs";
4
4
  import { createRequire, isBuiltin } from "node:module";
5
5
  import path, { posix } from "pathe";
6
6
  import path$1, { normalize, relative, win32 } from "node:path";
@@ -35,7 +35,7 @@ import { spawn } from "node:child_process";
35
35
  import * as t from "@weapp-vite/ast/babelTypes";
36
36
  import { objectHash } from "@weapp-core/shared/node";
37
37
  import PQueue from "p-queue";
38
- import { APP_PRELUDE_CHUNK_MARKER, APP_PRELUDE_GUARD_KEY, APP_PRELUDE_REQUIRE_MARKER, REQUEST_GLOBAL_ACTUALS_KEY, REQUEST_GLOBAL_BUNDLE_HOST_REF, REQUEST_GLOBAL_BUNDLE_MARKER, REQUEST_GLOBAL_CHUNK_HOST_REF, REQUEST_GLOBAL_CHUNK_MODULE_REF, REQUEST_GLOBAL_EXPOSE_HELPER, REQUEST_GLOBAL_INSTALLER_HOST_REF, REQUEST_GLOBAL_LAZY_CONSTRUCTOR_HELPER, REQUEST_GLOBAL_LAZY_FUNCTION_HELPER, REQUEST_GLOBAL_LOCAL_BINDINGS_MARKER, REQUEST_GLOBAL_MARK_PLACEHOLDER_HELPER, REQUEST_GLOBAL_PASSIVE_BINDINGS_MARKER, REQUEST_GLOBAL_PASSIVE_BINDINGS_MARKER as REQUEST_GLOBAL_PASSIVE_BINDINGS_MARKER$1, REQUEST_GLOBAL_PLACEHOLDER_KEY, REQUEST_GLOBAL_PRELUDE_GUARD_KEY, REQUEST_GLOBAL_PRELUDE_MARKER, REQUEST_GLOBAL_SYNTHETIC_EXPORT_NAME, REQUEST_GLOBAL_USABLE_CONSTRUCTOR_HELPER, WEAPP_VITE_IMPORT_META_ENV_KEY, WEAPP_VITE_INJECTED_API_IDENTIFIER, WEVU_APP_SHELL_COMPONENT_BASE, WEVU_APP_SHELL_TAG_NAME, WEVU_EXPRESSION_ERROR_IDENTIFIER, WEVU_INTERNAL_KEY_IDENTIFIER, WEVU_LAYOUT_BIND_PREFIX, WEVU_PAGE_LAYOUT_CURRENT_NAME_IDENTIFIER, WEVU_PAGE_LAYOUT_CURRENT_PROPS_IDENTIFIER, WEVU_PAGE_LAYOUT_NAME_KEY, WEVU_PAGE_LAYOUT_NEXT_NAME_IDENTIFIER, WEVU_PAGE_LAYOUT_NEXT_PROPS_IDENTIFIER, WEVU_PAGE_LAYOUT_NONE, WEVU_PAGE_LAYOUT_PROPS_KEY, WEVU_PAGE_LAYOUT_SETTER_KEY, WEVU_SCOPED_SLOT_CREATOR_KEY, WEVU_SLOT_FALLBACK_VIRTUAL_HOST_BASE, WEVU_SLOT_FALLBACK_VIRTUAL_HOST_GLOBAL_PATH, WEVU_SLOT_FALLBACK_VIRTUAL_HOST_TAG_NAME, WEVU_SLOT_NAMES_PROP, WEVU_SLOT_OWNER_ID_ATTR, WEVU_SLOT_OWNER_ID_PROP, WEVU_SLOT_PROPS_ATTR, WEVU_SLOT_SCOPE_ATTR, WEVU_SLOT_SCOPE_KEY } from "@weapp-core/constants";
38
+ import { APP_PRELUDE_CHUNK_MARKER, APP_PRELUDE_GUARD_KEY, APP_PRELUDE_REQUIRE_MARKER, REQUEST_GLOBAL_ACTUALS_KEY, REQUEST_GLOBAL_BUNDLE_HOST_REF, REQUEST_GLOBAL_BUNDLE_MARKER, REQUEST_GLOBAL_CHUNK_HOST_REF, REQUEST_GLOBAL_CHUNK_MODULE_REF, REQUEST_GLOBAL_EXPOSE_HELPER, REQUEST_GLOBAL_INSTALLER_HOST_REF, REQUEST_GLOBAL_LAZY_CONSTRUCTOR_HELPER, REQUEST_GLOBAL_LAZY_FUNCTION_HELPER, REQUEST_GLOBAL_LOCAL_BINDINGS_MARKER, REQUEST_GLOBAL_MARK_PLACEHOLDER_HELPER, REQUEST_GLOBAL_PASSIVE_BINDINGS_MARKER, REQUEST_GLOBAL_PASSIVE_BINDINGS_MARKER as REQUEST_GLOBAL_PASSIVE_BINDINGS_MARKER$1, REQUEST_GLOBAL_PLACEHOLDER_KEY, REQUEST_GLOBAL_PRELUDE_GUARD_KEY, REQUEST_GLOBAL_PRELUDE_MARKER, REQUEST_GLOBAL_SYNTHETIC_EXPORT_NAME, REQUEST_GLOBAL_USABLE_CONSTRUCTOR_HELPER, WEAPP_VITE_IMPORT_META_ENV_KEY, WEAPP_VITE_INJECTED_API_IDENTIFIER, WEVU_APP_SHELL_COMPONENT_BASE, WEVU_APP_SHELL_TAG_NAME, WEVU_EXPRESSION_ERROR_IDENTIFIER, WEVU_INTERNAL_KEY_IDENTIFIER, WEVU_LAYOUT_BIND_PREFIX, WEVU_PAGE_LAYOUT_CURRENT_NAME_IDENTIFIER, WEVU_PAGE_LAYOUT_CURRENT_PROPS_IDENTIFIER, WEVU_PAGE_LAYOUT_NAME_KEY, WEVU_PAGE_LAYOUT_NEXT_NAME_IDENTIFIER, WEVU_PAGE_LAYOUT_NEXT_PROPS_IDENTIFIER, WEVU_PAGE_LAYOUT_NONE, WEVU_PAGE_LAYOUT_PROPS_KEY, WEVU_PAGE_LAYOUT_SETTER_KEY, WEVU_SCOPED_SLOT_CREATOR_KEY, WEVU_SLOT_FALLBACK_VIRTUAL_HOST_BASE, WEVU_SLOT_FALLBACK_VIRTUAL_HOST_GLOBAL_PATH, WEVU_SLOT_FALLBACK_VIRTUAL_HOST_TAG_NAME, WEVU_SLOT_NAMES_PROP, WEVU_SLOT_OWNER_ID_ATTR, WEVU_SLOT_OWNER_ID_KEY, WEVU_SLOT_OWNER_ID_PROP, WEVU_SLOT_PROPS_ATTR, WEVU_SLOT_SCOPE_ATTR, WEVU_SLOT_SCOPE_KEY } from "@weapp-core/constants";
39
39
  import { Buffer } from "node:buffer";
40
40
  import { detect } from "package-manager-detector/detect";
41
41
  import tsconfigPaths from "vite-tsconfig-paths";
@@ -8347,6 +8347,13 @@ function toPluginArray(plugins) {
8347
8347
  }
8348
8348
  return result;
8349
8349
  }
8350
+ function resolveDefaultNpmBuildTsconfig(cwd) {
8351
+ const appTsconfig = path.resolve(cwd, ".weapp-vite/tsconfig.app.json");
8352
+ if (existsSync(appTsconfig)) return appTsconfig;
8353
+ const rootTsconfig = path.resolve(cwd, "tsconfig.json");
8354
+ if (existsSync(rootTsconfig)) return rootTsconfig;
8355
+ return false;
8356
+ }
8350
8357
  async function copyDirectory(sourceDir, targetDir) {
8351
8358
  await fs.ensureDir(targetDir);
8352
8359
  const entries = await fs.readdir(sourceDir, { withFileTypes: true });
@@ -8379,15 +8386,18 @@ function createPackageBuilder(ctx, oxcVitePlugin) {
8379
8386
  }
8380
8387
  function resolvePackageBuildTarget({ entry, name, options, outDir }) {
8381
8388
  const importMetaDefineEntries = ctx.configService?.importMetaDefineEntries ?? {};
8389
+ const cwd = ctx.configService?.cwd ?? process.cwd();
8390
+ const defaultTsconfig = resolveDefaultNpmBuildTsconfig(cwd);
8382
8391
  const mergedOptions = defu(options, {
8383
8392
  configFile: false,
8384
8393
  publicDir: false,
8385
8394
  logLevel: "silent",
8386
- root: ctx.configService?.cwd ?? process.cwd(),
8395
+ root: cwd,
8387
8396
  define: {
8388
8397
  ...importMetaDefineEntries,
8389
8398
  "process.env.NODE_ENV": JSON.stringify("production")
8390
8399
  },
8400
+ oxc: { tsconfig: false },
8391
8401
  plugins: [],
8392
8402
  build: {
8393
8403
  lib: {
@@ -8402,6 +8412,8 @@ function createPackageBuilder(ctx, oxcVitePlugin) {
8402
8412
  target: "es6",
8403
8413
  rolldownOptions: {
8404
8414
  external: [],
8415
+ tsconfig: defaultTsconfig,
8416
+ transform: { tsconfig: false },
8405
8417
  output: { exports: "named" }
8406
8418
  }
8407
8419
  }
@@ -11360,15 +11372,61 @@ function createBuildService(ctx) {
11360
11372
  }
11361
11373
  function resetRuntimeStateForConfigRestart() {
11362
11374
  const fresh = createRuntimeState();
11363
- ctx.runtimeState.autoRoutes = fresh.autoRoutes;
11364
- ctx.runtimeState.autoImport = fresh.autoImport;
11375
+ const autoRoutes = ctx.runtimeState.autoRoutes;
11376
+ autoRoutes.routes = fresh.autoRoutes.routes;
11377
+ autoRoutes.serialized = fresh.autoRoutes.serialized;
11378
+ autoRoutes.moduleCode = fresh.autoRoutes.moduleCode;
11379
+ autoRoutes.typedDefinition = fresh.autoRoutes.typedDefinition;
11380
+ autoRoutes.watchFiles.clear();
11381
+ autoRoutes.watchDirs.clear();
11382
+ autoRoutes.dirty = fresh.autoRoutes.dirty;
11383
+ autoRoutes.initialized = fresh.autoRoutes.initialized;
11384
+ autoRoutes.candidates.clear();
11385
+ autoRoutes.needsFullRescan = fresh.autoRoutes.needsFullRescan;
11386
+ autoRoutes.loadingAppConfig = fresh.autoRoutes.loadingAppConfig;
11387
+ const autoImport = ctx.runtimeState.autoImport;
11388
+ autoImport.registry.clear();
11389
+ autoImport.resolvedResolverComponents.clear();
11390
+ autoImport.matcher = void 0;
11391
+ autoImport.matcherKey = fresh.autoImport.matcherKey;
11392
+ autoImport.version += 1;
11393
+ autoImport.pendingEntriesByImporter.clear();
11365
11394
  ctx.runtimeState.build.hmr = fresh.build.hmr;
11366
- ctx.runtimeState.json = fresh.json;
11367
- ctx.runtimeState.asset = fresh.asset;
11368
- ctx.runtimeState.css = fresh.css;
11369
- ctx.runtimeState.wxml = fresh.wxml;
11370
- ctx.runtimeState.scan = fresh.scan;
11371
- ctx.runtimeState.lib = fresh.lib;
11395
+ const json = ctx.runtimeState.json;
11396
+ json.cache.cache.clear();
11397
+ json.cache.mtimeMap.clear();
11398
+ json.cache.signatureMap.clear();
11399
+ json.emittedSource.clear();
11400
+ const asset = ctx.runtimeState.asset;
11401
+ asset.emittedBuffer.clear();
11402
+ asset.scopedSlotGenerics.clear();
11403
+ const css = ctx.runtimeState.css;
11404
+ css.importerToDependencies.clear();
11405
+ css.dependencyToImporters.clear();
11406
+ css.emittedSource.clear();
11407
+ const wxml = ctx.runtimeState.wxml;
11408
+ wxml.depsMap.clear();
11409
+ wxml.importerMap.clear();
11410
+ wxml.tokenMap.clear();
11411
+ wxml.componentsMap.clear();
11412
+ wxml.aggregatedComponentsMap.clear();
11413
+ wxml.templatePathMap.clear();
11414
+ wxml.cache.cache.clear();
11415
+ wxml.cache.mtimeMap.clear();
11416
+ wxml.cache.signatureMap.clear();
11417
+ wxml.emittedCode.clear();
11418
+ const scan = ctx.runtimeState.scan;
11419
+ scan.subPackageMap.clear();
11420
+ scan.independentSubPackageMap.clear();
11421
+ scan.warnedMessages.clear();
11422
+ scan.appEntry = void 0;
11423
+ scan.pluginJson = void 0;
11424
+ scan.pluginJsonPath = void 0;
11425
+ scan.isDirty = fresh.scan.isDirty;
11426
+ scan.independentDirtyRoots.clear();
11427
+ const lib = ctx.runtimeState.lib;
11428
+ lib.enabled = fresh.lib.enabled;
11429
+ lib.entries.clear();
11372
11430
  }
11373
11431
  async function runDev(target) {
11374
11432
  if (process.env.NODE_ENV === void 0) process.env.NODE_ENV = "development";
@@ -11482,6 +11540,18 @@ function createBuildService(ctx) {
11482
11540
  else if (e.code === "END") {
11483
11541
  const durationMs = performance.now() - startTime;
11484
11542
  (async () => {
11543
+ if (shouldRestartDevBuild(target)) {
11544
+ await watcher.close();
11545
+ logger_default.info("检测到 Vite 配置变更,正在重启小程序开发构建...");
11546
+ resetRuntimeStateForConfigRestart();
11547
+ await configService.load(configService.loadOptions);
11548
+ await scanService.loadAppEntry();
11549
+ scanService.loadSubPackages();
11550
+ await runDev(target);
11551
+ logger_default.success("Vite 配置已重新加载,小程序开发构建已重启。");
11552
+ resolveWatcher(e);
11553
+ return;
11554
+ }
11485
11555
  if (firstBuildCompleted) {
11486
11556
  finalizeHmrProfile(durationMs);
11487
11557
  recordHmrProfile(durationMs);
@@ -11494,16 +11564,6 @@ function createBuildService(ctx) {
11494
11564
  resetHmrProfile();
11495
11565
  if (appWxssPath && shouldTouchAppWxss()) touch(appWxssPath).catch(() => {});
11496
11566
  resolveWatcher(e);
11497
- if (shouldRestartDevBuild(target)) {
11498
- await watcher.close();
11499
- logger_default.info("检测到 Vite 配置变更,正在重启小程序开发构建...");
11500
- resetRuntimeStateForConfigRestart();
11501
- await configService.load(configService.loadOptions);
11502
- await scanService.loadAppEntry();
11503
- scanService.loadSubPackages();
11504
- logger_default.success("Vite 配置已重新加载,小程序开发构建已重启。");
11505
- await runDev(target);
11506
- }
11507
11567
  })().catch((error) => {
11508
11568
  resetHmrProfile();
11509
11569
  rejectWatcher(error);
@@ -12187,6 +12247,14 @@ function configureBuildAndPlugins(options) {
12187
12247
  if (defaultTarget) buildConfig.target = defaultTarget;
12188
12248
  }
12189
12249
  const rdOptions = buildConfig.rolldownOptions ?? (buildConfig.rolldownOptions = {});
12250
+ if (config.oxc !== false) {
12251
+ const oxcOptions = config.oxc ?? {};
12252
+ if (!Object.prototype.hasOwnProperty.call(oxcOptions, "tsconfig")) oxcOptions.tsconfig = false;
12253
+ config.oxc = oxcOptions;
12254
+ }
12255
+ const rdTransform = rdOptions.transform ?? {};
12256
+ if (!Object.prototype.hasOwnProperty.call(rdTransform, "tsconfig")) rdTransform.tsconfig = false;
12257
+ rdOptions.transform = rdTransform;
12190
12258
  if (pluginOnly) rdOptions.preserveEntrySignatures = "exports-only";
12191
12259
  if (Array.isArray(rdOptions.output)) rdOptions.output = rdOptions.output.map((output) => ({
12192
12260
  ...output,
@@ -13767,183 +13835,626 @@ function preparePlatformConfigAsset(bundle, options) {
13767
13835
  return normalizedConfig;
13768
13836
  }
13769
13837
  //#endregion
13770
- //#region src/plugins/asset.ts
13771
- function normalizeCopyGlobs(globs) {
13772
- return Array.isArray(globs) ? globs : [];
13838
+ //#region src/plugins/vue/transform/wevuPreset.ts
13839
+ const PERFORMANCE_PRESET_DEFAULTS = {
13840
+ app: { setData: {
13841
+ strategy: "patch",
13842
+ suspendWhenHidden: true,
13843
+ diagnostics: "fallback",
13844
+ highFrequencyWarning: {
13845
+ enabled: true,
13846
+ devOnly: true
13847
+ }
13848
+ } },
13849
+ component: { setData: {
13850
+ strategy: "patch",
13851
+ suspendWhenHidden: true,
13852
+ diagnostics: "fallback",
13853
+ highFrequencyWarning: {
13854
+ enabled: true,
13855
+ devOnly: true
13856
+ }
13857
+ } }
13858
+ };
13859
+ function getPlainRecord(value) {
13860
+ if (!value || typeof value !== "object" || Array.isArray(value)) return;
13861
+ return value;
13773
13862
  }
13774
- function stripQueryAndHash(value) {
13775
- const endIndex = [value.indexOf("?"), value.indexOf("#")].filter((index) => index >= 0).reduce((min, index) => Math.min(min, index), Number.POSITIVE_INFINITY);
13776
- return Number.isFinite(endIndex) ? value.slice(0, endIndex) : value;
13863
+ function mergeDefaults(defaults, options) {
13864
+ if (!defaults) return options;
13865
+ if (!options) return defaults;
13866
+ const merged = {
13867
+ ...defaults,
13868
+ ...options
13869
+ };
13870
+ const defaultSetData = getPlainRecord(defaults.setData);
13871
+ const optionSetData = getPlainRecord(options.setData);
13872
+ if (defaultSetData || optionSetData) merged.setData = {
13873
+ ...defaultSetData ?? {},
13874
+ ...optionSetData ?? {}
13875
+ };
13876
+ const defaultOptions = getPlainRecord(defaults.options);
13877
+ const optionOptions = getPlainRecord(options.options);
13878
+ if (defaultOptions || optionOptions) merged.options = {
13879
+ ...defaultOptions ?? {},
13880
+ ...optionOptions ?? {}
13881
+ };
13882
+ return merged;
13777
13883
  }
13778
- function createPathMatcher(patterns, options) {
13779
- if (!patterns.length) return () => false;
13780
- return pm(patterns.map((pattern) => normalizePath$1(pattern)), options);
13884
+ function mergeWevuDefaults(base, next) {
13885
+ return {
13886
+ app: mergeDefaults(base.app, next.app),
13887
+ component: mergeDefaults(base.component, next.component)
13888
+ };
13781
13889
  }
13782
- function createAssetPathVariants(file, roots) {
13783
- const variants = [file];
13784
- for (const root of roots) {
13785
- const relative = path.relative(root, file);
13786
- if (relative && !relative.startsWith("..") && !path.isAbsolute(relative)) variants.push(relative);
13787
- }
13788
- return variants.map((variant) => normalizePath$1(variant));
13890
+ /**
13891
+ * 读取 wevu 预设名称。
13892
+ */
13893
+ function resolveWevuPreset(config) {
13894
+ return config?.wevu?.preset;
13789
13895
  }
13790
- function parseJsonBuffer(buffer) {
13791
- try {
13792
- const parsed = JSON.parse(buffer.toString("utf8"));
13793
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return;
13794
- return parsed;
13795
- } catch {
13796
- return;
13896
+ /**
13897
+ * 根据配置解析最终的 wevu defaults(预设 + 用户配置)。
13898
+ */
13899
+ function resolveWevuDefaultsWithPreset(config) {
13900
+ const userDefaults = config?.wevu?.defaults;
13901
+ if (resolveWevuPreset(config) !== "performance") return userDefaults;
13902
+ return mergeWevuDefaults(PERFORMANCE_PRESET_DEFAULTS, userDefaults ?? {});
13903
+ }
13904
+ /**
13905
+ * 根据配置判断是否启用自动 setData.pick 注入。
13906
+ */
13907
+ function isAutoSetDataPickEnabledWithPreset(config) {
13908
+ const explicit = config?.wevu?.autoSetDataPick;
13909
+ if (typeof explicit === "boolean") return explicit;
13910
+ return resolveWevuPreset(config) === "performance";
13911
+ }
13912
+ /**
13913
+ * 读取 wevu 输出是否压缩。
13914
+ */
13915
+ function isWevuMinifyEnabled(config, isDev = false) {
13916
+ const explicit = config?.wevu?.minify;
13917
+ if (typeof explicit === "boolean") return explicit;
13918
+ return !isDev;
13919
+ }
13920
+ //#endregion
13921
+ //#region src/plugins/vue/transform/injectSetDataPick.ts
13922
+ const SCOPED_SLOT_OWNER_AUTO_PICK_BIND_KEY_LIMIT = 200;
13923
+ const AUTO_BIND_PICK_KEY_PREFIX = "__wv_bind_";
13924
+ /**
13925
+ * 根据配置判断是否启用自动 setData.pick 注入。
13926
+ */
13927
+ function isAutoSetDataPickEnabled(config) {
13928
+ return isAutoSetDataPickEnabledWithPreset(config);
13929
+ }
13930
+ function isKnownWevuComponentCallee(callee) {
13931
+ if (callee.type === "Identifier") return callee.name === "createWevuComponent" || callee.name === "defineComponent";
13932
+ if (callee.type !== "MemberExpression" || callee.computed) return false;
13933
+ return callee.property.type === "Identifier" && (callee.property.name === "createWevuComponent" || callee.property.name === "defineComponent" || callee.property.name === "so");
13934
+ }
13935
+ /**
13936
+ * 通过轻量字符串特征快速判断脚本是否可能需要注入 setData.pick。
13937
+ */
13938
+ function mayNeedInjectSetDataPickInJs(source) {
13939
+ return source.includes("createWevuComponent") || source.includes("defineComponent") || source.includes("__wevu_isPage") || source.includes(".so(");
13940
+ }
13941
+ function getObjectPropertyByKey$1(objectExpression, key) {
13942
+ for (const member of objectExpression.properties) {
13943
+ if (member.type !== "ObjectProperty") continue;
13944
+ if (member.key.type === "Identifier" && member.key.name === key) return member;
13945
+ if (member.key.type === "StringLiteral" && member.key.value === key) return member;
13797
13946
  }
13798
13947
  }
13799
- function getScopedSlotGenericKeys(ctx, fileName) {
13800
- const componentBase = `/${toPosixPath(fileName.replace(/\.(?:json|wxml|js)$/, ""))}`;
13801
- return ctx.runtimeState.asset.scopedSlotGenerics.get(componentBase);
13948
+ function hasCompiledWevuOptionsMarker(optionsObject) {
13949
+ return Boolean(getObjectPropertyByKey$1(optionsObject, "__wevu_isPage"));
13802
13950
  }
13803
- function withScopedSlotComponentGenerics(ctx, fileName, buffer) {
13804
- const keys = getScopedSlotGenericKeys(ctx, fileName);
13805
- if (!keys?.size) return buffer;
13806
- const parsed = parseJsonBuffer(buffer);
13807
- if (!parsed) return buffer;
13808
- const componentGenerics = parsed.componentGenerics && typeof parsed.componentGenerics === "object" && !Array.isArray(parsed.componentGenerics) ? { ...parsed.componentGenerics } : {};
13809
- for (const key of keys) {
13810
- if (!componentGenerics[key]) {
13811
- componentGenerics[key] = { default: WEAPP_SCOPED_SLOT_GENERIC_COMPONENT_PLACEHOLDER };
13951
+ function unwrapExpression(node) {
13952
+ let current = node;
13953
+ while (true) {
13954
+ if (current.type === "TSAsExpression" || current.type === "TSTypeAssertion" || current.type === "TSNonNullExpression" || current.type === "ParenthesizedExpression" || current.type === "TSSatisfiesExpression") {
13955
+ current = current.expression;
13812
13956
  continue;
13813
13957
  }
13814
- if (componentGenerics[key] === true) continue;
13815
- if (typeof componentGenerics[key] === "object" && !Array.isArray(componentGenerics[key])) {
13816
- const value = componentGenerics[key];
13817
- componentGenerics[key] = typeof value.default === "string" && value.default.trim() ? { ...value } : {
13818
- ...value,
13819
- default: WEAPP_SCOPED_SLOT_GENERIC_COMPONENT_PLACEHOLDER
13820
- };
13821
- continue;
13958
+ return current;
13959
+ }
13960
+ }
13961
+ function resolveOptionsObjectExpression(expression, scope) {
13962
+ if (!expression) return;
13963
+ const unwrapped = unwrapExpression(expression);
13964
+ if (unwrapped.type === "ObjectExpression") return unwrapped;
13965
+ if (unwrapped.type === "Identifier") {
13966
+ const binding = scope.getBinding(unwrapped.name);
13967
+ if (!binding || !binding.path.isVariableDeclarator()) return;
13968
+ const init = binding.path.node.init;
13969
+ if (!init || init.type !== "ObjectExpression" && init.type !== "CallExpression" && init.type !== "Identifier") return;
13970
+ return resolveOptionsObjectExpression(init, binding.path.scope);
13971
+ }
13972
+ if (unwrapped.type === "CallExpression" && unwrapped.callee.type === "MemberExpression" && !unwrapped.callee.computed && unwrapped.callee.object.type === "Identifier" && unwrapped.callee.object.name === "Object" && unwrapped.callee.property.type === "Identifier" && unwrapped.callee.property.name === "assign") for (let i = unwrapped.arguments.length - 1; i >= 0; i--) {
13973
+ const arg = unwrapped.arguments[i];
13974
+ if (arg.type !== "SpreadElement") {
13975
+ const resolved = resolveOptionsObjectExpression(arg, scope);
13976
+ if (resolved) return resolved;
13822
13977
  }
13823
13978
  }
13824
- parsed.componentGenerics = componentGenerics;
13825
- const normalized = resolveJson({ json: parsed }, void 0, ctx.configService.platform);
13826
- return Buffer.from(normalized ?? JSON.stringify(parsed, null, 2));
13827
13979
  }
13828
- function createScopedSlotGenericTag(key) {
13829
- return `<${key} wx:if="{{${WEVU_SLOT_OWNER_ID_PROP}}}" ${WEVU_SLOT_OWNER_ID_ATTR}="{{${WEVU_SLOT_OWNER_ID_PROP}}}" ${WEVU_SLOT_PROPS_ATTR}="{{[]}}" ${WEVU_SLOT_SCOPE_ATTR}="{{${WEVU_SLOT_SCOPE_KEY}}}" />`;
13980
+ function createPickArrayExpression(keys) {
13981
+ return {
13982
+ type: "ArrayExpression",
13983
+ elements: keys.map((key) => ({
13984
+ type: "StringLiteral",
13985
+ value: key
13986
+ }))
13987
+ };
13830
13988
  }
13831
- function createSlotPatchPattern(key) {
13832
- const slotName = key.replace(/^scoped-slots-/, "");
13833
- if (slotName === "default") return /<slot(\s*)\/>|<slot(\s*)><\/slot>/g;
13834
- const escapedSlotName = slotName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
13835
- return new RegExp(`<slot(?=[^>]*\\bname=["']${escapedSlotName}["'])((?:\\s+[^>]*)?)\\/>|<slot(?=[^>]*\\bname=["']${escapedSlotName}["'])((?:\\s+[^>]*)?)><\\/slot>`, "g");
13989
+ function mergeStableKeys(keys, stableKeys) {
13990
+ const merged = [];
13991
+ const seen = /* @__PURE__ */ new Set();
13992
+ for (const key of [...keys, ...stableKeys]) {
13993
+ if (seen.has(key)) continue;
13994
+ seen.add(key);
13995
+ merged.push(key);
13996
+ }
13997
+ return merged;
13836
13998
  }
13837
- function withScopedSlotGenericSlots(ctx, fileName, buffer) {
13838
- const keys = getScopedSlotGenericKeys(ctx, fileName);
13839
- if (!keys?.size || ctx.configService.platform !== "weapp") return buffer;
13840
- let source = buffer.toString("utf8");
13999
+ function mergePickArrayExpression(arrayExpression, keys) {
14000
+ const existing = /* @__PURE__ */ new Set();
14001
+ for (const element of arrayExpression.elements) if (element && element.type === "StringLiteral") existing.add(element.value);
13841
14002
  let changed = false;
13842
14003
  for (const key of keys) {
13843
- if (source.includes(`<${key} `) || source.includes(`<${key}>`)) continue;
13844
- const tag = createScopedSlotGenericTag(key);
13845
- source = source.replace(createSlotPatchPattern(key), (matched) => {
13846
- changed = true;
13847
- return `${matched}${tag}`;
14004
+ if (existing.has(key)) continue;
14005
+ arrayExpression.elements.push({
14006
+ type: "StringLiteral",
14007
+ value: key
13848
14008
  });
14009
+ existing.add(key);
14010
+ changed = true;
13849
14011
  }
13850
- return changed ? Buffer.from(source) : buffer;
14012
+ return changed;
13851
14013
  }
13852
- function createScopedSlotHostPropertiesSource() {
13853
- return `${WEVU_SLOT_OWNER_ID_PROP}: { type: String, value: "" }, ${WEVU_SLOT_SCOPE_KEY}: { type: null, value: null }`;
14014
+ function injectPickIntoSetDataObject(setDataObject, keys) {
14015
+ const pickProp = getObjectPropertyByKey$1(setDataObject, "pick");
14016
+ if (!pickProp) {
14017
+ setDataObject.properties.unshift({
14018
+ type: "ObjectProperty",
14019
+ key: {
14020
+ type: "Identifier",
14021
+ name: "pick"
14022
+ },
14023
+ computed: false,
14024
+ shorthand: false,
14025
+ value: createPickArrayExpression(keys)
14026
+ });
14027
+ return true;
14028
+ }
14029
+ if (pickProp.value.type !== "ArrayExpression") return false;
14030
+ return mergePickArrayExpression(pickProp.value, keys);
13854
14031
  }
13855
- function withScopedSlotHostProperties(ctx, fileName, source) {
13856
- if (!getScopedSlotGenericKeys(ctx, fileName)?.size || ctx.configService.platform !== "weapp" || source.includes(WEVU_SLOT_OWNER_ID_PROP)) return source;
13857
- const propertySource = createScopedSlotHostPropertiesSource();
13858
- if (/properties\s*:\s*\{/.test(source)) return source.replace(/properties\s*:\s*\{/, (matched) => `${matched} ${propertySource},`);
13859
- return source.replace(/Component\(\s*\{/, (matched) => `${matched} properties: { ${propertySource} },`);
13860
- }
13861
- function withScopedSlotHostAsset(ctx, fileName, buffer) {
13862
- if (fileName.endsWith(".json")) return withScopedSlotComponentGenerics(ctx, fileName, buffer);
13863
- if (fileName.endsWith(".wxml")) return withScopedSlotGenericSlots(ctx, fileName, buffer);
13864
- if (fileName.endsWith(".js")) {
13865
- const source = buffer.toString("utf8");
13866
- const next = withScopedSlotHostProperties(ctx, fileName, source);
13867
- return next === source ? buffer : Buffer.from(next);
14032
+ function injectPickIntoOptionsObject(optionsObject, keys) {
14033
+ const setDataProp = getObjectPropertyByKey$1(optionsObject, "setData");
14034
+ if (!setDataProp) {
14035
+ optionsObject.properties.unshift({
14036
+ type: "ObjectProperty",
14037
+ key: {
14038
+ type: "Identifier",
14039
+ name: "setData"
14040
+ },
14041
+ computed: false,
14042
+ shorthand: false,
14043
+ value: {
14044
+ type: "ObjectExpression",
14045
+ properties: [{
14046
+ type: "ObjectProperty",
14047
+ key: {
14048
+ type: "Identifier",
14049
+ name: "pick"
14050
+ },
14051
+ computed: false,
14052
+ shorthand: false,
14053
+ value: createPickArrayExpression(keys)
14054
+ }]
14055
+ }
14056
+ });
14057
+ return true;
13868
14058
  }
13869
- return buffer;
13870
- }
13871
- function patchScopedSlotHostAssetForBundle(ctx, fileName, output) {
13872
- if (output.type === "chunk") {
13873
- const current = output.code;
13874
- if (typeof current !== "string") return false;
13875
- const next = withScopedSlotHostProperties(ctx, fileName, current);
13876
- if (next === current) return false;
13877
- output.code = next;
14059
+ const setDataValue = unwrapExpression(setDataProp.value);
14060
+ if (setDataValue.type === "ObjectExpression") return injectPickIntoSetDataObject(setDataValue, keys);
14061
+ if (setDataValue.type === "Identifier" || setDataValue.type === "MemberExpression" || setDataValue.type === "CallExpression") {
14062
+ setDataProp.value = {
14063
+ type: "ObjectExpression",
14064
+ properties: [{
14065
+ type: "ObjectProperty",
14066
+ key: {
14067
+ type: "Identifier",
14068
+ name: "pick"
14069
+ },
14070
+ computed: false,
14071
+ shorthand: false,
14072
+ value: createPickArrayExpression(keys)
14073
+ }, {
14074
+ type: "SpreadElement",
14075
+ argument: setDataValue
14076
+ }]
14077
+ };
13878
14078
  return true;
13879
14079
  }
13880
- const current = output.source;
13881
- if (typeof current !== "string" && !Buffer.isBuffer(current) && !(current instanceof Uint8Array)) return false;
13882
- const currentBuffer = Buffer.from(current);
13883
- const next = withScopedSlotHostAsset(ctx, fileName, currentBuffer);
13884
- if (Buffer.compare(currentBuffer, next) === 0) return false;
13885
- output.source = next.toString("utf8");
13886
- return true;
14080
+ return false;
13887
14081
  }
13888
- function emitScopedSlotGenericPlaceholderAssets(ctx, pluginContext, bundle, fileName) {
13889
- if (!getScopedSlotGenericKeys(ctx, fileName)?.size || ctx.configService.platform !== "weapp") return;
13890
- emitAlipayGenericPlaceholderAssetsByBase(pluginContext, bundle, resolveWeappScopedSlotGenericPlaceholderBase(toPosixPath(fileName.replace(/\.json$/, ""))), ctx.configService.outputExtensions, {
13891
- jsonConfig: {
13892
- component: true,
13893
- options: { virtualHost: true }
14082
+ function createScopedSlotHostPropertyDefinition(typeName, value) {
14083
+ return {
14084
+ type: "ObjectExpression",
14085
+ properties: [{
14086
+ type: "ObjectProperty",
14087
+ key: {
14088
+ type: "Identifier",
14089
+ name: "type"
14090
+ },
14091
+ computed: false,
14092
+ shorthand: false,
14093
+ value: typeName === "String" ? {
14094
+ type: "Identifier",
14095
+ name: "String"
14096
+ } : { type: "NullLiteral" }
14097
+ }, {
14098
+ type: "ObjectProperty",
14099
+ key: {
14100
+ type: "Identifier",
14101
+ name: "value"
14102
+ },
14103
+ computed: false,
14104
+ shorthand: false,
14105
+ value: value === null ? { type: "NullLiteral" } : {
14106
+ type: "StringLiteral",
14107
+ value
14108
+ }
14109
+ }]
14110
+ };
14111
+ }
14112
+ function createScopedSlotHostProperties() {
14113
+ return [
14114
+ {
14115
+ type: "ObjectProperty",
14116
+ key: {
14117
+ type: "Identifier",
14118
+ name: WEVU_SLOT_NAMES_PROP
14119
+ },
14120
+ computed: false,
14121
+ shorthand: false,
14122
+ value: createScopedSlotHostPropertyDefinition("null", null)
13894
14123
  },
13895
- templateSource: "<view wx:if=\"{{false}}\" />"
13896
- });
14124
+ {
14125
+ type: "ObjectProperty",
14126
+ key: {
14127
+ type: "Identifier",
14128
+ name: WEVU_SLOT_OWNER_ID_PROP
14129
+ },
14130
+ computed: false,
14131
+ shorthand: false,
14132
+ value: createScopedSlotHostPropertyDefinition("String", "")
14133
+ },
14134
+ {
14135
+ type: "ObjectProperty",
14136
+ key: {
14137
+ type: "Identifier",
14138
+ name: WEVU_SLOT_SCOPE_KEY
14139
+ },
14140
+ computed: false,
14141
+ shorthand: false,
14142
+ value: createScopedSlotHostPropertyDefinition("null", null)
14143
+ }
14144
+ ];
13897
14145
  }
13898
- function patchScopedSlotHostAssetsInBundle(ctx, pluginContext, bundle) {
13899
- for (const [fileName, output] of Object.entries(bundle)) {
13900
- if (!/\.(?:json|wxml|js)$/.test(fileName) || !output) continue;
13901
- if (!patchScopedSlotHostAssetForBundle(ctx, fileName, output)) continue;
13902
- if (fileName.endsWith(".json")) emitScopedSlotGenericPlaceholderAssets(ctx, pluginContext, bundle, fileName);
13903
- const source = output.type === "chunk" ? output.code : output.source;
13904
- ctx.runtimeState.asset.emittedBuffer.set(fileName, Buffer.from(source));
14146
+ function injectScopedSlotHostPropertiesIntoObject(propertiesObject) {
14147
+ let changed = false;
14148
+ for (const prop of createScopedSlotHostProperties().reverse()) {
14149
+ const key = prop.key.type === "Identifier" ? prop.key.name : void 0;
14150
+ if (!key || getObjectPropertyByKey$1(propertiesObject, key)) continue;
14151
+ propertiesObject.properties.unshift(prop);
14152
+ changed = true;
13905
14153
  }
14154
+ return changed;
13906
14155
  }
13907
- function collectBundledAssetSourcePaths(bundle) {
13908
- const sources = /* @__PURE__ */ new Set();
13909
- for (const output of Object.values(bundle)) {
13910
- if (!output || output.type !== "asset") continue;
13911
- for (const originalFile of output.originalFileNames ?? []) if (typeof originalFile === "string" && originalFile) sources.add(normalizePath$1(originalFile));
14156
+ function injectScopedSlotHostPropertiesIntoOptionsObject(optionsObject) {
14157
+ const propertiesProp = getObjectPropertyByKey$1(optionsObject, "properties");
14158
+ if (!propertiesProp) {
14159
+ optionsObject.properties.unshift({
14160
+ type: "ObjectProperty",
14161
+ key: {
14162
+ type: "Identifier",
14163
+ name: "properties"
14164
+ },
14165
+ computed: false,
14166
+ shorthand: false,
14167
+ value: {
14168
+ type: "ObjectExpression",
14169
+ properties: createScopedSlotHostProperties()
14170
+ }
14171
+ });
14172
+ return true;
13912
14173
  }
13913
- return sources;
14174
+ const propertiesValue = unwrapExpression(propertiesProp.value);
14175
+ if (propertiesValue.type === "ObjectExpression") return injectScopedSlotHostPropertiesIntoObject(propertiesValue);
14176
+ if (propertiesValue.type === "Identifier" || propertiesValue.type === "MemberExpression" || propertiesValue.type === "CallExpression") {
14177
+ propertiesProp.value = {
14178
+ type: "ObjectExpression",
14179
+ properties: [{
14180
+ type: "SpreadElement",
14181
+ argument: propertiesValue
14182
+ }, ...createScopedSlotHostProperties()]
14183
+ };
14184
+ return true;
14185
+ }
14186
+ return false;
13914
14187
  }
13915
- function collectAssetModuleSourcePaths(moduleIds) {
13916
- const sources = /* @__PURE__ */ new Set();
13917
- for (const moduleId of moduleIds) {
13918
- if (typeof moduleId !== "string" || !moduleId) continue;
13919
- sources.add(normalizePath$1(stripQueryAndHash(moduleId)));
14188
+ function transformTargetWevuOptionsInJs(source, transformOptions) {
14189
+ if (!mayNeedInjectSetDataPickInJs(source)) return {
14190
+ code: source,
14191
+ transformed: false
14192
+ };
14193
+ const ast = parseJsLike(source);
14194
+ const candidateOptions = /* @__PURE__ */ new Set();
14195
+ traverse(ast, { CallExpression(path) {
14196
+ const firstArg = path.node.arguments[0];
14197
+ if (!firstArg || firstArg.type === "SpreadElement") return;
14198
+ const resolvedOptions = resolveOptionsObjectExpression(firstArg, path.scope);
14199
+ if (resolvedOptions && (isKnownWevuComponentCallee(path.node.callee) || hasCompiledWevuOptionsMarker(resolvedOptions))) candidateOptions.add(resolvedOptions);
14200
+ } });
14201
+ if (!candidateOptions.size) return {
14202
+ code: source,
14203
+ transformed: false
14204
+ };
14205
+ let changed = false;
14206
+ for (const optionsObject of candidateOptions) changed = transformOptions(optionsObject) || changed;
14207
+ if (!changed) return {
14208
+ code: source,
14209
+ transformed: false
14210
+ };
14211
+ const generated = generate(ast, {
14212
+ retainLines: true,
14213
+ sourceMaps: true,
14214
+ sourceFileName: "inline.js"
14215
+ }, source);
14216
+ return {
14217
+ code: generated.code,
14218
+ transformed: true,
14219
+ map: generated.map
14220
+ };
14221
+ }
14222
+ /**
14223
+ * 从编译后的 WXML 模板提取渲染相关的顶层 key。
14224
+ */
14225
+ function collectSetDataPickKeysFromTemplate(template, options) {
14226
+ return collectSetDataPickKeysFromTemplateCode(template, options);
14227
+ }
14228
+ /**
14229
+ * 判断 scoped slot 宿主页是否应该跳过大规模模板 bind 自动 pick。
14230
+ */
14231
+ function shouldUseScopedSlotOwnerOnlySetDataPick(pickKeys) {
14232
+ let bindKeyCount = 0;
14233
+ for (const key of pickKeys) if (key.startsWith(AUTO_BIND_PICK_KEY_PREFIX)) {
14234
+ bindKeyCount += 1;
14235
+ if (bindKeyCount > SCOPED_SLOT_OWNER_AUTO_PICK_BIND_KEY_LIMIT) return true;
13920
14236
  }
13921
- return sources;
14237
+ return false;
13922
14238
  }
13923
- function scanAssetFiles(configService, config, buildTarget) {
13924
- const weappViteConfig = configService.weappViteConfig;
13925
- const include = normalizeCopyGlobs(weappViteConfig?.copy?.include);
13926
- const exclude = normalizeCopyGlobs(weappViteConfig?.copy?.exclude);
13927
- const filter = weappViteConfig?.copy?.filter ?? (() => true);
13928
- const ignore = [
13929
- ...defaultExcluded,
13930
- path.resolve(configService.cwd, `${config.build.outDir}/**/*`),
13931
- ...exclude
13932
- ];
13933
- const includeMatcher = createPathMatcher([`**/*.{${defaultAssetExtensions.join(",")}}`, ...include], { dot: false });
13934
- const ignoreMatcher = createPathMatcher(ignore, { dot: true });
13935
- const roots = /* @__PURE__ */ new Set();
13936
- if (buildTarget !== "plugin") roots.add(configService.absoluteSrcRoot);
13937
- if (configService.absolutePluginRoot && buildTarget === "plugin") roots.add(configService.absolutePluginRoot);
13938
- if (!roots.size) return Promise.resolve([]);
13939
- const crawlPromises = Array.from(roots).map((root) => {
13940
- return new fdir({
13941
- includeDirs: false,
13942
- pathSeparator: "/"
13943
- }).withFullPaths().crawl(root).withPromise().then((files) => {
13944
- return files.filter((file) => {
13945
- const variants = createAssetPathVariants(file, [
13946
- root,
14239
+ /**
14240
+ * 裁剪 scoped slot 宿主页中过量的自动 bind key,同时保留业务状态 key。
14241
+ */
14242
+ function pruneScopedSlotOwnerAutoSetDataPickKeys(pickKeys) {
14243
+ if (!shouldUseScopedSlotOwnerOnlySetDataPick(pickKeys)) return pickKeys;
14244
+ return pickKeys.filter((key) => !key.startsWith(AUTO_BIND_PICK_KEY_PREFIX));
14245
+ }
14246
+ /**
14247
+ * 在 wevu 组件脚本中注入 setData.pick。
14248
+ */
14249
+ function injectSetDataPickInJs(source, pickKeys) {
14250
+ const mergedPickKeys = mergeStableKeys(pickKeys, [
14251
+ WEVU_SLOT_NAMES_PROP,
14252
+ WEVU_SLOT_OWNER_ID_PROP,
14253
+ WEVU_SLOT_SCOPE_KEY
14254
+ ]);
14255
+ if (!mergedPickKeys.length) return {
14256
+ code: source,
14257
+ transformed: false
14258
+ };
14259
+ return transformTargetWevuOptionsInJs(source, (optionsObject) => injectPickIntoOptionsObject(optionsObject, mergedPickKeys));
14260
+ }
14261
+ /**
14262
+ * 只为 scoped slot 宿主首屏同步注入必要的 setData.pick 字段。
14263
+ */
14264
+ function injectScopedSlotOwnerSetDataPickInJs(source, pickKeys = []) {
14265
+ const mergedPickKeys = mergeStableKeys(pickKeys, [
14266
+ WEVU_SLOT_OWNER_ID_KEY,
14267
+ WEVU_SLOT_NAMES_PROP,
14268
+ WEVU_SLOT_OWNER_ID_PROP,
14269
+ WEVU_SLOT_SCOPE_KEY
14270
+ ]);
14271
+ return transformTargetWevuOptionsInJs(source, (optionsObject) => injectPickIntoOptionsObject(optionsObject, mergedPickKeys));
14272
+ }
14273
+ /**
14274
+ * 在含有 scoped slot outlet 的 wevu 组件脚本中注入宿主内部属性。
14275
+ */
14276
+ function injectScopedSlotHostPropertiesInJs(source) {
14277
+ return transformTargetWevuOptionsInJs(source, injectScopedSlotHostPropertiesIntoOptionsObject);
14278
+ }
14279
+ //#endregion
14280
+ //#region src/plugins/asset.ts
14281
+ function normalizeCopyGlobs(globs) {
14282
+ return Array.isArray(globs) ? globs : [];
14283
+ }
14284
+ function stripQueryAndHash(value) {
14285
+ const endIndex = [value.indexOf("?"), value.indexOf("#")].filter((index) => index >= 0).reduce((min, index) => Math.min(min, index), Number.POSITIVE_INFINITY);
14286
+ return Number.isFinite(endIndex) ? value.slice(0, endIndex) : value;
14287
+ }
14288
+ function createPathMatcher(patterns, options) {
14289
+ if (!patterns.length) return () => false;
14290
+ return pm(patterns.map((pattern) => normalizePath$1(pattern)), options);
14291
+ }
14292
+ function createAssetPathVariants(file, roots) {
14293
+ const variants = [file];
14294
+ for (const root of roots) {
14295
+ const relative = path.relative(root, file);
14296
+ if (relative && !relative.startsWith("..") && !path.isAbsolute(relative)) variants.push(relative);
14297
+ }
14298
+ return variants.map((variant) => normalizePath$1(variant));
14299
+ }
14300
+ function parseJsonBuffer(buffer) {
14301
+ try {
14302
+ const parsed = JSON.parse(buffer.toString("utf8"));
14303
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return;
14304
+ return parsed;
14305
+ } catch {
14306
+ return;
14307
+ }
14308
+ }
14309
+ function getScopedSlotGenericKeys(ctx, fileName) {
14310
+ const componentBase = `/${toPosixPath(fileName.replace(/\.(?:json|wxml|js)$/, ""))}`;
14311
+ return ctx.runtimeState.asset.scopedSlotGenerics.get(componentBase);
14312
+ }
14313
+ function withScopedSlotComponentGenerics(ctx, fileName, buffer) {
14314
+ const keys = getScopedSlotGenericKeys(ctx, fileName);
14315
+ if (!keys?.size) return buffer;
14316
+ const parsed = parseJsonBuffer(buffer);
14317
+ if (!parsed) return buffer;
14318
+ const componentGenerics = parsed.componentGenerics && typeof parsed.componentGenerics === "object" && !Array.isArray(parsed.componentGenerics) ? { ...parsed.componentGenerics } : {};
14319
+ for (const key of keys) {
14320
+ if (!componentGenerics[key]) {
14321
+ componentGenerics[key] = { default: WEAPP_SCOPED_SLOT_GENERIC_COMPONENT_PLACEHOLDER };
14322
+ continue;
14323
+ }
14324
+ if (componentGenerics[key] === true) continue;
14325
+ if (typeof componentGenerics[key] === "object" && !Array.isArray(componentGenerics[key])) {
14326
+ const value = componentGenerics[key];
14327
+ componentGenerics[key] = typeof value.default === "string" && value.default.trim() ? { ...value } : {
14328
+ ...value,
14329
+ default: WEAPP_SCOPED_SLOT_GENERIC_COMPONENT_PLACEHOLDER
14330
+ };
14331
+ continue;
14332
+ }
14333
+ }
14334
+ parsed.componentGenerics = componentGenerics;
14335
+ const normalized = resolveJson({ json: parsed }, void 0, ctx.configService.platform);
14336
+ return Buffer.from(normalized ?? JSON.stringify(parsed, null, 2));
14337
+ }
14338
+ function createScopedSlotGenericTag(key) {
14339
+ return `<${key} wx:if="{{${WEVU_SLOT_OWNER_ID_PROP}}}" ${WEVU_SLOT_OWNER_ID_ATTR}="{{${WEVU_SLOT_OWNER_ID_PROP}}}" ${WEVU_SLOT_PROPS_ATTR}="{{[]}}" ${WEVU_SLOT_SCOPE_ATTR}="{{${WEVU_SLOT_SCOPE_KEY}}}" />`;
14340
+ }
14341
+ function createSlotPatchPattern(key) {
14342
+ const slotName = key.replace(/^scoped-slots-/, "");
14343
+ if (slotName === "default") return /<slot(\s*)\/>|<slot(\s*)><\/slot>/g;
14344
+ const escapedSlotName = slotName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
14345
+ return new RegExp(`<slot(?=[^>]*\\bname=["']${escapedSlotName}["'])((?:\\s+[^>]*)?)\\/>|<slot(?=[^>]*\\bname=["']${escapedSlotName}["'])((?:\\s+[^>]*)?)><\\/slot>`, "g");
14346
+ }
14347
+ function withScopedSlotGenericSlots(ctx, fileName, buffer) {
14348
+ const keys = getScopedSlotGenericKeys(ctx, fileName);
14349
+ if (!keys?.size || ctx.configService.platform !== "weapp") return buffer;
14350
+ let source = buffer.toString("utf8");
14351
+ let changed = false;
14352
+ for (const key of keys) {
14353
+ if (source.includes(`<${key} `) || source.includes(`<${key}>`)) continue;
14354
+ const tag = createScopedSlotGenericTag(key);
14355
+ source = source.replace(createSlotPatchPattern(key), (matched) => {
14356
+ changed = true;
14357
+ return `${matched}${tag}`;
14358
+ });
14359
+ }
14360
+ return changed ? Buffer.from(source) : buffer;
14361
+ }
14362
+ function createScopedSlotHostPropertiesSource() {
14363
+ return `${WEVU_SLOT_NAMES_PROP}: { type: null, value: null }, ${WEVU_SLOT_OWNER_ID_PROP}: { type: String, value: "" }, ${WEVU_SLOT_SCOPE_KEY}: { type: null, value: null }`;
14364
+ }
14365
+ function withScopedSlotHostProperties(ctx, fileName, source) {
14366
+ if (!getScopedSlotGenericKeys(ctx, fileName)?.size || ctx.configService.platform !== "weapp" || source.includes(WEVU_SLOT_OWNER_ID_PROP)) return source;
14367
+ const injected = injectScopedSlotHostPropertiesInJs(source);
14368
+ if (injected.transformed) return injected.code;
14369
+ const propertySource = createScopedSlotHostPropertiesSource();
14370
+ return source.replace(/Component\(\s*\{/, (matched) => `${matched} properties: { ${propertySource} },`);
14371
+ }
14372
+ function withScopedSlotHostAsset(ctx, fileName, buffer) {
14373
+ if (fileName.endsWith(".json")) return withScopedSlotComponentGenerics(ctx, fileName, buffer);
14374
+ if (fileName.endsWith(".wxml")) return withScopedSlotGenericSlots(ctx, fileName, buffer);
14375
+ if (fileName.endsWith(".js")) {
14376
+ const source = buffer.toString("utf8");
14377
+ const next = withScopedSlotHostProperties(ctx, fileName, source);
14378
+ return next === source ? buffer : Buffer.from(next);
14379
+ }
14380
+ return buffer;
14381
+ }
14382
+ function patchScopedSlotHostAssetForBundle(ctx, fileName, output) {
14383
+ if (output.type === "chunk") {
14384
+ const current = output.code;
14385
+ if (typeof current !== "string") return false;
14386
+ const next = withScopedSlotHostProperties(ctx, fileName, current);
14387
+ if (next === current) return false;
14388
+ output.code = next;
14389
+ return true;
14390
+ }
14391
+ const current = output.source;
14392
+ if (typeof current !== "string" && !Buffer.isBuffer(current) && !(current instanceof Uint8Array)) return false;
14393
+ const currentBuffer = Buffer.from(current);
14394
+ const next = withScopedSlotHostAsset(ctx, fileName, currentBuffer);
14395
+ if (Buffer.compare(currentBuffer, next) === 0) return false;
14396
+ output.source = next.toString("utf8");
14397
+ return true;
14398
+ }
14399
+ function emitScopedSlotGenericPlaceholderAssets(ctx, pluginContext, bundle, fileName) {
14400
+ if (!getScopedSlotGenericKeys(ctx, fileName)?.size || ctx.configService.platform !== "weapp") return;
14401
+ emitAlipayGenericPlaceholderAssetsByBase(pluginContext, bundle, resolveWeappScopedSlotGenericPlaceholderBase(toPosixPath(fileName.replace(/\.json$/, ""))), ctx.configService.outputExtensions, {
14402
+ jsonConfig: {
14403
+ component: true,
14404
+ options: { virtualHost: true }
14405
+ },
14406
+ templateSource: "<view wx:if=\"{{false}}\" />"
14407
+ });
14408
+ }
14409
+ function patchScopedSlotHostAssetsInBundle(ctx, pluginContext, bundle) {
14410
+ for (const [fileName, output] of Object.entries(bundle)) {
14411
+ if (!/\.(?:json|wxml|js)$/.test(fileName) || !output) continue;
14412
+ if (!patchScopedSlotHostAssetForBundle(ctx, fileName, output)) continue;
14413
+ if (fileName.endsWith(".json")) emitScopedSlotGenericPlaceholderAssets(ctx, pluginContext, bundle, fileName);
14414
+ const source = output.type === "chunk" ? output.code : output.source;
14415
+ ctx.runtimeState.asset.emittedBuffer.set(fileName, Buffer.from(source));
14416
+ }
14417
+ }
14418
+ function collectBundledAssetSourcePaths(bundle) {
14419
+ const sources = /* @__PURE__ */ new Set();
14420
+ for (const output of Object.values(bundle)) {
14421
+ if (!output || output.type !== "asset") continue;
14422
+ for (const originalFile of output.originalFileNames ?? []) if (typeof originalFile === "string" && originalFile) sources.add(normalizePath$1(originalFile));
14423
+ }
14424
+ return sources;
14425
+ }
14426
+ function collectAssetModuleSourcePaths(moduleIds) {
14427
+ const sources = /* @__PURE__ */ new Set();
14428
+ for (const moduleId of moduleIds) {
14429
+ if (typeof moduleId !== "string" || !moduleId) continue;
14430
+ sources.add(normalizePath$1(stripQueryAndHash(moduleId)));
14431
+ }
14432
+ return sources;
14433
+ }
14434
+ function scanAssetFiles(configService, config, buildTarget) {
14435
+ const weappViteConfig = configService.weappViteConfig;
14436
+ const include = normalizeCopyGlobs(weappViteConfig?.copy?.include);
14437
+ const exclude = normalizeCopyGlobs(weappViteConfig?.copy?.exclude);
14438
+ const filter = weappViteConfig?.copy?.filter ?? (() => true);
14439
+ const ignore = [
14440
+ ...defaultExcluded,
14441
+ path.resolve(configService.cwd, `${config.build.outDir}/**/*`),
14442
+ ...exclude
14443
+ ];
14444
+ const includeMatcher = createPathMatcher([`**/*.{${defaultAssetExtensions.join(",")}}`, ...include], { dot: false });
14445
+ const ignoreMatcher = createPathMatcher(ignore, { dot: true });
14446
+ const roots = /* @__PURE__ */ new Set();
14447
+ if (buildTarget !== "plugin") roots.add(configService.absoluteSrcRoot);
14448
+ if (configService.absolutePluginRoot && buildTarget === "plugin") roots.add(configService.absolutePluginRoot);
14449
+ if (!roots.size) return Promise.resolve([]);
14450
+ const crawlPromises = Array.from(roots).map((root) => {
14451
+ return new fdir({
14452
+ includeDirs: false,
14453
+ pathSeparator: "/"
14454
+ }).withFullPaths().crawl(root).withPromise().then((files) => {
14455
+ return files.filter((file) => {
14456
+ const variants = createAssetPathVariants(file, [
14457
+ root,
13947
14458
  configService.absoluteSrcRoot,
13948
14459
  configService.cwd
13949
14460
  ]);
@@ -14877,7 +15388,7 @@ function parseExpressionAst(expression) {
14877
15388
  function createStaticObjectKey(key) {
14878
15389
  return t.isValidIdentifier(key) ? t.identifier(key) : t.stringLiteral(key);
14879
15390
  }
14880
- function getObjectPropertyByKey$1(node, key) {
15391
+ function getObjectPropertyByKey(node, key) {
14881
15392
  for (const prop of node.properties) {
14882
15393
  if (!t.isObjectProperty(prop) || prop.computed) continue;
14883
15394
  if (t.isIdentifier(prop.key) && prop.key.name === key || t.isStringLiteral(prop.key) && prop.key.value === key) return prop;
@@ -14934,7 +15445,7 @@ function injectLayoutBindingComputed(script, props) {
14934
15445
  const expressionAst = parseExpressionAst(value.expression) ?? t.identifier("undefined");
14935
15446
  return t.objectProperty(createStaticObjectKey(`${WEVU_LAYOUT_BIND_PREFIX}${key}`), t.functionExpression(null, [], t.blockStatement([t.tryStatement(t.blockStatement([t.returnStatement(expressionAst)]), t.catchClause(t.identifier(WEVU_EXPRESSION_ERROR_IDENTIFIER), t.blockStatement([t.returnStatement(t.identifier("undefined"))])), null)])));
14936
15447
  });
14937
- const computedProp = getObjectPropertyByKey$1(optionsObject, "computed");
15448
+ const computedProp = getObjectPropertyByKey(optionsObject, "computed");
14938
15449
  if (!computedProp) optionsObject.properties.unshift(t.objectProperty(createStaticObjectKey("computed"), t.objectExpression(computedEntries)));
14939
15450
  else if (t.isObjectExpression(computedProp.value)) computedProp.value.properties.push(...computedEntries);
14940
15451
  else if (t.isIdentifier(computedProp.value) || t.isMemberExpression(computedProp.value)) computedProp.value = t.objectExpression([...computedEntries, t.spreadElement(t.cloneNode(computedProp.value, true))]);
@@ -14944,7 +15455,7 @@ function injectLayoutBindingComputed(script, props) {
14944
15455
  //#endregion
14945
15456
  //#region src/plugins/vue/transform/pageLayout/apply/native.ts
14946
15457
  function injectNativePageLayoutSetter(pageOptions) {
14947
- if (getObjectPropertyByKey$1(pageOptions, WEVU_PAGE_LAYOUT_SETTER_KEY)) return;
15458
+ if (getObjectPropertyByKey(pageOptions, WEVU_PAGE_LAYOUT_SETTER_KEY)) return;
14948
15459
  pageOptions.properties.push(t.objectMethod("method", createStaticObjectKey(WEVU_PAGE_LAYOUT_SETTER_KEY), [t.identifier("layout"), t.identifier("props")], t.blockStatement([
14949
15460
  t.variableDeclaration("const", [t.variableDeclarator(t.identifier(WEVU_PAGE_LAYOUT_NEXT_NAME_IDENTIFIER), t.conditionalExpression(t.binaryExpression("===", t.identifier("layout"), t.booleanLiteral(false)), t.stringLiteral(WEVU_PAGE_LAYOUT_NONE), t.identifier("layout")))]),
14950
15461
  t.variableDeclaration("const", [t.variableDeclarator(t.identifier(WEVU_PAGE_LAYOUT_NEXT_PROPS_IDENTIFIER), t.conditionalExpression(t.binaryExpression("===", t.identifier("layout"), t.booleanLiteral(false)), t.objectExpression([]), t.logicalExpression("||", t.identifier("props"), t.objectExpression([]))))]),
@@ -14975,15 +15486,15 @@ function buildInitialNativePageLayoutPropsExpression(currentLayout) {
14975
15486
  }
14976
15487
  function injectNativePageLayoutState(pageOptions, currentLayout) {
14977
15488
  const initialState = buildInitialNativePageLayoutState(currentLayout);
14978
- const existingData = getObjectPropertyByKey$1(pageOptions, "data");
15489
+ const existingData = getObjectPropertyByKey(pageOptions, "data");
14979
15490
  if (!existingData) {
14980
15491
  pageOptions.properties.unshift(t.objectProperty(createStaticObjectKey("data"), initialState));
14981
15492
  return;
14982
15493
  }
14983
15494
  if (t.isObjectExpression(existingData.value)) {
14984
15495
  const dataObject = existingData.value;
14985
- const layoutNameProp = getObjectPropertyByKey$1(dataObject, WEVU_PAGE_LAYOUT_NAME_KEY);
14986
- const layoutPropsProp = getObjectPropertyByKey$1(dataObject, WEVU_PAGE_LAYOUT_PROPS_KEY);
15496
+ const layoutNameProp = getObjectPropertyByKey(dataObject, WEVU_PAGE_LAYOUT_NAME_KEY);
15497
+ const layoutPropsProp = getObjectPropertyByKey(dataObject, WEVU_PAGE_LAYOUT_PROPS_KEY);
14987
15498
  if (!layoutNameProp) dataObject.properties.unshift(t.objectProperty(t.identifier(WEVU_PAGE_LAYOUT_NAME_KEY), buildInitialNativePageLayoutNameExpression(currentLayout)));
14988
15499
  if (!layoutPropsProp) dataObject.properties.push(t.objectProperty(t.identifier(WEVU_PAGE_LAYOUT_PROPS_KEY), buildInitialNativePageLayoutPropsExpression(currentLayout)));
14989
15500
  return;
@@ -21371,853 +21882,458 @@ function emitScopedSlotChunks(ctx, relativeBase, result, scopedSlotModules, emit
21371
21882
  preserveSignature: "exports-only"
21372
21883
  });
21373
21884
  emittedScopedSlotChunks.add(jsFile);
21374
- }
21375
- }
21376
- function resolveScopedSlotVirtualId(id) {
21377
- if (!id.startsWith(SCOPED_SLOT_VIRTUAL_PREFIX)) return null;
21378
- return id;
21379
- }
21380
- function loadScopedSlotModule(id, scopedSlotModules) {
21381
- if (!id.startsWith(SCOPED_SLOT_VIRTUAL_PREFIX)) return null;
21382
- const code = scopedSlotModules.get(id);
21383
- if (!code) return null;
21384
- return {
21385
- code,
21386
- map: null
21387
- };
21388
- }
21389
- //#endregion
21390
- //#region src/plugins/vue/transform/bundle/shared/assets.ts
21391
- const APP_VUE_LIKE_FILE_RE$1 = /[\\/]app\.(?:vue|jsx|tsx)$/;
21392
- async function processVueResultStyle(style, configService) {
21393
- if (!configService.platform) return style;
21394
- return await processCssWithCache(style, configService);
21395
- }
21396
- function resolveVueBundleAssetContext(configService) {
21397
- const outputExtensions = configService.outputExtensions;
21398
- const bundleOutputExtensions = resolveBundleOutputExtensions(outputExtensions);
21399
- return {
21400
- outputExtensions,
21401
- ...bundleOutputExtensions,
21402
- platformAssetOptions: resolveVueBundlePlatformAssetOptions({
21403
- configService,
21404
- templateExtension: bundleOutputExtensions.templateExtension,
21405
- scriptModuleExtension: bundleOutputExtensions.scriptModuleExtension
21406
- })
21407
- };
21408
- }
21409
- function emitSharedVueEntryJsonAsset(options) {
21410
- const normalizedConfig = preparePlatformConfigAsset(options.bundle, {
21411
- pluginCtx: options.pluginCtx,
21412
- relativeBase: options.relativeBase,
21413
- config: options.config,
21414
- kind: options.jsonOptions.kind,
21415
- outputExtensions: options.outputExtensions,
21416
- ...options.platformAssetOptions
21417
- });
21418
- emitSfcJsonAsset(options.pluginCtx, options.bundle, options.relativeBase, { config: normalizedConfig }, options.jsonOptions);
21419
- }
21420
- async function emitSharedFallbackPageAssets(options) {
21421
- const { bundle, pluginCtx, configService, relativeBase, result, outputExtensions, platformAssetOptions, styleExtension, jsonExtension, jsonDefaults, jsonMergeStrategy } = options;
21422
- if (result.style) emitSfcStyleIfMissing(pluginCtx, bundle, relativeBase, await processVueResultStyle(result.style, configService), styleExtension);
21423
- emitSharedVueEntryJsonAsset({
21424
- bundle,
21425
- pluginCtx,
21426
- relativeBase,
21427
- config: result.config,
21428
- outputExtensions,
21429
- platformAssetOptions,
21430
- jsonOptions: {
21431
- mergeExistingAsset: true,
21432
- mergeStrategy: jsonMergeStrategy,
21433
- defaults: jsonDefaults,
21434
- kind: "page",
21435
- extension: jsonExtension
21436
- }
21437
- });
21438
- }
21439
- function resolveClassStyleWxsAsset(ctx, relativeBase, wxsExtension, configService, result) {
21440
- if (!(Boolean(result.classStyleWxs) || Boolean(result.scopedSlotComponents?.some((slot) => slot.classStyleWxs))) || typeof wxsExtension !== "string" || wxsExtension.length === 0) return;
21441
- return {
21442
- fileName: resolveClassStyleWxsLocationForBase(ctx, relativeBase, wxsExtension, configService).fileName,
21443
- source: getClassStyleWxsSource({ extension: wxsExtension })
21444
- };
21445
- }
21446
- function emitSharedVueEntryAssets(options) {
21447
- const { bundle, pluginCtx, ctx, filename, relativeBase, result, configService, scriptModuleExtension, outputExtensions, platformAssetOptions, scopedSlotDefaults, scopedSlotMergeStrategy } = options;
21448
- const isAppVue = APP_VUE_LIKE_FILE_RE$1.test(filename);
21449
- if (result.template && !isAppVue) emitPlatformTemplateAsset(bundle, {
21450
- ctx,
21451
- pluginCtx,
21452
- filename,
21453
- relativeBase,
21454
- template: result.template,
21455
- ...platformAssetOptions
21456
- });
21457
- const classStyleWxs = resolveClassStyleWxsAsset(ctx, relativeBase, scriptModuleExtension, configService, result);
21458
- if (result.classStyleWxs && classStyleWxs) emitClassStyleWxsAssetIfMissing(pluginCtx, bundle, classStyleWxs.fileName, classStyleWxs.source);
21459
- emitScopedSlotAssets(pluginCtx, bundle, relativeBase, result, ctx, classStyleWxs, outputExtensions, {
21460
- defaults: scopedSlotDefaults,
21461
- mergeStrategy: scopedSlotMergeStrategy
21462
- });
21463
- injectLocalSlotFallbackWrapperUsingComponentIfNeeded({
21464
- bundle,
21465
- result,
21466
- compilerCtx: ctx,
21467
- outputExtensions
21468
- });
21469
- emitSlotFallbackWrapperComponentAsset({
21470
- ctx: pluginCtx,
21471
- bundle,
21472
- relativeBase,
21473
- result,
21474
- compilerCtx: ctx,
21475
- outputExtensions,
21476
- jsonOptions: {
21477
- defaults: scopedSlotDefaults,
21478
- mergeStrategy: scopedSlotMergeStrategy
21479
- }
21480
- });
21481
- return { classStyleWxs };
21482
- }
21483
- function emitBundleVueEntryAssets(options) {
21484
- const jsonConfig = options.configService.weappViteConfig?.json;
21485
- emitSharedVueEntryAssets({
21486
- ...options,
21487
- scopedSlotDefaults: jsonConfig?.defaults?.component,
21488
- scopedSlotMergeStrategy: jsonConfig?.mergeStrategy
21489
- });
21490
- return { jsonConfig };
21491
- }
21492
- async function emitFallbackPageBundleAssets(options) {
21493
- const { jsonConfig } = emitBundleVueEntryAssets({
21494
- bundle: options.bundle,
21495
- pluginCtx: options.pluginCtx,
21496
- ctx: options.ctx,
21497
- filename: options.filename,
21498
- relativeBase: options.relativeBase,
21499
- result: options.result,
21500
- configService: options.configService,
21501
- templateExtension: options.templateExtension,
21502
- scriptModuleExtension: options.scriptModuleExtension,
21503
- outputExtensions: options.outputExtensions,
21504
- platformAssetOptions: options.platformAssetOptions
21505
- });
21506
- await emitSharedFallbackPageAssets({
21507
- bundle: options.bundle,
21508
- pluginCtx: options.pluginCtx,
21509
- configService: options.configService,
21510
- relativeBase: options.relativeBase,
21511
- result: options.result,
21512
- outputExtensions: options.outputExtensions,
21513
- platformAssetOptions: options.platformAssetOptions,
21514
- styleExtension: options.styleExtension,
21515
- jsonExtension: options.jsonExtension,
21516
- jsonDefaults: jsonConfig?.defaults?.page,
21517
- jsonMergeStrategy: jsonConfig?.mergeStrategy
21518
- });
21519
- }
21520
- async function emitCompiledEntryBundleAssets(options) {
21521
- const isAppVue = APP_VUE_LIKE_FILE_RE$1.test(options.filename);
21522
- const hmrState = options.ctx.runtimeState?.build?.hmr;
21523
- const shouldEmitComponentJson = !isAppVue && !options.isPage;
21524
- const shouldMergeJsonAsset = isAppVue;
21525
- const jsonKind = isAppVue ? "app" : options.isPage ? "page" : "component";
21526
- const isAssetOnlyHmr = (hmrState?.profile?.dirtyReasonSummary)?.some((item) => item.startsWith("entry-local-asset:") || item.startsWith("style-sidecar:")) === true;
21527
- const isAppVueHmrUpdate = Boolean(isAppVue && options.configService.isDev && hmrState?.profile?.file === options.filename);
21528
- const sfcStyle = options.result.style;
21529
- const shouldEmitSfcStyleAsset = typeof sfcStyle === "string" && sfcStyle.length > 0 && (isAppVue && (!options.configService.isDev || isAppVueHmrUpdate) || options.configService.isDev && isAssetOnlyHmr && hmrState?.lastHmrEntryIds?.has(options.filename));
21530
- const { jsonConfig } = emitBundleVueEntryAssets({
21531
- bundle: options.bundle,
21532
- pluginCtx: options.pluginCtx,
21533
- ctx: options.ctx,
21534
- filename: options.filename,
21535
- relativeBase: options.relativeBase,
21536
- result: options.result,
21537
- configService: options.configService,
21538
- templateExtension: options.templateExtension,
21539
- scriptModuleExtension: options.scriptModuleExtension,
21540
- outputExtensions: options.outputExtensions,
21541
- platformAssetOptions: options.platformAssetOptions
21542
- });
21543
- if (shouldEmitSfcStyleAsset) {
21544
- const style = await processVueResultStyle(sfcStyle, options.configService);
21545
- emitSfcStyleIfMissing(options.pluginCtx, options.bundle, options.relativeBase, style, options.outputExtensions.wxss, isAppVue ? { updateExisting: false } : void 0);
21546
- }
21547
- if (options.result.config || shouldEmitComponentJson) emitSharedVueEntryJsonAsset({
21548
- bundle: options.bundle,
21549
- pluginCtx: options.pluginCtx,
21550
- relativeBase: options.relativeBase,
21551
- config: options.result.config,
21552
- outputExtensions: options.outputExtensions,
21553
- platformAssetOptions: options.platformAssetOptions,
21554
- jsonOptions: {
21555
- defaultConfig: shouldEmitComponentJson ? { component: true } : void 0,
21556
- mergeExistingAsset: shouldMergeJsonAsset,
21557
- mergeStrategy: jsonConfig?.mergeStrategy,
21558
- defaults: jsonConfig?.defaults?.[jsonKind],
21559
- kind: jsonKind,
21560
- extension: options.jsonExtension
21561
- }
21562
- });
21563
- return {
21564
- isAppVue,
21565
- shouldEmitComponentJson
21566
- };
21567
- }
21568
- //#endregion
21569
- //#region src/plugins/vue/transform/wevuPreset.ts
21570
- const PERFORMANCE_PRESET_DEFAULTS = {
21571
- app: { setData: {
21572
- strategy: "patch",
21573
- suspendWhenHidden: true,
21574
- diagnostics: "fallback",
21575
- highFrequencyWarning: {
21576
- enabled: true,
21577
- devOnly: true
21578
- }
21579
- } },
21580
- component: { setData: {
21581
- strategy: "patch",
21582
- suspendWhenHidden: true,
21583
- diagnostics: "fallback",
21584
- highFrequencyWarning: {
21585
- enabled: true,
21586
- devOnly: true
21587
- }
21588
- } }
21589
- };
21590
- function getPlainRecord(value) {
21591
- if (!value || typeof value !== "object" || Array.isArray(value)) return;
21592
- return value;
21593
- }
21594
- function mergeDefaults(defaults, options) {
21595
- if (!defaults) return options;
21596
- if (!options) return defaults;
21597
- const merged = {
21598
- ...defaults,
21599
- ...options
21600
- };
21601
- const defaultSetData = getPlainRecord(defaults.setData);
21602
- const optionSetData = getPlainRecord(options.setData);
21603
- if (defaultSetData || optionSetData) merged.setData = {
21604
- ...defaultSetData ?? {},
21605
- ...optionSetData ?? {}
21606
- };
21607
- const defaultOptions = getPlainRecord(defaults.options);
21608
- const optionOptions = getPlainRecord(options.options);
21609
- if (defaultOptions || optionOptions) merged.options = {
21610
- ...defaultOptions ?? {},
21611
- ...optionOptions ?? {}
21612
- };
21613
- return merged;
21614
- }
21615
- function mergeWevuDefaults(base, next) {
21616
- return {
21617
- app: mergeDefaults(base.app, next.app),
21618
- component: mergeDefaults(base.component, next.component)
21619
- };
21620
- }
21621
- /**
21622
- * 读取 wevu 预设名称。
21623
- */
21624
- function resolveWevuPreset(config) {
21625
- return config?.wevu?.preset;
21626
- }
21627
- /**
21628
- * 根据配置解析最终的 wevu defaults(预设 + 用户配置)。
21629
- */
21630
- function resolveWevuDefaultsWithPreset(config) {
21631
- const userDefaults = config?.wevu?.defaults;
21632
- if (resolveWevuPreset(config) !== "performance") return userDefaults;
21633
- return mergeWevuDefaults(PERFORMANCE_PRESET_DEFAULTS, userDefaults ?? {});
21634
- }
21635
- /**
21636
- * 根据配置判断是否启用自动 setData.pick 注入。
21637
- */
21638
- function isAutoSetDataPickEnabledWithPreset(config) {
21639
- const explicit = config?.wevu?.autoSetDataPick;
21640
- if (typeof explicit === "boolean") return explicit;
21641
- return resolveWevuPreset(config) === "performance";
21642
- }
21643
- /**
21644
- * 读取 wevu 输出是否压缩。
21645
- */
21646
- function isWevuMinifyEnabled(config, isDev = false) {
21647
- const explicit = config?.wevu?.minify;
21648
- if (typeof explicit === "boolean") return explicit;
21649
- return !isDev;
21650
- }
21651
- //#endregion
21652
- //#region src/plugins/vue/transform/compileOptions.ts
21653
- function hasVueExtension(id) {
21654
- return Boolean(id?.endsWith(".vue"));
21655
- }
21656
- function getCompileVueFileOptionsCacheKey(vuePath, isPage, isApp) {
21657
- return `${vuePath}::${isPage ? "page" : "component"}::${isApp ? "app" : "entry"}`;
21658
- }
21659
- function resolveVueTemplatePlatformOptions(options) {
21660
- const supportsWxs = options.wxsEnabled && typeof options.wxsExtension === "string" && options.wxsExtension.length > 0;
21661
- const resolvedWxsExtension = supportsWxs ? options.wxsExtension : void 0;
21662
- let classStyleRuntime = options.classStyleRuntime;
21663
- if (options.classStyleRuntime === "auto") classStyleRuntime = supportsWxs ? "wxs" : "js";
21664
- else if (options.classStyleRuntime === "wxs" && !supportsWxs) {
21665
- classStyleRuntime = "js";
21666
- if (!options.classStyleRuntimeWarned.value) {
21667
- logger_default.warn("已配置 vue.template.classStyleRuntime = \"wxs\",但当前平台不支持 WXS 或已禁用 weapp.wxs,将回退到 JS 运行时。");
21668
- options.classStyleRuntimeWarned.value = true;
21669
- }
21670
- }
21671
- return {
21672
- templatePlatform: getMiniProgramTemplatePlatform(options.platform),
21673
- supportsWxs,
21674
- wxsExtension: resolvedWxsExtension,
21675
- classStyleRuntime
21676
- };
21677
- }
21678
- function buildCompileVueFileOptions(ctx, pluginCtx, vuePath, isPage, isApp, configService, state) {
21679
- const importerBaseName = removeExtensionDeep(vuePath);
21680
- const autoImportResolveCache = /* @__PURE__ */ new Map();
21681
- const scopedSlotsCompiler = configService.weappViteConfig?.vue?.template?.scopedSlotsCompiler ?? "auto";
21682
- const scopedSlotsRequireProps = configService.weappViteConfig?.vue?.template?.scopedSlotsRequireProps ?? false;
21683
- const slotSingleRootNoWrapper = configService.weappViteConfig?.vue?.template?.slotSingleRootNoWrapper ?? false;
21684
- const slotFallbackWrapper = configService.weappViteConfig?.vue?.template?.slotFallbackWrapper;
21685
- const slotFallbackWrapperStrategy = configService.weappViteConfig?.vue?.template?.slotFallbackWrapperStrategy ?? (configService.platform === "weapp" && slotFallbackWrapper === void 0 ? "virtual-host" : "view");
21686
- const slotMultipleInstance = configService.weappViteConfig?.vue?.template?.slotMultipleInstance ?? true;
21687
- const htmlTagToWxml = configService.weappViteConfig?.vue?.template?.htmlTagToWxml;
21688
- const htmlTagToWxmlTagClass = configService.weappViteConfig?.vue?.template?.htmlTagToWxmlTagClass ?? true;
21689
- const classStyleRuntimeConfig = configService.weappViteConfig?.vue?.template?.classStyleRuntime ?? "js";
21690
- const objectLiteralBindMode = configService.weappViteConfig?.vue?.template?.objectLiteralBindMode ?? "runtime";
21691
- const mustacheInterpolation = configService.weappViteConfig?.vue?.template?.mustacheInterpolation ?? "compact";
21692
- const functionPropNames = configService.weappViteConfig?.vue?.template?.functionPropNames;
21693
- const formatWxmlConfig = configService.weappViteConfig?.vue?.template?.formatWxml ?? "auto";
21694
- const formatWxml = formatWxmlConfig === "auto" ? configService.isDev : formatWxmlConfig;
21695
- const wxsEnabled = configService.weappViteConfig?.wxs !== false;
21696
- const wxsExtension = configService.outputExtensions?.wxs;
21697
- const templatePlatformOptions = resolveVueTemplatePlatformOptions({
21698
- platform: configService.platform,
21699
- wxsEnabled,
21700
- wxsExtension,
21701
- classStyleRuntime: classStyleRuntimeConfig,
21702
- classStyleRuntimeWarned: state.classStyleRuntimeWarned
21703
- });
21704
- const relativeBase = configService.relativeOutputPath(vuePath.slice(0, -4));
21705
- const resolvedWxsExtension = templatePlatformOptions.wxsExtension;
21706
- let classStyleWxsSrc;
21707
- if (resolvedWxsExtension && relativeBase) classStyleWxsSrc = resolveClassStyleWxsLocationForBase(ctx, relativeBase, resolvedWxsExtension, configService).src;
21708
- const jsonConfig = configService.weappViteConfig?.json;
21709
- const wevuDefaults = resolveWevuDefaultsWithPreset(configService.weappViteConfig);
21710
- const wevuMinify = isWevuMinifyEnabled(configService.weappViteConfig, configService.isDev);
21711
- const jsonKind = isApp ? "app" : isPage ? "page" : "component";
21712
- async function resolvePotentialVueSfcEntryId(candidate) {
21713
- const trimmed = candidate?.trim();
21714
- if (!trimmed) return;
21715
- const entryResolveOptions = createCachedEntryResolveOptions(configService, { kind: "default" });
21716
- const localCandidate = path.isAbsolute(trimmed) ? trimmed : trimmed.startsWith(".") ? path.resolve(path.dirname(vuePath), trimmed) : !trimmed.includes(":") && !trimmed.startsWith("@") ? path.resolve(configService.absoluteSrcRoot, trimmed) : void 0;
21717
- if (localCandidate) {
21718
- const normalized = normalizeFsResolvedId(localCandidate);
21719
- if (hasVueExtension(normalized)) return normalized;
21720
- const resolvedEntry = !normalized || isSkippableResolvedId(normalized) ? void 0 : await resolveEntryPath(normalized, entryResolveOptions);
21721
- if (hasVueExtension(resolvedEntry)) return resolvedEntry;
21722
- }
21723
- const resolveCandidates = path.extname(trimmed) ? [trimmed] : [
21724
- trimmed,
21725
- `${trimmed}.vue`,
21726
- `${trimmed}/index.vue`
21727
- ];
21728
- for (const resolveCandidate of resolveCandidates) {
21729
- const resolved = await pluginCtx.resolve?.(resolveCandidate, vuePath);
21730
- const normalized = resolved?.id ? normalizeFsResolvedId(resolved.id) : void 0;
21731
- if (!normalized || isSkippableResolvedId(normalized)) continue;
21732
- if (hasVueExtension(normalized)) return normalized;
21733
- if (path.isAbsolute(normalized)) {
21734
- const resolvedEntry = await resolveEntryPath(normalized, entryResolveOptions);
21735
- if (hasVueExtension(resolvedEntry)) return resolvedEntry;
21736
- }
21737
- }
21738
- }
21739
- async function resolveAutoImportComponentSourceType(match) {
21740
- if (match.kind === "local") {
21741
- const resolvedId = match.entry.templatePath;
21742
- return {
21743
- resolvedId,
21744
- sourceType: hasVueExtension(resolvedId) ? "wevu-sfc" : "native"
21745
- };
21746
- }
21747
- const explicitSourceType = match.value.sourceType;
21748
- const explicitResolvedId = match.value.resolvedId;
21749
- const resolvedExplicitVueId = await resolvePotentialVueSfcEntryId(explicitResolvedId);
21750
- if (explicitSourceType || resolvedExplicitVueId || hasVueExtension(explicitResolvedId) || hasVueExtension(match.value.from)) return {
21751
- resolvedId: resolvedExplicitVueId ?? explicitResolvedId,
21752
- sourceType: explicitSourceType ?? (resolvedExplicitVueId || hasVueExtension(explicitResolvedId) || hasVueExtension(match.value.from) ? "wevu-sfc" : "native")
21753
- };
21754
- let localSourceBase;
21755
- if (match.value.from.startsWith("/")) localSourceBase = path.join(configService.absoluteSrcRoot, match.value.from.slice(1));
21756
- else if (match.value.from.startsWith(".")) localSourceBase = path.resolve(path.dirname(importerBaseName), match.value.from);
21757
- if (!localSourceBase) return {
21758
- resolvedId: explicitResolvedId,
21759
- sourceType: "native"
21760
- };
21761
- const resolvedId = await resolveEntryPath(localSourceBase, createCachedEntryResolveOptions(configService, { kind: "default" }));
21762
- return {
21763
- resolvedId,
21764
- sourceType: hasVueExtension(resolvedId) ? "wevu-sfc" : "native"
21765
- };
21766
- }
21767
- return {
21768
- isPage,
21769
- isApp,
21770
- warn: (message) => logger_default.warn(message),
21771
- autoUsingComponents: {
21772
- enabled: true,
21773
- warn: (message) => logger_default.warn(message),
21774
- resolveUsingComponentPath: createUsingComponentPathResolver(pluginCtx, configService, state.reExportResolutionCache)
21775
- },
21776
- autoImportTags: {
21777
- enabled: true,
21778
- warn: (message) => logger_default.warn(message),
21779
- resolveUsingComponent: async (tag) => {
21780
- const autoImportService = ctx.autoImportService;
21781
- if (!autoImportService) return;
21782
- const version = typeof autoImportService.getVersion === "function" ? autoImportService.getVersion() : 0;
21783
- const cached = autoImportResolveCache.get(tag);
21784
- const match = cached && cached.version === version ? cached.match : autoImportService.resolve(tag, importerBaseName);
21785
- if (!cached || cached.version !== version) autoImportResolveCache.set(tag, {
21786
- match,
21787
- version
21788
- });
21789
- if (!match?.value) return;
21790
- const sourceInfo = await resolveAutoImportComponentSourceType(match);
21791
- return {
21792
- ...match.value,
21793
- ...sourceInfo
21794
- };
21795
- }
21796
- },
21797
- template: {
21798
- platform: templatePlatformOptions.templatePlatform,
21799
- htmlTagToWxml,
21800
- htmlTagToWxmlTagClass,
21801
- scopedSlotsCompiler,
21802
- scopedSlotsRequireProps,
21803
- slotSingleRootNoWrapper,
21804
- slotFallbackWrapper,
21805
- slotFallbackWrapperStrategy,
21806
- slotMultipleInstance,
21807
- classStyleRuntime: templatePlatformOptions.classStyleRuntime,
21808
- objectLiteralBindMode,
21809
- mustacheInterpolation,
21810
- functionPropNames,
21811
- formatWxml,
21812
- wxsExtension: templatePlatformOptions.wxsExtension,
21813
- classStyleWxsSrc
21814
- },
21815
- json: {
21816
- kind: jsonKind,
21817
- defaults: jsonConfig?.defaults,
21818
- mergeStrategy: jsonConfig?.mergeStrategy
21819
- },
21820
- sfcSrc: createSfcResolveSrcOptions(pluginCtx, configService),
21821
- wevuDefaults,
21822
- minify: wevuMinify
21823
- };
21824
- }
21825
- function createCompileVueFileOptions(ctx, pluginCtx, vuePath, isPage, isApp, configService, state) {
21826
- const cacheKey = getCompileVueFileOptionsCacheKey(vuePath, isPage, isApp);
21827
- const cached = state.compileOptionsCache?.get(cacheKey);
21828
- if (cached) return cached;
21829
- const created = buildCompileVueFileOptions(ctx, pluginCtx, vuePath, isPage, isApp, configService, state);
21830
- state.compileOptionsCache?.set(cacheKey, created);
21831
- return created;
21832
- }
21833
- //#endregion
21834
- //#region src/utils/sourcemap.ts
21835
- function isEncodedSourceMapLike(value) {
21836
- return Boolean(value && typeof value === "object" && "version" in value && typeof value.version === "number" && "mappings" in value && "names" in value && "sources" in value);
21885
+ }
21837
21886
  }
21838
- function normalizeEncodedSourceMapLike(value) {
21839
- if (!value || typeof value !== "object") return null;
21840
- const sourceMap = value;
21841
- const numericVersion = typeof sourceMap.version === "number" ? sourceMap.version : typeof sourceMap.version === "string" ? Number(sourceMap.version) : NaN;
21842
- if (!Number.isFinite(numericVersion)) return null;
21843
- const normalized = {
21844
- ...sourceMap,
21845
- version: numericVersion
21846
- };
21847
- return isEncodedSourceMapLike(normalized) ? normalized : null;
21887
+ function resolveScopedSlotVirtualId(id) {
21888
+ if (!id.startsWith(SCOPED_SLOT_VIRTUAL_PREFIX)) return null;
21889
+ return id;
21848
21890
  }
21849
- function composeSourceMaps(transformedMap, originalMap) {
21850
- if (isEncodedSourceMapLike(transformedMap) && isEncodedSourceMapLike(originalMap)) return remapping([transformedMap, originalMap], () => null);
21851
- if (isEncodedSourceMapLike(transformedMap)) return transformedMap;
21852
- if (isEncodedSourceMapLike(originalMap)) return originalMap;
21853
- return null;
21891
+ function loadScopedSlotModule(id, scopedSlotModules) {
21892
+ if (!id.startsWith(SCOPED_SLOT_VIRTUAL_PREFIX)) return null;
21893
+ const code = scopedSlotModules.get(id);
21894
+ if (!code) return null;
21895
+ return {
21896
+ code,
21897
+ map: null
21898
+ };
21854
21899
  }
21855
21900
  //#endregion
21856
- //#region src/plugins/utils/viteResolverAdapter.ts
21857
- const WINDOWS_ABSOLUTE_PATH_RE = /^[A-Z]:[\\/]/i;
21858
- function isExplicitFileRequest(id) {
21859
- return id.startsWith(".") || id.startsWith("/") || WINDOWS_ABSOLUTE_PATH_RE.test(id);
21860
- }
21861
- function isFilePathLike(id) {
21862
- return Boolean(path.extname(id));
21863
- }
21864
- function resolveLocalFile(source, importer, normalizeOptions) {
21865
- const cleanSource = normalizeFsResolvedId(source, normalizeOptions);
21866
- if (!isExplicitFileRequest(cleanSource) || !isFilePathLike(cleanSource)) return;
21867
- const candidate = path.isAbsolute(cleanSource) || WINDOWS_ABSOLUTE_PATH_RE.test(cleanSource) ? cleanSource : importer ? path.resolve(path.dirname(normalizeFsResolvedId(importer, normalizeOptions)), cleanSource) : void 0;
21868
- if (!candidate) return;
21869
- try {
21870
- return fs$1.statSync(candidate).isFile() ? candidate : void 0;
21871
- } catch {
21872
- return;
21873
- }
21901
+ //#region src/plugins/vue/transform/bundle/shared/assets.ts
21902
+ const APP_VUE_LIKE_FILE_RE$1 = /[\\/]app\.(?:vue|jsx|tsx)$/;
21903
+ async function processVueResultStyle(style, configService) {
21904
+ if (!configService.platform) return style;
21905
+ return await processCssWithCache(style, configService);
21874
21906
  }
21875
- function createViteResolverAdapter(resolver, reader, options) {
21876
- const checkMtime = options?.checkMtime;
21877
- const normalizeOptions = options?.normalize;
21907
+ function resolveVueBundleAssetContext(configService) {
21908
+ const outputExtensions = configService.outputExtensions;
21909
+ const bundleOutputExtensions = resolveBundleOutputExtensions(outputExtensions);
21878
21910
  return {
21879
- resolveId: async (source, importer) => {
21880
- const localFile = resolveLocalFile(source, importer, normalizeOptions);
21881
- if (localFile) return localFile;
21882
- const resolved = await resolver.resolve(source, importer);
21883
- return resolved ? resolved.id : void 0;
21884
- },
21885
- loadCode: async (resolvedId) => {
21886
- const clean = normalizeFsResolvedId(resolvedId, normalizeOptions);
21887
- if (isSkippableResolvedId(clean)) return;
21888
- try {
21889
- return await reader.readFile(clean, { checkMtime });
21890
- } catch {
21891
- return;
21892
- }
21893
- }
21911
+ outputExtensions,
21912
+ ...bundleOutputExtensions,
21913
+ platformAssetOptions: resolveVueBundlePlatformAssetOptions({
21914
+ configService,
21915
+ templateExtension: bundleOutputExtensions.templateExtension,
21916
+ scriptModuleExtension: bundleOutputExtensions.scriptModuleExtension
21917
+ })
21894
21918
  };
21895
21919
  }
21896
- //#endregion
21897
- //#region src/plugins/vue/transform/injectPageFeatures.ts
21898
- async function injectWevuPageFeaturesInJsWithViteResolver(ctx, source, id, options) {
21899
- const checkMtime = options?.checkMtime ?? true;
21900
- const injected = await injectWevuPageFeaturesInJsWithResolver(source, {
21901
- id,
21902
- resolver: createViteResolverAdapter({ resolve: (source, importer) => ctx.resolve(source, importer) }, { readFile: readFile$1 }, { checkMtime }),
21903
- minify: options?.minify
21920
+ function emitSharedVueEntryJsonAsset(options) {
21921
+ const normalizedConfig = preparePlatformConfigAsset(options.bundle, {
21922
+ pluginCtx: options.pluginCtx,
21923
+ relativeBase: options.relativeBase,
21924
+ config: options.config,
21925
+ kind: options.jsonOptions.kind,
21926
+ outputExtensions: options.outputExtensions,
21927
+ ...options.platformAssetOptions
21904
21928
  });
21905
- return {
21906
- ...injected,
21907
- map: normalizeEncodedSourceMapLike(injected.map)
21908
- };
21929
+ emitSfcJsonAsset(options.pluginCtx, options.bundle, options.relativeBase, { config: normalizedConfig }, options.jsonOptions);
21909
21930
  }
21910
- //#endregion
21911
- //#region src/plugins/vue/transform/injectSetDataPick.ts
21912
- /**
21913
- * 根据配置判断是否启用自动 setData.pick 注入。
21914
- */
21915
- function isAutoSetDataPickEnabled(config) {
21916
- return isAutoSetDataPickEnabledWithPreset(config);
21931
+ async function emitSharedFallbackPageAssets(options) {
21932
+ const { bundle, pluginCtx, configService, relativeBase, result, outputExtensions, platformAssetOptions, styleExtension, jsonExtension, jsonDefaults, jsonMergeStrategy } = options;
21933
+ if (result.style) emitSfcStyleIfMissing(pluginCtx, bundle, relativeBase, await processVueResultStyle(result.style, configService), styleExtension);
21934
+ emitSharedVueEntryJsonAsset({
21935
+ bundle,
21936
+ pluginCtx,
21937
+ relativeBase,
21938
+ config: result.config,
21939
+ outputExtensions,
21940
+ platformAssetOptions,
21941
+ jsonOptions: {
21942
+ mergeExistingAsset: true,
21943
+ mergeStrategy: jsonMergeStrategy,
21944
+ defaults: jsonDefaults,
21945
+ kind: "page",
21946
+ extension: jsonExtension
21947
+ }
21948
+ });
21917
21949
  }
21918
- function isTargetWevuComponentCall(callee) {
21919
- if (callee.type === "Identifier") return callee.name === "createWevuComponent" || callee.name === "defineComponent";
21920
- if (callee.type !== "MemberExpression" || callee.computed) return false;
21921
- return callee.property.type === "Identifier" && (callee.property.name === "createWevuComponent" || callee.property.name === "defineComponent");
21950
+ function resolveClassStyleWxsAsset(ctx, relativeBase, wxsExtension, configService, result) {
21951
+ if (!(Boolean(result.classStyleWxs) || Boolean(result.scopedSlotComponents?.some((slot) => slot.classStyleWxs))) || typeof wxsExtension !== "string" || wxsExtension.length === 0) return;
21952
+ return {
21953
+ fileName: resolveClassStyleWxsLocationForBase(ctx, relativeBase, wxsExtension, configService).fileName,
21954
+ source: getClassStyleWxsSource({ extension: wxsExtension })
21955
+ };
21922
21956
  }
21923
- /**
21924
- * 通过轻量字符串特征快速判断脚本是否可能需要注入 setData.pick。
21925
- */
21926
- function mayNeedInjectSetDataPickInJs(source) {
21927
- return source.includes("createWevuComponent") || source.includes("defineComponent");
21957
+ function emitSharedVueEntryAssets(options) {
21958
+ const { bundle, pluginCtx, ctx, filename, relativeBase, result, configService, scriptModuleExtension, outputExtensions, platformAssetOptions, scopedSlotDefaults, scopedSlotMergeStrategy } = options;
21959
+ const isAppVue = APP_VUE_LIKE_FILE_RE$1.test(filename);
21960
+ if (result.template && !isAppVue) emitPlatformTemplateAsset(bundle, {
21961
+ ctx,
21962
+ pluginCtx,
21963
+ filename,
21964
+ relativeBase,
21965
+ template: result.template,
21966
+ ...platformAssetOptions
21967
+ });
21968
+ const classStyleWxs = resolveClassStyleWxsAsset(ctx, relativeBase, scriptModuleExtension, configService, result);
21969
+ if (result.classStyleWxs && classStyleWxs) emitClassStyleWxsAssetIfMissing(pluginCtx, bundle, classStyleWxs.fileName, classStyleWxs.source);
21970
+ emitScopedSlotAssets(pluginCtx, bundle, relativeBase, result, ctx, classStyleWxs, outputExtensions, {
21971
+ defaults: scopedSlotDefaults,
21972
+ mergeStrategy: scopedSlotMergeStrategy
21973
+ });
21974
+ injectLocalSlotFallbackWrapperUsingComponentIfNeeded({
21975
+ bundle,
21976
+ result,
21977
+ compilerCtx: ctx,
21978
+ outputExtensions
21979
+ });
21980
+ emitSlotFallbackWrapperComponentAsset({
21981
+ ctx: pluginCtx,
21982
+ bundle,
21983
+ relativeBase,
21984
+ result,
21985
+ compilerCtx: ctx,
21986
+ outputExtensions,
21987
+ jsonOptions: {
21988
+ defaults: scopedSlotDefaults,
21989
+ mergeStrategy: scopedSlotMergeStrategy
21990
+ }
21991
+ });
21992
+ return { classStyleWxs };
21928
21993
  }
21929
- function getObjectPropertyByKey(objectExpression, key) {
21930
- for (const member of objectExpression.properties) {
21931
- if (member.type !== "ObjectProperty") continue;
21932
- if (member.key.type === "Identifier" && member.key.name === key) return member;
21933
- if (member.key.type === "StringLiteral" && member.key.value === key) return member;
21934
- }
21994
+ function emitBundleVueEntryAssets(options) {
21995
+ const jsonConfig = options.configService.weappViteConfig?.json;
21996
+ emitSharedVueEntryAssets({
21997
+ ...options,
21998
+ scopedSlotDefaults: jsonConfig?.defaults?.component,
21999
+ scopedSlotMergeStrategy: jsonConfig?.mergeStrategy
22000
+ });
22001
+ return { jsonConfig };
21935
22002
  }
21936
- function unwrapExpression(node) {
21937
- let current = node;
21938
- while (true) {
21939
- if (current.type === "TSAsExpression" || current.type === "TSTypeAssertion" || current.type === "TSNonNullExpression" || current.type === "ParenthesizedExpression" || current.type === "TSSatisfiesExpression") {
21940
- current = current.expression;
21941
- continue;
21942
- }
21943
- return current;
21944
- }
22003
+ async function emitFallbackPageBundleAssets(options) {
22004
+ const { jsonConfig } = emitBundleVueEntryAssets({
22005
+ bundle: options.bundle,
22006
+ pluginCtx: options.pluginCtx,
22007
+ ctx: options.ctx,
22008
+ filename: options.filename,
22009
+ relativeBase: options.relativeBase,
22010
+ result: options.result,
22011
+ configService: options.configService,
22012
+ templateExtension: options.templateExtension,
22013
+ scriptModuleExtension: options.scriptModuleExtension,
22014
+ outputExtensions: options.outputExtensions,
22015
+ platformAssetOptions: options.platformAssetOptions
22016
+ });
22017
+ await emitSharedFallbackPageAssets({
22018
+ bundle: options.bundle,
22019
+ pluginCtx: options.pluginCtx,
22020
+ configService: options.configService,
22021
+ relativeBase: options.relativeBase,
22022
+ result: options.result,
22023
+ outputExtensions: options.outputExtensions,
22024
+ platformAssetOptions: options.platformAssetOptions,
22025
+ styleExtension: options.styleExtension,
22026
+ jsonExtension: options.jsonExtension,
22027
+ jsonDefaults: jsonConfig?.defaults?.page,
22028
+ jsonMergeStrategy: jsonConfig?.mergeStrategy
22029
+ });
21945
22030
  }
21946
- function resolveOptionsObjectExpression(expression, scope) {
21947
- if (!expression) return;
21948
- const unwrapped = unwrapExpression(expression);
21949
- if (unwrapped.type === "ObjectExpression") return unwrapped;
21950
- if (unwrapped.type === "Identifier") {
21951
- const binding = scope.getBinding(unwrapped.name);
21952
- if (!binding || !binding.path.isVariableDeclarator()) return;
21953
- const init = binding.path.node.init;
21954
- if (!init || init.type !== "ObjectExpression" && init.type !== "CallExpression" && init.type !== "Identifier") return;
21955
- return resolveOptionsObjectExpression(init, binding.path.scope);
22031
+ async function emitCompiledEntryBundleAssets(options) {
22032
+ const isAppVue = APP_VUE_LIKE_FILE_RE$1.test(options.filename);
22033
+ const hmrState = options.ctx.runtimeState?.build?.hmr;
22034
+ const shouldEmitComponentJson = !isAppVue && !options.isPage;
22035
+ const shouldMergeJsonAsset = isAppVue;
22036
+ const jsonKind = isAppVue ? "app" : options.isPage ? "page" : "component";
22037
+ const isAssetOnlyHmr = (hmrState?.profile?.dirtyReasonSummary)?.some((item) => item.startsWith("entry-local-asset:") || item.startsWith("style-sidecar:")) === true;
22038
+ const isAppVueHmrUpdate = Boolean(isAppVue && options.configService.isDev && hmrState?.profile?.file === options.filename);
22039
+ const sfcStyle = options.result.style;
22040
+ const shouldEmitSfcStyleAsset = typeof sfcStyle === "string" && sfcStyle.length > 0 && (isAppVue && (!options.configService.isDev || isAppVueHmrUpdate) || options.configService.isDev && isAssetOnlyHmr && hmrState?.lastHmrEntryIds?.has(options.filename));
22041
+ const { jsonConfig } = emitBundleVueEntryAssets({
22042
+ bundle: options.bundle,
22043
+ pluginCtx: options.pluginCtx,
22044
+ ctx: options.ctx,
22045
+ filename: options.filename,
22046
+ relativeBase: options.relativeBase,
22047
+ result: options.result,
22048
+ configService: options.configService,
22049
+ templateExtension: options.templateExtension,
22050
+ scriptModuleExtension: options.scriptModuleExtension,
22051
+ outputExtensions: options.outputExtensions,
22052
+ platformAssetOptions: options.platformAssetOptions
22053
+ });
22054
+ if (shouldEmitSfcStyleAsset) {
22055
+ const style = await processVueResultStyle(sfcStyle, options.configService);
22056
+ emitSfcStyleIfMissing(options.pluginCtx, options.bundle, options.relativeBase, style, options.outputExtensions.wxss, isAppVue ? { updateExisting: false } : void 0);
21956
22057
  }
21957
- if (unwrapped.type === "CallExpression" && unwrapped.callee.type === "MemberExpression" && !unwrapped.callee.computed && unwrapped.callee.object.type === "Identifier" && unwrapped.callee.object.name === "Object" && unwrapped.callee.property.type === "Identifier" && unwrapped.callee.property.name === "assign") for (let i = unwrapped.arguments.length - 1; i >= 0; i--) {
21958
- const arg = unwrapped.arguments[i];
21959
- if (arg.type !== "SpreadElement") {
21960
- const resolved = resolveOptionsObjectExpression(arg, scope);
21961
- if (resolved) return resolved;
22058
+ if (options.result.config || shouldEmitComponentJson) emitSharedVueEntryJsonAsset({
22059
+ bundle: options.bundle,
22060
+ pluginCtx: options.pluginCtx,
22061
+ relativeBase: options.relativeBase,
22062
+ config: options.result.config,
22063
+ outputExtensions: options.outputExtensions,
22064
+ platformAssetOptions: options.platformAssetOptions,
22065
+ jsonOptions: {
22066
+ defaultConfig: shouldEmitComponentJson ? { component: true } : void 0,
22067
+ mergeExistingAsset: shouldMergeJsonAsset,
22068
+ mergeStrategy: jsonConfig?.mergeStrategy,
22069
+ defaults: jsonConfig?.defaults?.[jsonKind],
22070
+ kind: jsonKind,
22071
+ extension: options.jsonExtension
21962
22072
  }
21963
- }
21964
- }
21965
- function createPickArrayExpression(keys) {
22073
+ });
21966
22074
  return {
21967
- type: "ArrayExpression",
21968
- elements: keys.map((key) => ({
21969
- type: "StringLiteral",
21970
- value: key
21971
- }))
22075
+ isAppVue,
22076
+ shouldEmitComponentJson
21972
22077
  };
21973
22078
  }
21974
- function mergeStableKeys(keys, stableKeys) {
21975
- const merged = [];
21976
- const seen = /* @__PURE__ */ new Set();
21977
- for (const key of [...keys, ...stableKeys]) {
21978
- if (seen.has(key)) continue;
21979
- seen.add(key);
21980
- merged.push(key);
21981
- }
21982
- return merged;
22079
+ //#endregion
22080
+ //#region src/plugins/vue/transform/compileOptions.ts
22081
+ function hasVueExtension(id) {
22082
+ return Boolean(id?.endsWith(".vue"));
21983
22083
  }
21984
- function mergePickArrayExpression(arrayExpression, keys) {
21985
- const existing = /* @__PURE__ */ new Set();
21986
- for (const element of arrayExpression.elements) if (element && element.type === "StringLiteral") existing.add(element.value);
21987
- let changed = false;
21988
- for (const key of keys) {
21989
- if (existing.has(key)) continue;
21990
- arrayExpression.elements.push({
21991
- type: "StringLiteral",
21992
- value: key
21993
- });
21994
- existing.add(key);
21995
- changed = true;
21996
- }
21997
- return changed;
22084
+ function getCompileVueFileOptionsCacheKey(vuePath, isPage, isApp) {
22085
+ return `${vuePath}::${isPage ? "page" : "component"}::${isApp ? "app" : "entry"}`;
21998
22086
  }
21999
- function injectPickIntoSetDataObject(setDataObject, keys) {
22000
- const pickProp = getObjectPropertyByKey(setDataObject, "pick");
22001
- if (!pickProp) {
22002
- setDataObject.properties.unshift({
22003
- type: "ObjectProperty",
22004
- key: {
22005
- type: "Identifier",
22006
- name: "pick"
22007
- },
22008
- computed: false,
22009
- shorthand: false,
22010
- value: createPickArrayExpression(keys)
22011
- });
22012
- return true;
22087
+ function resolveVueTemplatePlatformOptions(options) {
22088
+ const supportsWxs = options.wxsEnabled && typeof options.wxsExtension === "string" && options.wxsExtension.length > 0;
22089
+ const resolvedWxsExtension = supportsWxs ? options.wxsExtension : void 0;
22090
+ let classStyleRuntime = options.classStyleRuntime;
22091
+ if (options.classStyleRuntime === "auto") classStyleRuntime = supportsWxs ? "wxs" : "js";
22092
+ else if (options.classStyleRuntime === "wxs" && !supportsWxs) {
22093
+ classStyleRuntime = "js";
22094
+ if (!options.classStyleRuntimeWarned.value) {
22095
+ logger_default.warn("已配置 vue.template.classStyleRuntime = \"wxs\",但当前平台不支持 WXS 或已禁用 weapp.wxs,将回退到 JS 运行时。");
22096
+ options.classStyleRuntimeWarned.value = true;
22097
+ }
22013
22098
  }
22014
- if (pickProp.value.type !== "ArrayExpression") return false;
22015
- return mergePickArrayExpression(pickProp.value, keys);
22099
+ return {
22100
+ templatePlatform: getMiniProgramTemplatePlatform(options.platform),
22101
+ supportsWxs,
22102
+ wxsExtension: resolvedWxsExtension,
22103
+ classStyleRuntime
22104
+ };
22016
22105
  }
22017
- function injectPickIntoOptionsObject(optionsObject, keys) {
22018
- const setDataProp = getObjectPropertyByKey(optionsObject, "setData");
22019
- if (!setDataProp) {
22020
- optionsObject.properties.unshift({
22021
- type: "ObjectProperty",
22022
- key: {
22023
- type: "Identifier",
22024
- name: "setData"
22025
- },
22026
- computed: false,
22027
- shorthand: false,
22028
- value: {
22029
- type: "ObjectExpression",
22030
- properties: [{
22031
- type: "ObjectProperty",
22032
- key: {
22033
- type: "Identifier",
22034
- name: "pick"
22035
- },
22036
- computed: false,
22037
- shorthand: false,
22038
- value: createPickArrayExpression(keys)
22039
- }]
22106
+ function buildCompileVueFileOptions(ctx, pluginCtx, vuePath, isPage, isApp, configService, state) {
22107
+ const importerBaseName = removeExtensionDeep(vuePath);
22108
+ const autoImportResolveCache = /* @__PURE__ */ new Map();
22109
+ const scopedSlotsCompiler = configService.weappViteConfig?.vue?.template?.scopedSlotsCompiler ?? "auto";
22110
+ const scopedSlotsRequireProps = configService.weappViteConfig?.vue?.template?.scopedSlotsRequireProps ?? false;
22111
+ const slotSingleRootNoWrapper = configService.weappViteConfig?.vue?.template?.slotSingleRootNoWrapper ?? false;
22112
+ const slotFallbackWrapper = configService.weappViteConfig?.vue?.template?.slotFallbackWrapper;
22113
+ const slotFallbackWrapperStrategy = configService.weappViteConfig?.vue?.template?.slotFallbackWrapperStrategy ?? (configService.platform === "weapp" && slotFallbackWrapper === void 0 ? "virtual-host" : "view");
22114
+ const slotMultipleInstance = configService.weappViteConfig?.vue?.template?.slotMultipleInstance ?? true;
22115
+ const htmlTagToWxml = configService.weappViteConfig?.vue?.template?.htmlTagToWxml;
22116
+ const htmlTagToWxmlTagClass = configService.weappViteConfig?.vue?.template?.htmlTagToWxmlTagClass ?? true;
22117
+ const classStyleRuntimeConfig = configService.weappViteConfig?.vue?.template?.classStyleRuntime ?? "js";
22118
+ const objectLiteralBindMode = configService.weappViteConfig?.vue?.template?.objectLiteralBindMode ?? "runtime";
22119
+ const mustacheInterpolation = configService.weappViteConfig?.vue?.template?.mustacheInterpolation ?? "compact";
22120
+ const functionPropNames = configService.weappViteConfig?.vue?.template?.functionPropNames;
22121
+ const formatWxmlConfig = configService.weappViteConfig?.vue?.template?.formatWxml ?? "auto";
22122
+ const formatWxml = formatWxmlConfig === "auto" ? configService.isDev : formatWxmlConfig;
22123
+ const wxsEnabled = configService.weappViteConfig?.wxs !== false;
22124
+ const wxsExtension = configService.outputExtensions?.wxs;
22125
+ const templatePlatformOptions = resolveVueTemplatePlatformOptions({
22126
+ platform: configService.platform,
22127
+ wxsEnabled,
22128
+ wxsExtension,
22129
+ classStyleRuntime: classStyleRuntimeConfig,
22130
+ classStyleRuntimeWarned: state.classStyleRuntimeWarned
22131
+ });
22132
+ const relativeBase = configService.relativeOutputPath(vuePath.slice(0, -4));
22133
+ const resolvedWxsExtension = templatePlatformOptions.wxsExtension;
22134
+ let classStyleWxsSrc;
22135
+ if (resolvedWxsExtension && relativeBase) classStyleWxsSrc = resolveClassStyleWxsLocationForBase(ctx, relativeBase, resolvedWxsExtension, configService).src;
22136
+ const jsonConfig = configService.weappViteConfig?.json;
22137
+ const wevuDefaults = resolveWevuDefaultsWithPreset(configService.weappViteConfig);
22138
+ const wevuMinify = isWevuMinifyEnabled(configService.weappViteConfig, configService.isDev);
22139
+ const jsonKind = isApp ? "app" : isPage ? "page" : "component";
22140
+ async function resolvePotentialVueSfcEntryId(candidate) {
22141
+ const trimmed = candidate?.trim();
22142
+ if (!trimmed) return;
22143
+ const entryResolveOptions = createCachedEntryResolveOptions(configService, { kind: "default" });
22144
+ const localCandidate = path.isAbsolute(trimmed) ? trimmed : trimmed.startsWith(".") ? path.resolve(path.dirname(vuePath), trimmed) : !trimmed.includes(":") && !trimmed.startsWith("@") ? path.resolve(configService.absoluteSrcRoot, trimmed) : void 0;
22145
+ if (localCandidate) {
22146
+ const normalized = normalizeFsResolvedId(localCandidate);
22147
+ if (hasVueExtension(normalized)) return normalized;
22148
+ const resolvedEntry = !normalized || isSkippableResolvedId(normalized) ? void 0 : await resolveEntryPath(normalized, entryResolveOptions);
22149
+ if (hasVueExtension(resolvedEntry)) return resolvedEntry;
22150
+ }
22151
+ const resolveCandidates = path.extname(trimmed) ? [trimmed] : [
22152
+ trimmed,
22153
+ `${trimmed}.vue`,
22154
+ `${trimmed}/index.vue`
22155
+ ];
22156
+ for (const resolveCandidate of resolveCandidates) {
22157
+ const resolved = await pluginCtx.resolve?.(resolveCandidate, vuePath);
22158
+ const normalized = resolved?.id ? normalizeFsResolvedId(resolved.id) : void 0;
22159
+ if (!normalized || isSkippableResolvedId(normalized)) continue;
22160
+ if (hasVueExtension(normalized)) return normalized;
22161
+ if (path.isAbsolute(normalized)) {
22162
+ const resolvedEntry = await resolveEntryPath(normalized, entryResolveOptions);
22163
+ if (hasVueExtension(resolvedEntry)) return resolvedEntry;
22040
22164
  }
22041
- });
22042
- return true;
22165
+ }
22043
22166
  }
22044
- const setDataValue = unwrapExpression(setDataProp.value);
22045
- if (setDataValue.type === "ObjectExpression") return injectPickIntoSetDataObject(setDataValue, keys);
22046
- if (setDataValue.type === "Identifier" || setDataValue.type === "MemberExpression" || setDataValue.type === "CallExpression") {
22047
- setDataProp.value = {
22048
- type: "ObjectExpression",
22049
- properties: [{
22050
- type: "ObjectProperty",
22051
- key: {
22052
- type: "Identifier",
22053
- name: "pick"
22054
- },
22055
- computed: false,
22056
- shorthand: false,
22057
- value: createPickArrayExpression(keys)
22058
- }, {
22059
- type: "SpreadElement",
22060
- argument: setDataValue
22061
- }]
22167
+ async function resolveAutoImportComponentSourceType(match) {
22168
+ if (match.kind === "local") {
22169
+ const resolvedId = match.entry.templatePath;
22170
+ return {
22171
+ resolvedId,
22172
+ sourceType: hasVueExtension(resolvedId) ? "wevu-sfc" : "native"
22173
+ };
22174
+ }
22175
+ const explicitSourceType = match.value.sourceType;
22176
+ const explicitResolvedId = match.value.resolvedId;
22177
+ const resolvedExplicitVueId = await resolvePotentialVueSfcEntryId(explicitResolvedId);
22178
+ if (explicitSourceType || resolvedExplicitVueId || hasVueExtension(explicitResolvedId) || hasVueExtension(match.value.from)) return {
22179
+ resolvedId: resolvedExplicitVueId ?? explicitResolvedId,
22180
+ sourceType: explicitSourceType ?? (resolvedExplicitVueId || hasVueExtension(explicitResolvedId) || hasVueExtension(match.value.from) ? "wevu-sfc" : "native")
22181
+ };
22182
+ let localSourceBase;
22183
+ if (match.value.from.startsWith("/")) localSourceBase = path.join(configService.absoluteSrcRoot, match.value.from.slice(1));
22184
+ else if (match.value.from.startsWith(".")) localSourceBase = path.resolve(path.dirname(importerBaseName), match.value.from);
22185
+ if (!localSourceBase) return {
22186
+ resolvedId: explicitResolvedId,
22187
+ sourceType: "native"
22188
+ };
22189
+ const resolvedId = await resolveEntryPath(localSourceBase, createCachedEntryResolveOptions(configService, { kind: "default" }));
22190
+ return {
22191
+ resolvedId,
22192
+ sourceType: hasVueExtension(resolvedId) ? "wevu-sfc" : "native"
22062
22193
  };
22063
- return true;
22064
22194
  }
22065
- return false;
22066
- }
22067
- function createScopedSlotHostPropertyDefinition(typeName, value) {
22068
22195
  return {
22069
- type: "ObjectExpression",
22070
- properties: [{
22071
- type: "ObjectProperty",
22072
- key: {
22073
- type: "Identifier",
22074
- name: "type"
22075
- },
22076
- computed: false,
22077
- shorthand: false,
22078
- value: typeName === "String" ? {
22079
- type: "Identifier",
22080
- name: "String"
22081
- } : { type: "NullLiteral" }
22082
- }, {
22083
- type: "ObjectProperty",
22084
- key: {
22085
- type: "Identifier",
22086
- name: "value"
22087
- },
22088
- computed: false,
22089
- shorthand: false,
22090
- value: value === null ? { type: "NullLiteral" } : {
22091
- type: "StringLiteral",
22092
- value
22196
+ isPage,
22197
+ isApp,
22198
+ warn: (message) => logger_default.warn(message),
22199
+ autoUsingComponents: {
22200
+ enabled: true,
22201
+ warn: (message) => logger_default.warn(message),
22202
+ resolveUsingComponentPath: createUsingComponentPathResolver(pluginCtx, configService, state.reExportResolutionCache)
22203
+ },
22204
+ autoImportTags: {
22205
+ enabled: true,
22206
+ warn: (message) => logger_default.warn(message),
22207
+ resolveUsingComponent: async (tag) => {
22208
+ const autoImportService = ctx.autoImportService;
22209
+ if (!autoImportService) return;
22210
+ const version = typeof autoImportService.getVersion === "function" ? autoImportService.getVersion() : 0;
22211
+ const cached = autoImportResolveCache.get(tag);
22212
+ const match = cached && cached.version === version ? cached.match : autoImportService.resolve(tag, importerBaseName);
22213
+ if (!cached || cached.version !== version) autoImportResolveCache.set(tag, {
22214
+ match,
22215
+ version
22216
+ });
22217
+ if (!match?.value) return;
22218
+ const sourceInfo = await resolveAutoImportComponentSourceType(match);
22219
+ return {
22220
+ ...match.value,
22221
+ ...sourceInfo
22222
+ };
22093
22223
  }
22094
- }]
22095
- };
22096
- }
22097
- function createScopedSlotHostProperties() {
22098
- return [{
22099
- type: "ObjectProperty",
22100
- key: {
22101
- type: "Identifier",
22102
- name: WEVU_SLOT_OWNER_ID_PROP
22103
22224
  },
22104
- computed: false,
22105
- shorthand: false,
22106
- value: createScopedSlotHostPropertyDefinition("String", "")
22107
- }, {
22108
- type: "ObjectProperty",
22109
- key: {
22110
- type: "Identifier",
22111
- name: WEVU_SLOT_SCOPE_KEY
22225
+ template: {
22226
+ platform: templatePlatformOptions.templatePlatform,
22227
+ htmlTagToWxml,
22228
+ htmlTagToWxmlTagClass,
22229
+ scopedSlotsCompiler,
22230
+ scopedSlotsRequireProps,
22231
+ slotSingleRootNoWrapper,
22232
+ slotFallbackWrapper,
22233
+ slotFallbackWrapperStrategy,
22234
+ slotMultipleInstance,
22235
+ classStyleRuntime: templatePlatformOptions.classStyleRuntime,
22236
+ objectLiteralBindMode,
22237
+ mustacheInterpolation,
22238
+ functionPropNames,
22239
+ formatWxml,
22240
+ wxsExtension: templatePlatformOptions.wxsExtension,
22241
+ classStyleWxsSrc
22112
22242
  },
22113
- computed: false,
22114
- shorthand: false,
22115
- value: createScopedSlotHostPropertyDefinition("null", null)
22116
- }];
22243
+ json: {
22244
+ kind: jsonKind,
22245
+ defaults: jsonConfig?.defaults,
22246
+ mergeStrategy: jsonConfig?.mergeStrategy
22247
+ },
22248
+ sfcSrc: createSfcResolveSrcOptions(pluginCtx, configService),
22249
+ wevuDefaults,
22250
+ minify: wevuMinify
22251
+ };
22117
22252
  }
22118
- function injectScopedSlotHostPropertiesIntoObject(propertiesObject) {
22119
- let changed = false;
22120
- for (const prop of createScopedSlotHostProperties().reverse()) {
22121
- const key = prop.key.type === "Identifier" ? prop.key.name : void 0;
22122
- if (!key || getObjectPropertyByKey(propertiesObject, key)) continue;
22123
- propertiesObject.properties.unshift(prop);
22124
- changed = true;
22125
- }
22126
- return changed;
22253
+ function createCompileVueFileOptions(ctx, pluginCtx, vuePath, isPage, isApp, configService, state) {
22254
+ const cacheKey = getCompileVueFileOptionsCacheKey(vuePath, isPage, isApp);
22255
+ const cached = state.compileOptionsCache?.get(cacheKey);
22256
+ if (cached) return cached;
22257
+ const created = buildCompileVueFileOptions(ctx, pluginCtx, vuePath, isPage, isApp, configService, state);
22258
+ state.compileOptionsCache?.set(cacheKey, created);
22259
+ return created;
22127
22260
  }
22128
- function injectScopedSlotHostPropertiesIntoOptionsObject(optionsObject) {
22129
- const propertiesProp = getObjectPropertyByKey(optionsObject, "properties");
22130
- if (!propertiesProp) {
22131
- optionsObject.properties.unshift({
22132
- type: "ObjectProperty",
22133
- key: {
22134
- type: "Identifier",
22135
- name: "properties"
22136
- },
22137
- computed: false,
22138
- shorthand: false,
22139
- value: {
22140
- type: "ObjectExpression",
22141
- properties: createScopedSlotHostProperties()
22142
- }
22143
- });
22144
- return true;
22145
- }
22146
- const propertiesValue = unwrapExpression(propertiesProp.value);
22147
- if (propertiesValue.type === "ObjectExpression") return injectScopedSlotHostPropertiesIntoObject(propertiesValue);
22148
- if (propertiesValue.type === "Identifier" || propertiesValue.type === "MemberExpression" || propertiesValue.type === "CallExpression") {
22149
- propertiesProp.value = {
22150
- type: "ObjectExpression",
22151
- properties: [{
22152
- type: "SpreadElement",
22153
- argument: propertiesValue
22154
- }, ...createScopedSlotHostProperties()]
22155
- };
22156
- return true;
22157
- }
22158
- return false;
22261
+ //#endregion
22262
+ //#region src/utils/sourcemap.ts
22263
+ function isEncodedSourceMapLike(value) {
22264
+ return Boolean(value && typeof value === "object" && "version" in value && typeof value.version === "number" && "mappings" in value && "names" in value && "sources" in value);
22159
22265
  }
22160
- function transformTargetWevuOptionsInJs(source, transformOptions) {
22161
- if (!mayNeedInjectSetDataPickInJs(source)) return {
22162
- code: source,
22163
- transformed: false
22164
- };
22165
- const ast = parseJsLike(source);
22166
- const candidateOptions = /* @__PURE__ */ new Set();
22167
- traverse(ast, { CallExpression(path) {
22168
- if (!isTargetWevuComponentCall(path.node.callee)) return;
22169
- const firstArg = path.node.arguments[0];
22170
- if (!firstArg || firstArg.type === "SpreadElement") return;
22171
- const resolvedOptions = resolveOptionsObjectExpression(firstArg, path.scope);
22172
- if (resolvedOptions) candidateOptions.add(resolvedOptions);
22173
- } });
22174
- if (!candidateOptions.size) return {
22175
- code: source,
22176
- transformed: false
22177
- };
22178
- let changed = false;
22179
- for (const optionsObject of candidateOptions) changed = transformOptions(optionsObject) || changed;
22180
- if (!changed) return {
22181
- code: source,
22182
- transformed: false
22183
- };
22184
- const generated = generate(ast, {
22185
- retainLines: true,
22186
- sourceMaps: true,
22187
- sourceFileName: "inline.js"
22188
- }, source);
22189
- return {
22190
- code: generated.code,
22191
- transformed: true,
22192
- map: generated.map
22266
+ function normalizeEncodedSourceMapLike(value) {
22267
+ if (!value || typeof value !== "object") return null;
22268
+ const sourceMap = value;
22269
+ const numericVersion = typeof sourceMap.version === "number" ? sourceMap.version : typeof sourceMap.version === "string" ? Number(sourceMap.version) : NaN;
22270
+ if (!Number.isFinite(numericVersion)) return null;
22271
+ const normalized = {
22272
+ ...sourceMap,
22273
+ version: numericVersion
22193
22274
  };
22275
+ return isEncodedSourceMapLike(normalized) ? normalized : null;
22194
22276
  }
22195
- /**
22196
- * 从编译后的 WXML 模板提取渲染相关的顶层 key。
22197
- */
22198
- function collectSetDataPickKeysFromTemplate(template, options) {
22199
- return collectSetDataPickKeysFromTemplateCode(template, options);
22277
+ function composeSourceMaps(transformedMap, originalMap) {
22278
+ if (isEncodedSourceMapLike(transformedMap) && isEncodedSourceMapLike(originalMap)) return remapping([transformedMap, originalMap], () => null);
22279
+ if (isEncodedSourceMapLike(transformedMap)) return transformedMap;
22280
+ if (isEncodedSourceMapLike(originalMap)) return originalMap;
22281
+ return null;
22200
22282
  }
22201
- /**
22202
- * 在 wevu 组件脚本中注入 setData.pick。
22203
- */
22204
- function injectSetDataPickInJs(source, pickKeys) {
22205
- const mergedPickKeys = mergeStableKeys(pickKeys, [
22206
- WEVU_SLOT_NAMES_PROP,
22207
- WEVU_SLOT_OWNER_ID_PROP,
22208
- WEVU_SLOT_SCOPE_KEY
22209
- ]);
22210
- if (!mergedPickKeys.length) return {
22211
- code: source,
22212
- transformed: false
22283
+ //#endregion
22284
+ //#region src/plugins/utils/viteResolverAdapter.ts
22285
+ const WINDOWS_ABSOLUTE_PATH_RE = /^[A-Z]:[\\/]/i;
22286
+ function isExplicitFileRequest(id) {
22287
+ return id.startsWith(".") || id.startsWith("/") || WINDOWS_ABSOLUTE_PATH_RE.test(id);
22288
+ }
22289
+ function isFilePathLike(id) {
22290
+ return Boolean(path.extname(id));
22291
+ }
22292
+ function resolveLocalFile(source, importer, normalizeOptions) {
22293
+ const cleanSource = normalizeFsResolvedId(source, normalizeOptions);
22294
+ if (!isExplicitFileRequest(cleanSource) || !isFilePathLike(cleanSource)) return;
22295
+ const candidate = path.isAbsolute(cleanSource) || WINDOWS_ABSOLUTE_PATH_RE.test(cleanSource) ? cleanSource : importer ? path.resolve(path.dirname(normalizeFsResolvedId(importer, normalizeOptions)), cleanSource) : void 0;
22296
+ if (!candidate) return;
22297
+ try {
22298
+ return fs$1.statSync(candidate).isFile() ? candidate : void 0;
22299
+ } catch {
22300
+ return;
22301
+ }
22302
+ }
22303
+ function createViteResolverAdapter(resolver, reader, options) {
22304
+ const checkMtime = options?.checkMtime;
22305
+ const normalizeOptions = options?.normalize;
22306
+ return {
22307
+ resolveId: async (source, importer) => {
22308
+ const localFile = resolveLocalFile(source, importer, normalizeOptions);
22309
+ if (localFile) return localFile;
22310
+ const resolved = await resolver.resolve(source, importer);
22311
+ return resolved ? resolved.id : void 0;
22312
+ },
22313
+ loadCode: async (resolvedId) => {
22314
+ const clean = normalizeFsResolvedId(resolvedId, normalizeOptions);
22315
+ if (isSkippableResolvedId(clean)) return;
22316
+ try {
22317
+ return await reader.readFile(clean, { checkMtime });
22318
+ } catch {
22319
+ return;
22320
+ }
22321
+ }
22213
22322
  };
22214
- return transformTargetWevuOptionsInJs(source, (optionsObject) => injectPickIntoOptionsObject(optionsObject, mergedPickKeys));
22215
22323
  }
22216
- /**
22217
- * 在含有 scoped slot outlet 的 wevu 组件脚本中注入宿主内部属性。
22218
- */
22219
- function injectScopedSlotHostPropertiesInJs(source) {
22220
- return transformTargetWevuOptionsInJs(source, injectScopedSlotHostPropertiesIntoOptionsObject);
22324
+ //#endregion
22325
+ //#region src/plugins/vue/transform/injectPageFeatures.ts
22326
+ async function injectWevuPageFeaturesInJsWithViteResolver(ctx, source, id, options) {
22327
+ const checkMtime = options?.checkMtime ?? true;
22328
+ const injected = await injectWevuPageFeaturesInJsWithResolver(source, {
22329
+ id,
22330
+ resolver: createViteResolverAdapter({ resolve: (source, importer) => ctx.resolve(source, importer) }, { readFile: readFile$1 }, { checkMtime }),
22331
+ minify: options?.minify
22332
+ });
22333
+ return {
22334
+ ...injected,
22335
+ map: normalizeEncodedSourceMapLike(injected.map)
22336
+ };
22221
22337
  }
22222
22338
  //#endregion
22223
22339
  //#region src/plugins/vue/transform/plugin/shared/autoRoutes.ts
@@ -22525,15 +22641,26 @@ async function finalizeTransformEntryScript(options) {
22525
22641
  }
22526
22642
  }
22527
22643
  }
22528
- if (!isApp && result.script && result.template && isAutoSetDataPickEnabled(configService.weappViteConfig) && mayNeedTransformSetDataPick(result.template, { platform: configService.platform }) && mayNeedInjectSetDataPickInJs(result.script)) {
22644
+ const shouldAutoSetDataPick = !isApp && result.script && result.template && isAutoSetDataPickEnabled(configService.weappViteConfig) && mayNeedTransformSetDataPick(result.template, { platform: configService.platform }) && mayNeedInjectSetDataPickInJs(result.script);
22645
+ const shouldInjectScopedSlotOwnerPick = !isApp && result.script && result.template?.includes(WEVU_SLOT_OWNER_ID_ATTR) && mayNeedInjectSetDataPickInJs(result.script);
22646
+ if (shouldAutoSetDataPick) {
22647
+ const keys = collectSetDataPickKeysFromTemplate(result.template, { astEngine: resolveAstEngine(configService.weappViteConfig) });
22648
+ const scopedSlotPickKeys = shouldUseScopedSlotOwnerOnlySetDataPick(keys) ? pruneScopedSlotOwnerAutoSetDataPickKeys(keys) : keys;
22649
+ const injectedPick = shouldInjectScopedSlotOwnerPick ? injectScopedSlotOwnerSetDataPickInJs(result.script, scopedSlotPickKeys) : injectSetDataPickInJs(result.script, keys);
22650
+ if (injectedPick.transformed) {
22651
+ result.script = injectedPick.code;
22652
+ result.scriptMap = composeSourceMaps(injectedPick.map, result.scriptMap);
22653
+ }
22654
+ } else if (shouldInjectScopedSlotOwnerPick) {
22529
22655
  const keys = collectSetDataPickKeysFromTemplate(result.template, { astEngine: resolveAstEngine(configService.weappViteConfig) });
22530
- const injectedPick = injectSetDataPickInJs(result.script, keys);
22656
+ const injectedPick = injectScopedSlotOwnerSetDataPickInJs(result.script, pruneScopedSlotOwnerAutoSetDataPickKeys(keys));
22531
22657
  if (injectedPick.transformed) {
22532
22658
  result.script = injectedPick.code;
22533
22659
  result.scriptMap = composeSourceMaps(injectedPick.map, result.scriptMap);
22534
22660
  }
22535
22661
  }
22536
- if (!isPage && !isApp && result.script && result.template?.includes(WEVU_SLOT_OWNER_ID_PROP)) {
22662
+ const hasScopedSlotHostGenerics = Boolean(result.componentGenerics && Object.keys(result.componentGenerics).length > 0);
22663
+ if (!isPage && !isApp && result.script && (hasScopedSlotHostGenerics || result.template?.includes(WEVU_SLOT_OWNER_ID_PROP) || result.template?.includes("vueSlots"))) {
22537
22664
  const injectedProps = injectScopedSlotHostPropertiesInJs(result.script);
22538
22665
  if (injectedProps.transformed) {
22539
22666
  result.script = injectedProps.code;
@@ -22710,12 +22837,20 @@ async function finalizeCompiledVueLikeResult(options) {
22710
22837
  });
22711
22838
  if (injected.transformed) result.script = injected.code;
22712
22839
  }
22713
- if (!isApp && result.script && result.template && isAutoSetDataPickEnabled(configService.weappViteConfig) && mayNeedInjectSetDataPickInJs(result.script)) {
22840
+ const shouldAutoSetDataPick = !isApp && result.script && result.template && isAutoSetDataPickEnabled(configService.weappViteConfig) && mayNeedInjectSetDataPickInJs(result.script);
22841
+ const shouldInjectScopedSlotOwnerPick = !isApp && result.script && result.template?.includes(WEVU_SLOT_OWNER_ID_ATTR) && mayNeedInjectSetDataPickInJs(result.script);
22842
+ if (shouldAutoSetDataPick) {
22843
+ const keys = collectSetDataPickKeysFromTemplate(result.template);
22844
+ const scopedSlotPickKeys = shouldUseScopedSlotOwnerOnlySetDataPick(keys) ? pruneScopedSlotOwnerAutoSetDataPickKeys(keys) : keys;
22845
+ const injectedPick = shouldInjectScopedSlotOwnerPick ? injectScopedSlotOwnerSetDataPickInJs(result.script, scopedSlotPickKeys) : injectSetDataPickInJs(result.script, keys);
22846
+ if (injectedPick.transformed) result.script = injectedPick.code;
22847
+ } else if (shouldInjectScopedSlotOwnerPick) {
22714
22848
  const keys = collectSetDataPickKeysFromTemplate(result.template);
22715
- const injectedPick = injectSetDataPickInJs(result.script, keys);
22849
+ const injectedPick = injectScopedSlotOwnerSetDataPickInJs(result.script, pruneScopedSlotOwnerAutoSetDataPickKeys(keys));
22716
22850
  if (injectedPick.transformed) result.script = injectedPick.code;
22717
22851
  }
22718
- if (!isPage && !isApp && result.script && result.template?.includes(WEVU_SLOT_OWNER_ID_PROP)) {
22852
+ const hasScopedSlotHostGenerics = Boolean(result.componentGenerics && Object.keys(result.componentGenerics).length > 0);
22853
+ if (!isPage && !isApp && result.script && (hasScopedSlotHostGenerics || result.template?.includes(WEVU_SLOT_OWNER_ID_PROP) || result.template?.includes("vueSlots"))) {
22719
22854
  const injectedProps = injectScopedSlotHostPropertiesInJs(result.script);
22720
22855
  if (injectedProps.transformed) result.script = injectedProps.code;
22721
22856
  }
@@ -23898,6 +24033,27 @@ function escapeRegex(value) {
23898
24033
  function createAbsolutePathPattern(value) {
23899
24034
  return value.split(PATH_SEPARATOR_SPLIT_REGEX).map((segment) => escapeRegex(segment)).join("[/\\\\]+");
23900
24035
  }
24036
+ function hasTsconfigReference(tsconfig, target) {
24037
+ if (!existsSync(tsconfig)) return false;
24038
+ try {
24039
+ const parsed = parse$1(readFileSync(tsconfig, "utf8"), void 0, true);
24040
+ const references = Array.isArray(parsed.references) ? parsed.references : [];
24041
+ const tsconfigDir = path.dirname(tsconfig);
24042
+ return references.some((reference) => {
24043
+ if (!reference || typeof reference !== "object" || typeof reference.path !== "string") return false;
24044
+ return path.resolve(tsconfigDir, reference.path) === target;
24045
+ });
24046
+ } catch {
24047
+ return false;
24048
+ }
24049
+ }
24050
+ function resolveDefaultRolldownTsconfig(cwd) {
24051
+ const appTsconfig = path.resolve(cwd, ".weapp-vite/tsconfig.app.json");
24052
+ const rootTsconfig = path.resolve(cwd, "tsconfig.json");
24053
+ if (existsSync(appTsconfig)) return appTsconfig;
24054
+ if (hasTsconfigReference(rootTsconfig, appTsconfig)) return appTsconfig;
24055
+ if (existsSync(rootTsconfig)) return rootTsconfig;
24056
+ }
23901
24057
  function normalizeInlineConfigAfterDefu(inline, options) {
23902
24058
  const { cwd, ctx, platform, rolldownOptions, subPackageMeta } = options;
23903
24059
  const build = inline.build ?? (inline.build = {});
@@ -23910,8 +24066,8 @@ function normalizeInlineConfigAfterDefu(inline, options) {
23910
24066
  ...userRolldownOptions?.output ?? {}
23911
24067
  }
23912
24068
  };
23913
- const rootTsconfig = path.resolve(cwd, "tsconfig.json");
23914
- if (!Object.prototype.hasOwnProperty.call(mergedRolldownOptions, "tsconfig") && !mergedRolldownOptions.resolve?.tsconfigFilename && existsSync(rootTsconfig)) mergedRolldownOptions.tsconfig = rootTsconfig;
24069
+ const defaultTsconfig = resolveDefaultRolldownTsconfig(cwd);
24070
+ if (!Object.prototype.hasOwnProperty.call(mergedRolldownOptions, "tsconfig") && !mergedRolldownOptions.resolve?.tsconfigFilename && defaultTsconfig) mergedRolldownOptions.tsconfig = defaultTsconfig;
23915
24071
  build.rolldownOptions = mergedRolldownOptions;
23916
24072
  inline.define = {
23917
24073
  ...inline.define ?? {},
@@ -24762,7 +24918,7 @@ async function loadAppEntry(ctx, scanState) {
24762
24918
  const vueAppPath = await findVueEntry(appBasename);
24763
24919
  let configFromVue;
24764
24920
  if (!appConfigFile && vueAppPath) {
24765
- const { extractConfigFromVue } = await import("./file-DiowMq_y.mjs");
24921
+ const { extractConfigFromVue } = await import("./file-CHPrnwzT.mjs");
24766
24922
  configFromVue = await extractConfigFromVue(vueAppPath);
24767
24923
  if (configFromVue) appConfigFile = vueAppPath;
24768
24924
  }
@@ -25941,7 +26097,54 @@ async function syncManagedTsconfigFiles(ctx) {
25941
26097
  for (const file of await createManagedTsconfigFiles(ctx)) await outputFileIfChanged(file);
25942
26098
  return changed;
25943
26099
  }
25944
- async function syncManagedTsconfigBootstrapFiles(cwd) {
26100
+ const MANAGED_TSCONFIG_MARKERS = [".weapp-vite/tsconfig.app.json", ".weapp-vite/tsconfig.shared.json"];
26101
+ async function readTsconfigData(filePath) {
26102
+ const content = await fs.readFile(filePath, "utf8").catch(() => void 0);
26103
+ if (!content) return;
26104
+ try {
26105
+ const parsed = parse$1(content, void 0, true);
26106
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : void 0;
26107
+ } catch {
26108
+ return;
26109
+ }
26110
+ }
26111
+ function normalizeReferencePath(value) {
26112
+ return value.replace(/\\/g, "/").replace(/^\.\//, "");
26113
+ }
26114
+ function getTsconfigReferences(data) {
26115
+ return (Array.isArray(data?.references) ? data.references : []).filter((reference) => {
26116
+ return Boolean(reference && typeof reference === "object" && typeof reference.path === "string");
26117
+ });
26118
+ }
26119
+ function resolveReferenceProjectRoot(baseDir, value) {
26120
+ const resolved = path.resolve(baseDir, value);
26121
+ return path.basename(resolved).endsWith(".json") ? path.dirname(resolved) : resolved;
26122
+ }
26123
+ async function isManagedTsconfigProject(projectRoot) {
26124
+ const data = await readTsconfigData(path.resolve(projectRoot, "tsconfig.json"));
26125
+ if (!data) return false;
26126
+ if (typeof data.extends === "string") {
26127
+ const normalizedExtends = normalizeReferencePath(data.extends);
26128
+ if (MANAGED_TSCONFIG_MARKERS.some((marker) => normalizedExtends.includes(marker))) return true;
26129
+ }
26130
+ return getTsconfigReferences(data).some((reference) => {
26131
+ const normalizedPath = normalizeReferencePath(reference.path);
26132
+ return MANAGED_TSCONFIG_MARKERS.some((marker) => normalizedPath.includes(marker));
26133
+ });
26134
+ }
26135
+ async function findReferencingWorkspaceTsconfig(cwd) {
26136
+ const targetRoot = path.resolve(cwd);
26137
+ let current = path.dirname(targetRoot);
26138
+ while (current && current !== path.dirname(current)) {
26139
+ const references = getTsconfigReferences(await readTsconfigData(path.join(current, "tsconfig.json")));
26140
+ if (references.some((reference) => resolveReferenceProjectRoot(current, reference.path) === targetRoot)) return {
26141
+ root: current,
26142
+ references
26143
+ };
26144
+ current = path.dirname(current);
26145
+ }
26146
+ }
26147
+ async function syncSingleProjectManagedTsconfigBootstrapFiles(cwd) {
25945
26148
  const packageJsonPath = path.resolve(cwd, "package.json");
25946
26149
  const bootstrapCtx = { configService: {
25947
26150
  cwd,
@@ -25963,6 +26166,17 @@ async function syncManagedTsconfigBootstrapFiles(cwd) {
25963
26166
  }
25964
26167
  return changed;
25965
26168
  }
26169
+ async function syncManagedTsconfigBootstrapFiles(cwd) {
26170
+ let changed = await syncSingleProjectManagedTsconfigBootstrapFiles(cwd);
26171
+ const workspace = await findReferencingWorkspaceTsconfig(cwd);
26172
+ if (!workspace) return changed;
26173
+ for (const reference of workspace.references) {
26174
+ const projectRoot = resolveReferenceProjectRoot(workspace.root, reference.path);
26175
+ if (projectRoot === path.resolve(cwd) || !await isManagedTsconfigProject(projectRoot)) continue;
26176
+ changed = await syncSingleProjectManagedTsconfigBootstrapFiles(projectRoot) || changed;
26177
+ }
26178
+ return changed;
26179
+ }
25966
26180
  //#endregion
25967
26181
  //#region src/runtime/supportFiles.ts
25968
26182
  async function hasManagedTsconfigChanges(ctx) {