weapp-vite 6.16.18 → 6.16.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/auto-import-components/resolvers.d.mts +1 -1
  2. package/dist/auto-import-components/resolvers.mjs +3 -0
  3. package/dist/auto-routes.d.mts +1 -1
  4. package/dist/auto-routes.mjs +1 -1
  5. package/dist/cli.mjs +16 -12
  6. package/dist/{config-D6yS3er1.d.mts → config-DBTZvwxw.d.mts} +39 -3
  7. package/dist/config.d.mts +1 -1
  8. package/dist/config.mjs +3 -3
  9. package/dist/{createContext-1rR_RC4a.mjs → createContext-9Iyp31bM.mjs} +2272 -1678
  10. package/dist/docs/weapp-config.md +24 -0
  11. package/dist/{file-BD6SG7DR.mjs → file-Dv_e5yIa.mjs} +1 -1
  12. package/dist/file-IuX99F00.mjs +2 -0
  13. package/dist/getInstance-DS0CkWYU.mjs +2 -0
  14. package/dist/index.d.mts +2 -2
  15. package/dist/index.mjs +5 -5
  16. package/dist/json.d.mts +1 -1
  17. package/dist/json.mjs +1 -1
  18. package/dist/{mcp-DV3K2AVD.mjs → mcp-qmDOTH07.mjs} +1 -1
  19. package/dist/mcp.d.mts +1 -1
  20. package/dist/mcp.mjs +1 -1
  21. package/dist/runtime.d.mts +1 -1
  22. package/dist/runtime.mjs +1 -1
  23. package/dist/types.d.mts +4 -4
  24. package/package.json +14 -14
  25. package/dist/file-CGqxLI8I.mjs +0 -2
  26. package/dist/getInstance-Bwdj3KA1.mjs +0 -2
  27. /package/dist/{config-DJjSbpNX.mjs → config-DRGcCi3h.mjs} +0 -0
  28. /package/dist/{index-C1yQldy3.d.mts → index-Bmclyjw8.d.mts} +0 -0
  29. /package/dist/{json-D0HkutE0.mjs → json-BL8Dhhk6.mjs} +0 -0
  30. /package/dist/{logger-CgxdNjvb.mjs → logger-mt4mSTqV.mjs} +0 -0
  31. /package/dist/{pluginHost-BEnGeaSo.mjs → pluginHost--CaeyWpA.mjs} +0 -0
  32. /package/dist/{routes-DiEBrMtj.d.mts → routes-C7fCmf92.d.mts} +0 -0
  33. /package/dist/{runtime-spnjzaP2.mjs → runtime-C3z9pDQB.mjs} +0 -0
  34. /package/dist/{runtime-DSLk7kWi.d.mts → runtime-CDNs17Qq.d.mts} +0 -0
@@ -1,6 +1,6 @@
1
- import { n as applyWeappViteHostMeta } from "./pluginHost-BEnGeaSo.mjs";
2
- import { n as configureLogger, r as logger_default } from "./logger-CgxdNjvb.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-BD6SG7DR.mjs";
1
+ import { n as applyWeappViteHostMeta } from "./pluginHost--CaeyWpA.mjs";
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-Dv_e5yIa.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";
@@ -6196,6 +6196,123 @@ function resolveRoute(normalizedBase, subPackageRoots = []) {
6196
6196
  };
6197
6197
  }
6198
6198
  //#endregion
6199
+ //#region src/runtime/buildScope.ts
6200
+ const MAIN_SCOPE_TOKEN = "main";
6201
+ const BUILD_SCOPE_CLI_SOURCE = "__weappViteBuildScopeSource";
6202
+ function normalizeScopeRoot(value) {
6203
+ return normalizeRoot(value.trim());
6204
+ }
6205
+ function parseScopeTokens(value) {
6206
+ const tokens = (Array.isArray(value) ? value : typeof value === "string" ? value.split(",") : []).map((token) => normalizeScopeRoot(token)).filter((token) => token.length > 0);
6207
+ return [...new Set(tokens)];
6208
+ }
6209
+ function normalizeBuildScopeConfig(config, source) {
6210
+ if (!config) return;
6211
+ if (typeof config === "string" || Array.isArray(config)) {
6212
+ const tokens = parseScopeTokens(config);
6213
+ if (tokens.length === 0) return;
6214
+ return {
6215
+ enabled: true,
6216
+ includeMainPackage: true,
6217
+ subPackageRoots: tokens.filter((token) => token !== MAIN_SCOPE_TOKEN),
6218
+ source
6219
+ };
6220
+ }
6221
+ const include = parseScopeTokens(config.include);
6222
+ const includeMainPackage = config.includeMainPackage ?? true;
6223
+ const subPackageRoots = include.filter((token) => token !== MAIN_SCOPE_TOKEN);
6224
+ if (!includeMainPackage && subPackageRoots.length === 0) return;
6225
+ return {
6226
+ enabled: true,
6227
+ includeMainPackage,
6228
+ subPackageRoots,
6229
+ source: config[BUILD_SCOPE_CLI_SOURCE] === true ? "cli" : source
6230
+ };
6231
+ }
6232
+ function resolveBuildScope(config) {
6233
+ return normalizeBuildScopeConfig(config, "config");
6234
+ }
6235
+ function createBuildScopeConfigFromCli(value) {
6236
+ const tokens = parseScopeTokens(value);
6237
+ if (tokens.length === 0) return;
6238
+ return {
6239
+ includeMainPackage: true,
6240
+ include: tokens.filter((token) => token !== MAIN_SCOPE_TOKEN),
6241
+ [BUILD_SCOPE_CLI_SOURCE]: true
6242
+ };
6243
+ }
6244
+ function isSubPackageInScope(subPackage, roots) {
6245
+ const root = subPackage.root ? normalizeRoot(subPackage.root) : void 0;
6246
+ return Boolean(root && roots.has(root));
6247
+ }
6248
+ function normalizeScopedSubPackage(subPackage) {
6249
+ return {
6250
+ ...subPackage,
6251
+ root: normalizeRoot(subPackage.root ?? ""),
6252
+ pages: Array.isArray(subPackage.pages) ? subPackage.pages : []
6253
+ };
6254
+ }
6255
+ function filterPreloadRule(preloadRule, scope, allSubPackageRoots) {
6256
+ if (!preloadRule || typeof preloadRule !== "object") return preloadRule;
6257
+ const scopedRoots = new Set(scope.subPackageRoots);
6258
+ const scopedPreloadRule = {};
6259
+ for (const [pagePath, rule] of Object.entries(preloadRule)) {
6260
+ const normalizedPagePath = normalizeRoot(pagePath);
6261
+ const pageSubPackageRoot = [...allSubPackageRoots].find((root) => normalizedPagePath === root || normalizedPagePath.startsWith(`${root}/`));
6262
+ if (!(pageSubPackageRoot ? scopedRoots.has(pageSubPackageRoot) : scope.includeMainPackage)) continue;
6263
+ if (!rule || typeof rule !== "object" || !("packages" in rule)) {
6264
+ scopedPreloadRule[pagePath] = rule;
6265
+ continue;
6266
+ }
6267
+ const packages = rule.packages;
6268
+ if (!Array.isArray(packages)) {
6269
+ scopedPreloadRule[pagePath] = rule;
6270
+ continue;
6271
+ }
6272
+ const filteredPackages = packages.filter((packageRoot) => {
6273
+ return typeof packageRoot === "string" && scopedRoots.has(normalizeRoot(packageRoot));
6274
+ });
6275
+ if (filteredPackages.length > 0) scopedPreloadRule[pagePath] = {
6276
+ ...rule,
6277
+ packages: filteredPackages
6278
+ };
6279
+ }
6280
+ return Object.keys(scopedPreloadRule).length > 0 ? scopedPreloadRule : void 0;
6281
+ }
6282
+ function applyBuildScopeToAppConfig(config, scope) {
6283
+ if (!scope?.enabled) return config;
6284
+ const scopedRoots = new Set(scope.subPackageRoots);
6285
+ const sourceSubPackages = Array.isArray(config.subPackages) ? config.subPackages : Array.isArray(config.subpackages) ? config.subpackages : [];
6286
+ const allSubPackageRoots = new Set(sourceSubPackages.map((subPackage) => subPackage.root ? normalizeRoot(subPackage.root) : void 0).filter((root) => Boolean(root)));
6287
+ const scopedSubPackages = sourceSubPackages.filter((subPackage) => isSubPackageInScope(subPackage, scopedRoots)).map(normalizeScopedSubPackage);
6288
+ config.pages = scope.includeMainPackage && Array.isArray(config.pages) ? config.pages : [];
6289
+ config.subPackages = scopedSubPackages;
6290
+ delete config.subpackages;
6291
+ const preloadRule = filterPreloadRule(config.preloadRule, scope, allSubPackageRoots);
6292
+ if (preloadRule) config.preloadRule = preloadRule;
6293
+ else delete config.preloadRule;
6294
+ return config;
6295
+ }
6296
+ function applyBuildScopeToAutoRoutes(routes, scope) {
6297
+ if (!scope?.enabled) return routes;
6298
+ const scopedRoots = new Set(scope.subPackageRoots);
6299
+ const subPackages = routes.subPackages.filter((subPackage) => scopedRoots.has(normalizeRoot(subPackage.root))).map((subPackage) => ({
6300
+ ...subPackage,
6301
+ root: normalizeRoot(subPackage.root)
6302
+ }));
6303
+ const scopedEntries = new Set([...scope.includeMainPackage ? routes.pages : [], ...subPackages.flatMap((subPackage) => subPackage.pages.map((page) => `${subPackage.root}/${page}`))]);
6304
+ return {
6305
+ pages: scope.includeMainPackage ? routes.pages : [],
6306
+ entries: routes.entries.filter((entry) => scopedEntries.has(entry)),
6307
+ subPackages
6308
+ };
6309
+ }
6310
+ function applyBuildScopeToSubPackageRoots(roots, scope) {
6311
+ if (!scope?.enabled) return roots;
6312
+ const scopedRoots = new Set(scope.subPackageRoots);
6313
+ return roots.map((root) => normalizeRoot(root)).filter((root) => scopedRoots.has(root));
6314
+ }
6315
+ //#endregion
6199
6316
  //#region src/utils/miniProgramGlobals.ts
6200
6317
  function getMiniProgramGlobalKeys() {
6201
6318
  return [...getMiniProgramRuntimeGlobalKeysByResolvePriority()];
@@ -6340,7 +6457,7 @@ function getAutoRoutesSubPackageRoots(ctx) {
6340
6457
  const npmSubPackageRoots = Object.keys(ctx.configService?.weappViteConfig?.npm?.subPackages ?? {});
6341
6458
  for (const root of npmSubPackageRoots) roots.add(root);
6342
6459
  for (const root of collectAppJsonSubPackageRoots(ctx)) roots.add(root);
6343
- return [...roots];
6460
+ return applyBuildScopeToSubPackageRoots([...roots], resolveBuildScope(ctx.configService?.weappViteConfig?.buildScope));
6344
6461
  }
6345
6462
  //#endregion
6346
6463
  //#region src/runtime/autoRoutesPlugin/shared.ts
@@ -6508,11 +6625,11 @@ async function scanRoutes(ctx, candidatesMap) {
6508
6625
  sortAutoRoutesEntries(pages);
6509
6626
  sortAutoRoutesEntries(entries);
6510
6627
  sortAutoRoutesSubPackages(subPackageList);
6511
- const snapshot = {
6628
+ const snapshot = applyBuildScopeToAutoRoutes({
6512
6629
  pages,
6513
6630
  entries,
6514
6631
  subPackages: subPackageList
6515
- };
6632
+ }, resolveBuildScope(configService.weappViteConfig.buildScope));
6516
6633
  const { serialized, moduleCode, typedDefinition } = createAutoRoutesArtifacts(snapshot);
6517
6634
  return {
6518
6635
  snapshot,
@@ -9787,7 +9904,7 @@ function createAdvancedChunkNameResolver(options) {
9787
9904
  const REG_NODE_MODULES_DIR = /[\\/]node_modules[\\/]/gi;
9788
9905
  const REG_COMMONJS_HELPERS = /commonjsHelpers\.js$/;
9789
9906
  const REG_REQUEST_GLOBAL_RUNTIME_VENDOR_ID = /(?:^|[/\\])(?:@wevu[/\\]web-apis|web-apis[/\\]dist[/\\]index\.(?:m?js|cjs)|weapp-vite[/\\](?:dist[/\\]web-apis\.mjs|src[/\\](?:webApis\.ts|runtime[/\\]webApis[/\\]index\.ts)))(?:$|[?#])/;
9790
- const REG_HASHED_DIST_CHUNK_ID = /(?:^|[/\\])dist[/\\]([^/\\-]+)-([\w-]{6,})\.(?:m?js|cjs)(?:$|[?#])/;
9907
+ const REG_HASHED_DIST_CHUNK_ID = /(?:^|[/\\])dist[/\\](?:dev[/\\])?([^/\\-]+)-([\w-]{6,})\.(?:m?js|cjs)(?:$|[?#])/;
9791
9908
  const STABLE_HASHED_DIST_CHUNK_PRIORITY = ["src"];
9792
9909
  function resolveSharedPathRoot(configService, sharedPathRoot) {
9793
9910
  const absoluteSrcRoot = configService.absoluteSrcRoot;
@@ -9986,13 +10103,16 @@ function resolvePollingWatchConfig(configService) {
9986
10103
  const buildWatch = configService.inlineConfig?.build?.watch;
9987
10104
  const chokidar = buildWatch && typeof buildWatch === "object" && "chokidar" in buildWatch ? buildWatch.chokidar : void 0;
9988
10105
  const serverWatch = configService.inlineConfig?.server?.watch;
9989
- const usePollingCandidate = chokidar?.usePolling ?? serverWatch?.usePolling;
9990
- const intervalCandidate = chokidar?.interval ?? serverWatch?.interval;
9991
- const binaryIntervalCandidate = chokidar?.binaryInterval ?? serverWatch?.binaryInterval;
10106
+ const envUsePolling = process.env.CHOKIDAR_USEPOLLING;
10107
+ const envInterval = process.env.CHOKIDAR_INTERVAL;
10108
+ const envBinaryInterval = process.env.CHOKIDAR_BINARY_INTERVAL;
10109
+ const usePollingCandidate = chokidar?.usePolling ?? serverWatch?.usePolling ?? (envUsePolling === "1" || envUsePolling === "true" ? true : envUsePolling === "0" || envUsePolling === "false" ? false : void 0);
10110
+ const intervalCandidate = chokidar?.interval ?? serverWatch?.interval ?? (envInterval ? Number(envInterval) : void 0);
10111
+ const binaryIntervalCandidate = chokidar?.binaryInterval ?? serverWatch?.binaryInterval ?? (envBinaryInterval ? Number(envBinaryInterval) : void 0);
9992
10112
  return {
9993
10113
  usePolling: typeof usePollingCandidate === "boolean" ? usePollingCandidate : void 0,
9994
- interval: typeof intervalCandidate === "number" ? intervalCandidate : void 0,
9995
- binaryInterval: typeof binaryIntervalCandidate === "number" ? binaryIntervalCandidate : void 0
10114
+ interval: typeof intervalCandidate === "number" && Number.isFinite(intervalCandidate) ? intervalCandidate : void 0,
10115
+ binaryInterval: typeof binaryIntervalCandidate === "number" && Number.isFinite(binaryIntervalCandidate) ? binaryIntervalCandidate : void 0
9996
10116
  };
9997
10117
  }
9998
10118
  function createSidecarWatchOptions(configService, input) {
@@ -10745,8 +10865,13 @@ function createBuildService(ctx) {
10745
10865
  const sidecarEntryId = await resolveSnapshotSidecarEntryId(reason);
10746
10866
  if (sidecarEntryId) {
10747
10867
  markSnapshotEntryDirty(sidecarEntryId);
10748
- await touch(sidecarEntryId);
10749
- return "forwarded";
10868
+ process.env.WEAPP_VITE_FORCE_FULL_HMR_SHARED_CHUNKS = "1";
10869
+ try {
10870
+ await build(snapshotBuildOptions);
10871
+ return "snapshot";
10872
+ } finally {
10873
+ delete process.env.WEAPP_VITE_FORCE_FULL_HMR_SHARED_CHUNKS;
10874
+ }
10750
10875
  }
10751
10876
  markSnapshotEntriesFullDirty();
10752
10877
  process.env.WEAPP_VITE_FORCE_FULL_HMR_SHARED_CHUNKS = "1";
@@ -11030,57 +11155,72 @@ const PACKAGE_ALIASES = [
11030
11155
  find: "wevu",
11031
11156
  packageName: "wevu",
11032
11157
  distEntry: "dist/index.mjs",
11158
+ devDistEntry: "dist/dev/index.mjs",
11033
11159
  fallbackWorkspacePackagePath: WEVU_WORKSPACE_PACKAGE_PATH
11034
11160
  },
11035
11161
  {
11036
11162
  find: "wevu/compiler",
11037
11163
  packageName: "wevu",
11038
11164
  distEntry: "dist/compiler.mjs",
11165
+ devDistEntry: "dist/dev/compiler.mjs",
11039
11166
  fallbackWorkspacePackagePath: WEVU_WORKSPACE_PACKAGE_PATH
11040
11167
  },
11041
11168
  {
11042
11169
  find: "wevu/jsx-runtime",
11043
11170
  packageName: "wevu",
11044
11171
  distEntry: "dist/jsx-runtime.mjs",
11172
+ devDistEntry: "dist/dev/jsx-runtime.mjs",
11045
11173
  fallbackWorkspacePackagePath: WEVU_WORKSPACE_PACKAGE_PATH
11046
11174
  },
11047
11175
  {
11048
11176
  find: "wevu/store",
11049
11177
  packageName: "wevu",
11050
11178
  distEntry: "dist/store.mjs",
11179
+ devDistEntry: "dist/dev/store.mjs",
11051
11180
  fallbackWorkspacePackagePath: WEVU_WORKSPACE_PACKAGE_PATH
11052
11181
  },
11053
11182
  {
11054
11183
  find: "wevu/api",
11055
11184
  packageName: "wevu",
11056
11185
  distEntry: "dist/api.mjs",
11186
+ devDistEntry: "dist/dev/api.mjs",
11057
11187
  fallbackWorkspacePackagePath: WEVU_WORKSPACE_PACKAGE_PATH
11058
11188
  },
11059
11189
  {
11060
11190
  find: "wevu/fetch",
11061
11191
  packageName: "wevu",
11062
11192
  distEntry: "dist/fetch.mjs",
11193
+ devDistEntry: "dist/dev/fetch.mjs",
11063
11194
  fallbackWorkspacePackagePath: WEVU_WORKSPACE_PACKAGE_PATH
11064
11195
  },
11065
11196
  {
11066
11197
  find: "wevu/web-apis",
11067
11198
  packageName: "wevu",
11068
11199
  distEntry: "dist/web-apis.mjs",
11200
+ devDistEntry: "dist/dev/web-apis.mjs",
11069
11201
  fallbackWorkspacePackagePath: WEVU_WORKSPACE_PACKAGE_PATH
11070
11202
  },
11071
11203
  {
11072
11204
  find: "wevu/router",
11073
11205
  packageName: "wevu",
11074
11206
  distEntry: "dist/router.mjs",
11207
+ devDistEntry: "dist/dev/router.mjs",
11075
11208
  fallbackWorkspacePackagePath: WEVU_WORKSPACE_PACKAGE_PATH
11076
11209
  },
11077
11210
  {
11078
11211
  find: "vue-demi",
11079
11212
  packageName: "wevu",
11080
11213
  distEntry: "dist/vue-demi.mjs",
11214
+ devDistEntry: "dist/dev/vue-demi.mjs",
11081
11215
  fallbackWorkspacePackagePath: WEVU_WORKSPACE_PACKAGE_PATH
11082
11216
  }
11083
11217
  ];
11218
+ function resolveWevuRuntimeDistEntry(target, options) {
11219
+ if (!target.devDistEntry || target.packageName !== "wevu") return target.distEntry;
11220
+ const mode = options.wevuRuntime ?? "auto";
11221
+ if (mode === "dev" || mode === "auto" && options.isDev) return target.devDistEntry;
11222
+ return target.distEntry;
11223
+ }
11084
11224
  function resolveRepoRoot(fromDir) {
11085
11225
  let currentDir = fromDir;
11086
11226
  while (true) {
@@ -11102,10 +11242,11 @@ function resolvePackageEntry(packageName, distEntry, fallbackWorkspacePackagePat
11102
11242
  const fallbackEntry = path.resolve(repoRoot, fallbackWorkspacePackagePath, distEntry);
11103
11243
  if (existsSync(fallbackEntry)) return fallbackEntry;
11104
11244
  }
11105
- function resolveBuiltinPackageAliases() {
11245
+ function resolveBuiltinPackageAliases(options = {}) {
11106
11246
  const aliases = [];
11107
- for (const { find, packageName, distEntry, fallbackWorkspacePackagePath } of PACKAGE_ALIASES) {
11108
- const resolvedEntry = resolvePackageEntry(packageName, distEntry, fallbackWorkspacePackagePath);
11247
+ for (const target of PACKAGE_ALIASES) {
11248
+ const { find, packageName, fallbackWorkspacePackagePath } = target;
11249
+ const resolvedEntry = resolvePackageEntry(packageName, resolveWevuRuntimeDistEntry(target, options), fallbackWorkspacePackagePath);
11109
11250
  if (!resolvedEntry) continue;
11110
11251
  aliases.push({
11111
11252
  find,
@@ -11128,8 +11269,8 @@ function normalizeAliasOptions(alias) {
11128
11269
  };
11129
11270
  });
11130
11271
  }
11131
- function createAliasManager(oxcAlias, builtinAliases) {
11132
- function injectBuiltinAliases(config) {
11272
+ function createAliasManager(oxcAlias, defaultBuiltinAliases) {
11273
+ function injectBuiltinAliases(config, builtinAliases = defaultBuiltinAliases) {
11133
11274
  const resolve = config.resolve ?? (config.resolve = {});
11134
11275
  const aliasArray = normalizeAliasOptions(resolve.alias);
11135
11276
  if (!aliasArray.some((entry) => {
@@ -12193,7 +12334,7 @@ const handleCache = /* @__PURE__ */ new WeakMap();
12193
12334
  const inlineWxsTransformCache = /* @__PURE__ */ new Map();
12194
12335
  const INLINE_WXS_CACHE_LIMIT = 256;
12195
12336
  const IDENTIFIER_CHAR_RE = /[\w$]/;
12196
- function escapeRegExp(source) {
12337
+ function escapeRegExp$1(source) {
12197
12338
  return source.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
12198
12339
  }
12199
12340
  function isInsideMustache(code, start, end) {
@@ -12258,7 +12399,7 @@ function replaceDefineImportMetaEnv(code, defineImportMetaEnv) {
12258
12399
  const replacementRanges = [];
12259
12400
  for (const [key, value] of entries) {
12260
12401
  if (!(key === "import.meta.url" || key === "import.meta.dirname" || key.startsWith("import.meta.env.")) || key === "import.meta.env") continue;
12261
- const pattern = new RegExp(escapeRegExp(key), "g");
12402
+ const pattern = new RegExp(escapeRegExp$1(key), "g");
12262
12403
  for (const match of code.matchAll(pattern)) {
12263
12404
  const start = match.index ?? -1;
12264
12405
  if (start < 0) continue;
@@ -12782,11 +12923,15 @@ function emitSfcTemplateIfMissing(ctx, bundle, relativeBase, template, extension
12782
12923
  });
12783
12924
  emittedAssetSourceCache.set(cacheKey, template);
12784
12925
  }
12785
- function emitSfcStyleIfMissing(ctx, bundle, relativeBase, style, extension = "wxss") {
12926
+ function emitSfcStyleIfMissing(ctx, bundle, relativeBase, style, extension = "wxss", options) {
12786
12927
  const fileName = resolveSfcAssetFileName(relativeBase, extension);
12787
12928
  const cacheKey = `asset:${fileName}`;
12788
12929
  const existing = bundle[fileName];
12789
12930
  if (existing && existing.type === "asset") {
12931
+ if (options?.updateExisting === false) {
12932
+ emittedAssetSourceCache.set(cacheKey, existing.source?.toString?.() ?? "");
12933
+ return;
12934
+ }
12790
12935
  if ((existing.source?.toString?.() ?? "") !== style) existing.source = style;
12791
12936
  emittedAssetSourceCache.set(cacheKey, style);
12792
12937
  return;
@@ -13890,7 +14035,7 @@ function resolveRelativeJsonOutputFileName(configService, filePath) {
13890
14035
  }
13891
14036
  //#endregion
13892
14037
  //#region src/plugins/hooks/useLoadEntry/chunkEmitter.ts
13893
- function createChunkEmitter(configService, loadedEntrySet, debug, trackEmittedEntryId) {
14038
+ function createChunkEmitter(configService, loadedEntrySet, debug, trackEmittedEntryId, trackEmittedChunkId, shouldEmitEntryChunk, preloadAssetOnlyEntry) {
13894
14039
  return function emitEntriesChunks(resolvedIds) {
13895
14040
  return resolvedIds.map(async (resolvedId) => {
13896
14041
  if (!resolvedId) return;
@@ -13898,14 +14043,19 @@ function createChunkEmitter(configService, loadedEntrySet, debug, trackEmittedEn
13898
14043
  const shouldPreload = !loadedEntrySet.has(normalizedId);
13899
14044
  loadedEntrySet.add(normalizedId);
13900
14045
  const start = shouldPreload ? performance$1.now() : 0;
13901
- if (shouldPreload) await this.load(resolvedId);
14046
+ const shouldEmitChunk = shouldEmitEntryChunk?.(normalizedId, resolvedId) ?? true;
14047
+ if (shouldPreload) if (!shouldEmitChunk && preloadAssetOnlyEntry) await preloadAssetOnlyEntry.call(this, resolvedId, normalizedId);
14048
+ else await this.load(resolvedId);
13902
14049
  const fileName = resolveRelativeOutputFileNameWithExtension(configService, resolvedId.id, ".js");
13903
- this.emitFile({
13904
- type: "chunk",
13905
- id: resolvedId.id,
13906
- fileName,
13907
- preserveSignature: "exports-only"
13908
- });
14050
+ if (shouldEmitChunk) {
14051
+ this.emitFile({
14052
+ type: "chunk",
14053
+ id: resolvedId.id,
14054
+ fileName,
14055
+ preserveSignature: "exports-only"
14056
+ });
14057
+ trackEmittedChunkId?.(normalizedId);
14058
+ }
13909
14059
  trackEmittedEntryId?.(normalizedId);
13910
14060
  if (shouldPreload) debug?.(`load ${fileName} 耗时 ${(performance$1.now() - start).toFixed(2)}ms`);
13911
14061
  });
@@ -14005,11 +14155,28 @@ function buildNonJsonDescriptorPayload(descriptor, filename) {
14005
14155
  customBlocks: descriptor.customBlocks.filter((block) => block.type !== "json").map((block) => serializeBlock(block))
14006
14156
  };
14007
14157
  }
14158
+ function buildScriptDescriptorPayload(descriptor, filename) {
14159
+ const scriptSetupContent = descriptor.scriptSetup ? stripScriptSetupJsonMacros(descriptor.scriptSetup.content, filename) : void 0;
14160
+ return {
14161
+ script: serializeBlock(descriptor.script),
14162
+ scriptSetup: serializeBlock(descriptor.scriptSetup, scriptSetupContent)
14163
+ };
14164
+ }
14008
14165
  function resolveVueSfcNonJsonSignature(source, filename) {
14009
14166
  const { descriptor, errors } = parse(source, { filename });
14010
14167
  if (errors.length) return;
14011
14168
  return hashPayload(buildNonJsonDescriptorPayload(descriptor, filename));
14012
14169
  }
14170
+ function resolveVueSfcScriptSignature(source, filename) {
14171
+ const { descriptor, errors } = parse(source, { filename });
14172
+ if (errors.length) return;
14173
+ return hashPayload(buildScriptDescriptorPayload(descriptor, filename));
14174
+ }
14175
+ function resolveVueSfcHasTemplate(source, filename) {
14176
+ const { descriptor, errors } = parse(source, { filename });
14177
+ if (errors.length) return;
14178
+ return Boolean(descriptor.template?.content.trim());
14179
+ }
14013
14180
  //#endregion
14014
14181
  //#region src/plugins/utils/analyze.ts
14015
14182
  function collectPluginExportEntries(plugins, root) {
@@ -14853,6 +15020,11 @@ function addNormalizedWatchFile(pluginCtx, file) {
14853
15020
  pluginCtx.addWatchFile(normalizeWatchPath(file));
14854
15021
  return true;
14855
15022
  }
15023
+ function addNormalizedWatchFiles(pluginCtx, files) {
15024
+ let count = 0;
15025
+ for (const file of files) if (addNormalizedWatchFile(pluginCtx, file)) count += 1;
15026
+ return count;
15027
+ }
14856
15028
  //#endregion
14857
15029
  //#region src/plugins/hooks/useLoadEntry/loadEntry/watch.ts
14858
15030
  async function addWatchTarget(pluginCtx, target, existsCache, ttlMs) {
@@ -15148,7 +15320,7 @@ function prepareNormalizedEntries(options) {
15148
15320
  return normalizedEntries;
15149
15321
  }
15150
15322
  async function emitEntryOutput(options) {
15151
- const { pluginCtx, id, type, json: initialJson, jsonPath, templatePath, isPluginBuild, normalizedEntries, pluginResolvedRecords, pluginJsonPathForRegistration, pluginJsonForRegistration, resolveEntriesWithCache, entryResolveRoot, configService, wxmlService, resolvedEntryMap, loadedEntrySet, dirtyEntrySet, replaceLayoutDependencies, emitEntriesChunks, registerJsonAsset, existsCache, pathExistsTtlMs, debug, relativeCwdId, getTime, emittedWxmlCodeCache } = options;
15323
+ const { pluginCtx, id, type, json: initialJson, jsonPath, templatePath, isPluginBuild, normalizedEntries, pluginResolvedRecords, pluginJsonPathForRegistration, pluginJsonForRegistration, resolveEntriesWithCache, entryResolveRoot, configService, wxmlService, resolvedEntryMap, loadedEntrySet, dirtyEntrySet, forceEmitEntrySet, replaceLayoutDependencies, emitEntriesChunks, registerJsonAsset, existsCache, pathExistsTtlMs, debug, relativeCwdId, getTime, emittedWxmlCodeCache } = options;
15152
15324
  let json = initialJson;
15153
15325
  async function emitNativeLayoutAssets(layoutBasePath) {
15154
15326
  if (typeof pluginCtx.emitFile !== "function") return;
@@ -15237,10 +15409,11 @@ async function emitEntryOutput(options) {
15237
15409
  const normalizedResolvedId = normalizeFsResolvedId(resolvedId.id);
15238
15410
  if (normalizedResolvedId && !isSkippableResolvedId(normalizedResolvedId) && path.isAbsolute(normalizedResolvedId)) addNormalizedWatchFile(pluginCtx, normalizedResolvedId);
15239
15411
  if (normalizedResolvedId && !isSkippableResolvedId(normalizedResolvedId)) resolvedEntryMap.set(normalizedResolvedId, resolvedId);
15412
+ const isForcedEntry = forceEmitEntrySet?.has(entry) === true || forceEmitEntrySet?.has(normalizedResolvedId) === true;
15240
15413
  const isDirtyEntry = dirtyEntrySet.has(normalizedResolvedId);
15241
- if (!isDirtyEntry && loadedEntrySet.has(normalizedResolvedId)) continue;
15414
+ if (!isDirtyEntry && !isForcedEntry && loadedEntrySet.has(normalizedResolvedId)) continue;
15242
15415
  pendingResolvedIds.push(resolvedId);
15243
- if (isDirtyEntry) dirtyEntrySet.delete(normalizedResolvedId);
15416
+ if (isDirtyEntry || isForcedEntry) dirtyEntrySet.delete(normalizedResolvedId);
15244
15417
  }
15245
15418
  if (pendingResolvedIds.length) await Promise.all(emitEntriesChunks.call(pluginCtx, pendingResolvedIds));
15246
15419
  debug?.(`emitEntriesChunks ${relativeCwdId} 耗时 ${getTime()}`);
@@ -15298,6 +15471,7 @@ async function emitEntryOutput(options) {
15298
15471
  }
15299
15472
  //#endregion
15300
15473
  //#region src/plugins/hooks/useLoadEntry/loadEntry/resolve.ts
15474
+ const LEADING_ROOT_SLASH_RE = /^[/\\]+/;
15301
15475
  function createEntryResolver(configService) {
15302
15476
  const entryResolutionCache = /* @__PURE__ */ new Map();
15303
15477
  async function resolveEntryWithCache(pluginCtx, absPath) {
@@ -15321,7 +15495,7 @@ function createEntryResolver(configService) {
15321
15495
  return Promise.all(entries.filter((entry) => !entry.includes(":")).map(async (entry) => {
15322
15496
  return {
15323
15497
  entry,
15324
- resolvedId: await resolveEntryWithCache(pluginCtx, path.resolve(absoluteRoot, entry))
15498
+ resolvedId: await resolveEntryWithCache(pluginCtx, path.isAbsolute(entry) && await fs.pathExists(entry) ? entry : path.resolve(absoluteRoot, entry.replace(LEADING_ROOT_SLASH_RE, "")))
15325
15499
  };
15326
15500
  }));
15327
15501
  }
@@ -15513,6 +15687,7 @@ function createEntryLoader(options) {
15513
15687
  const relativeCwdId = configService.relativeCwd(id);
15514
15688
  const normalizedId = normalizeFsResolvedId(id);
15515
15689
  const libConfig = configService.weappLibConfig;
15690
+ let appVueNonJsonSignature;
15516
15691
  const libEntry = libConfig?.enabled && normalizedId ? ctx.runtimeState.lib.entries.get(normalizedId) : void 0;
15517
15692
  addNormalizedWatchFile(this, id);
15518
15693
  const baseName = removeExtensionDeep(id);
@@ -15554,8 +15729,9 @@ function createEntryLoader(options) {
15554
15729
  let pluginJsonForRegistration;
15555
15730
  let appResult;
15556
15731
  let shouldSkipAppEntries = false;
15732
+ const forceEmitEntrySet = /* @__PURE__ */ new Set();
15557
15733
  const nativeLayoutScriptEntries = /* @__PURE__ */ new Set();
15558
- const autoRoutesSignature = configService.isDev ? ctx.autoRoutesService?.getSignature?.() : void 0;
15734
+ let autoRoutesSignature = configService.isDev ? ctx.autoRoutesService?.getSignature?.() : void 0;
15559
15735
  const registerPageLayoutComponentEntries = async (layoutPlan, options) => {
15560
15736
  if (options?.trackLayoutDependencies) {
15561
15737
  const layoutDependencies = /* @__PURE__ */ new Set();
@@ -15583,6 +15759,19 @@ function createEntryLoader(options) {
15583
15759
  }
15584
15760
  };
15585
15761
  if (type === "app") {
15762
+ const vueEntryPath = await findVueEntry(baseName);
15763
+ const normalizedVueEntryPath = vueEntryPath ? normalizeFsResolvedId(vueEntryPath) : void 0;
15764
+ if (configService.isDev && vueEntryPath) {
15765
+ const vueSource = await fs.readFile(vueEntryPath, "utf-8").catch(() => void 0);
15766
+ if (vueSource) {
15767
+ appVueNonJsonSignature = resolveVueSfcNonJsonSignature(vueSource, vueEntryPath);
15768
+ if (appVueNonJsonSignature) ctx.runtimeState.build.hmr.vueEntryNonJsonSignatures.set(normalizeFsResolvedId(vueEntryPath), appVueNonJsonSignature);
15769
+ const scriptSignature = resolveVueSfcScriptSignature(vueSource, vueEntryPath);
15770
+ if (scriptSignature) ctx.runtimeState.build.hmr.vueEntryScriptSignatures.set(normalizeFsResolvedId(vueEntryPath), scriptSignature);
15771
+ const hasTemplate = resolveVueSfcHasTemplate(vueSource, vueEntryPath);
15772
+ if (hasTemplate !== void 0) ctx.runtimeState.build.hmr.vueEntryHasTemplate.set(normalizeFsResolvedId(vueEntryPath), hasTemplate);
15773
+ }
15774
+ }
15586
15775
  appResult = await collectAppEntries({
15587
15776
  pluginCtx: this,
15588
15777
  id,
@@ -15597,6 +15786,7 @@ function createEntryLoader(options) {
15597
15786
  extendedLibManager,
15598
15787
  cache: appEntriesCache
15599
15788
  });
15789
+ autoRoutesSignature = configService.isDev ? ctx.autoRoutesService?.getSignature?.() : void 0;
15600
15790
  entries.push(...appResult.entries);
15601
15791
  if (get(json, "tabBar.custom")) explicitEntryTypes.set(normalizeEntry("custom-tab-bar/index", jsonPath), "component");
15602
15792
  if (get(json, "appBar")) explicitEntryTypes.set(normalizeEntry("app-bar/index", jsonPath), "component");
@@ -15607,7 +15797,7 @@ function createEntryLoader(options) {
15607
15797
  });
15608
15798
  pluginJsonPathForRegistration = appResult.pluginJsonPathForRegistration;
15609
15799
  pluginJsonForRegistration = appResult.pluginJsonForRegistration;
15610
- shouldSkipAppEntries = Boolean(configService.isDev && !isPluginBuild && appResult.cacheHit && appEntryOutputCache.current && appEntryOutputCache.current.appSignature === appResult.appSignature && appEntryOutputCache.current.pluginSignature === appResult.pluginSignature && appEntryOutputCache.current.pluginJsonPath === appResult.pluginJsonPath && appEntryOutputCache.current.autoRoutesSignature === autoRoutesSignature && appEntryOutputCache.current.resolveCacheVersion === resolveCacheVersion);
15800
+ shouldSkipAppEntries = Boolean(configService.isDev && !isPluginBuild && !dirtyEntrySet.has(normalizedId) && !dirtyEntrySet.has(normalizedVueEntryPath ?? "") && appResult.cacheHit && appEntryOutputCache.current && appEntryOutputCache.current.appSignature === appResult.appSignature && appEntryOutputCache.current.appVueNonJsonSignature === appVueNonJsonSignature && appEntryOutputCache.current.pluginSignature === appResult.pluginSignature && appEntryOutputCache.current.pluginJsonPath === appResult.pluginJsonPath && appEntryOutputCache.current.autoRoutesSignature === autoRoutesSignature && appEntryOutputCache.current.resolveCacheVersion === resolveCacheVersion);
15611
15801
  } else {
15612
15802
  templatePath = await scanTemplateEntry(this, id, scanTemplateEntryFn, existsCache, pathExistsTtlMs);
15613
15803
  if (libEntry && libConfig) {
@@ -15660,16 +15850,29 @@ function createEntryLoader(options) {
15660
15850
  if (vueSource) {
15661
15851
  const nonJsonSignature = resolveVueSfcNonJsonSignature(vueSource, vueEntryPath);
15662
15852
  if (nonJsonSignature) ctx.runtimeState.build.hmr.vueEntryNonJsonSignatures.set(normalizedId, nonJsonSignature);
15853
+ const scriptSignature = resolveVueSfcScriptSignature(vueSource, vueEntryPath);
15854
+ if (scriptSignature) ctx.runtimeState.build.hmr.vueEntryScriptSignatures.set(normalizedId, scriptSignature);
15855
+ const hasTemplate = resolveVueSfcHasTemplate(vueSource, vueEntryPath);
15856
+ if (hasTemplate !== void 0) ctx.runtimeState.build.hmr.vueEntryHasTemplate.set(normalizedId, hasTemplate);
15663
15857
  }
15664
15858
  }
15665
15859
  await ctx.autoImportService?.awaitPendingRegistrations?.();
15666
15860
  applyAutoImports(baseName, json);
15667
15861
  const componentEntries = analyzeCommonJson(json);
15668
- const pendingAutoImportEntries = Array.from(ctx.runtimeState?.autoImport?.pendingEntriesByImporter.get(baseName) ?? []);
15669
- if (pendingAutoImportEntries.length) ctx.runtimeState?.autoImport?.pendingEntriesByImporter.delete(baseName);
15862
+ const pendingAutoImportMap = ctx.runtimeState?.autoImport?.pendingEntriesByImporter;
15863
+ const vueBaseName = vueEntryPath ? removeExtensionDeep(vueEntryPath) : void 0;
15864
+ const pendingAutoImportEntries = Array.from(new Set([...Array.from(pendingAutoImportMap?.get(baseName) ?? []), ...Array.from(vueBaseName ? pendingAutoImportMap?.get(vueBaseName) ?? [] : [])]));
15865
+ if (pendingAutoImportEntries.length) {
15866
+ pendingAutoImportMap?.delete(baseName);
15867
+ if (vueBaseName) pendingAutoImportMap?.delete(vueBaseName);
15868
+ }
15670
15869
  const mergedComponentEntries = Array.from(new Set([...componentEntries, ...pendingAutoImportEntries]));
15671
15870
  entries.push(...mergedComponentEntries);
15672
- for (const componentEntry of mergedComponentEntries) explicitEntryTypes.set(normalizeEntry(componentEntry, jsonPath), "component");
15871
+ for (const componentEntry of mergedComponentEntries) {
15872
+ const normalizedComponentEntry = normalizeEntry(componentEntry, jsonPath);
15873
+ explicitEntryTypes.set(normalizedComponentEntry, "component");
15874
+ if (pendingAutoImportEntries.includes(componentEntry)) forceEmitEntrySet.add(normalizedComponentEntry);
15875
+ }
15673
15876
  }
15674
15877
  const normalizedEntries = shouldSkipAppEntries ? [] : prepareNormalizedEntries({
15675
15878
  entries,
@@ -15705,6 +15908,7 @@ function createEntryLoader(options) {
15705
15908
  resolvedEntryMap,
15706
15909
  loadedEntrySet,
15707
15910
  dirtyEntrySet,
15911
+ forceEmitEntrySet,
15708
15912
  replaceLayoutDependencies,
15709
15913
  emitEntriesChunks,
15710
15914
  registerJsonAsset,
@@ -15718,6 +15922,7 @@ function createEntryLoader(options) {
15718
15922
  });
15719
15923
  if (type === "app" && !shouldSkipAppEntries && appResult) appEntryOutputCache.current = {
15720
15924
  appSignature: appResult.appSignature,
15925
+ appVueNonJsonSignature,
15721
15926
  pluginSignature: appResult.pluginSignature,
15722
15927
  pluginJsonPath: appResult.pluginJsonPath,
15723
15928
  autoRoutesSignature,
@@ -15769,6 +15974,10 @@ function createTemplateScanner(wxmlService, debug) {
15769
15974
  }
15770
15975
  //#endregion
15771
15976
  //#region src/plugins/hooks/useLoadEntry/index.ts
15977
+ function shouldExpandStableSharedChunk(chunkId, importers) {
15978
+ if ((importers?.size ?? 0) <= 1) return false;
15979
+ return chunkId.startsWith("weapp-vendors/") || !chunkId.includes("/") && chunkId !== "app.js";
15980
+ }
15772
15981
  function resolveUpstreamPendingReasonSummary(dirtyReasonSummary) {
15773
15982
  if (!dirtyReasonSummary?.length) return [];
15774
15983
  const pendingReasonSummary = [];
@@ -15804,7 +16013,11 @@ function resolvePendingEntryIds(options) {
15804
16013
  if (dirtyReason !== "dependency" && dirtyReason !== "direct" && dirtyReason !== "metadata") continue;
15805
16014
  const chunkIds = options.sharedChunksByEntry.get(entryId);
15806
16015
  if (!chunkIds?.size) continue;
15807
- for (const chunkId of chunkIds) if (dirtyReason === "dependency" || !options.sourceSharedChunks?.has(chunkId)) relatedChunkIds.add(chunkId);
16016
+ for (const chunkId of chunkIds) {
16017
+ const isSourceSharedChunk = options.sourceSharedChunks?.has(chunkId) === true;
16018
+ if (dirtyReason === "metadata") continue;
16019
+ if (dirtyReason === "dependency" || !isSourceSharedChunk || shouldExpandStableSharedChunk(chunkId, options.sharedChunkImporters?.get(chunkId))) relatedChunkIds.add(chunkId);
16020
+ }
15808
16021
  }
15809
16022
  if (!relatedChunkIds.size) return {
15810
16023
  pending,
@@ -15813,6 +16026,7 @@ function resolvePendingEntryIds(options) {
15813
16026
  };
15814
16027
  const expandedImporters = /* @__PURE__ */ new Set();
15815
16028
  let expansionMode = null;
16029
+ let hasStableSharedChunkExpansion = false;
15816
16030
  for (const chunkId of relatedChunkIds) {
15817
16031
  const importers = options.sharedChunkImporters.get(chunkId);
15818
16032
  if (!importers) continue;
@@ -15832,6 +16046,7 @@ function resolvePendingEntryIds(options) {
15832
16046
  if (options.dirtyEntrySet.has(importer) && options.dirtyEntryReasons.get(importer) === "metadata") hasMetadataDirtyImporter = true;
15833
16047
  }
15834
16048
  if (!hasDependencyDrivenImporter && !hasDirectDirtyImporter && !hasMetadataDirtyImporter && !shouldExpandLayoutSharedChunks) continue;
16049
+ if (shouldExpandStableSharedChunk(chunkId, importers)) hasStableSharedChunkExpansion = true;
15835
16050
  if (shouldExpandLayoutSharedChunks && !hasDependencyDrivenImporter && !hasDirectDirtyImporter && !hasMetadataDirtyImporter) expansionMode = expansionMode && expansionMode !== "dependency" ? "mixed" : "dependency";
15836
16051
  else if ([
15837
16052
  hasDependencyDrivenImporter,
@@ -15858,9 +16073,14 @@ function resolvePendingEntryIds(options) {
15858
16073
  return {
15859
16074
  pending,
15860
16075
  sharedChunkResolveMs: performance.now() - startedAt,
15861
- pendingReasonSummary
16076
+ pendingReasonSummary,
16077
+ shouldEmitAllEntries: hasStableSharedChunkExpansion && pending.size === options.resolvedEntryMap.size,
16078
+ forceFullSharedChunkRefresh: hasStableSharedChunkExpansion && pending.size === options.resolvedEntryMap.size
15862
16079
  };
15863
16080
  }
16081
+ function shouldPreloadEntryAssetOnly(dirtyReasonSummary) {
16082
+ return dirtyReasonSummary?.some((item) => item.startsWith("json-sidecar:") || item.startsWith("style-sidecar:") || item.startsWith("entry-local-asset:")) === true;
16083
+ }
15864
16084
  function useLoadEntry(ctx, options) {
15865
16085
  const debug = createDebugger("weapp-vite:load-entry");
15866
16086
  const buildTarget = options?.buildTarget ?? "app";
@@ -15872,14 +16092,32 @@ function useLoadEntry(ctx, options) {
15872
16092
  const layoutEntryDependents = ctx.runtimeState.build.hmr.layoutEntryDependents;
15873
16093
  const entryLayoutDependencies = ctx.runtimeState.build.hmr.entryLayoutDependencies;
15874
16094
  const lastActualEmittedEntryIds = /* @__PURE__ */ new Set();
16095
+ const lastChunkEmittedEntryIds = /* @__PURE__ */ new Set();
16096
+ const metadataEntryIds = /* @__PURE__ */ new Set();
15875
16097
  const jsonEmitManager = createJsonEmitManager(ctx.configService);
15876
16098
  const registerJsonAsset = jsonEmitManager.register.bind(jsonEmitManager);
15877
16099
  const normalizeEntry = createEntryNormalizer(ctx.configService);
15878
16100
  const scanTemplateEntry = createTemplateScanner(ctx.wxmlService, debug);
16101
+ const rootInputIds = options?.hmr?.rootInputIds;
16102
+ let loadEntry;
15879
16103
  const emitEntriesChunks = createChunkEmitter(ctx.configService, loadedEntrySet, debug, (entryId) => {
15880
16104
  lastActualEmittedEntryIds.add(entryId);
16105
+ }, (entryId) => {
16106
+ lastChunkEmittedEntryIds.add(entryId);
16107
+ }, (entryId) => !rootInputIds?.has(entryId) && !metadataEntryIds.has(entryId), async function preloadAssetOnlyEntry(resolvedId, entryId) {
16108
+ if (rootInputIds?.has(entryId)) {
16109
+ await loadEntry.call(this, resolvedId.id, "app");
16110
+ await this.load(resolvedId);
16111
+ return;
16112
+ }
16113
+ if (!shouldPreloadEntryAssetOnly(ctx.runtimeState.build.hmr.profile.dirtyReasonSummary)) {
16114
+ await this.load(resolvedId);
16115
+ return;
16116
+ }
16117
+ const entryType = entriesMap.get(entryId)?.type === "page" ? "page" : "component";
16118
+ await loadEntry.call(this, resolvedId.id, entryType);
15881
16119
  });
15882
- const loadEntry = createEntryLoader({
16120
+ loadEntry = createEntryLoader({
15883
16121
  ctx,
15884
16122
  entriesMap,
15885
16123
  loadedEntrySet,
@@ -15940,6 +16178,8 @@ function useLoadEntry(ctx, options) {
15940
16178
  if (!dirtyEntrySet.size) {
15941
16179
  options?.hmr?.setDidEmitAllEntries?.(false);
15942
16180
  options?.hmr?.setLastEmittedEntries?.(/* @__PURE__ */ new Set());
16181
+ options?.hmr?.setLastHmrEntries?.(/* @__PURE__ */ new Set());
16182
+ options?.hmr?.setSkipSharedChunkRefresh?.(true);
15943
16183
  return;
15944
16184
  }
15945
16185
  const emitStartedAt = performance.now();
@@ -15958,18 +16198,32 @@ function useLoadEntry(ctx, options) {
15958
16198
  const pendingEntryIds = pendingResolution.pending;
15959
16199
  const pending = [];
15960
16200
  lastActualEmittedEntryIds.clear();
16201
+ lastChunkEmittedEntryIds.clear();
16202
+ metadataEntryIds.clear();
15961
16203
  for (const entryId of pendingEntryIds) {
16204
+ if (dirtyEntryReasons.get(entryId) === "metadata") metadataEntryIds.add(entryId);
15962
16205
  dirtyEntrySet.delete(entryId);
15963
16206
  dirtyEntryReasons.delete(entryId);
15964
16207
  const resolvedId = resolvedEntryMap.get(entryId);
15965
16208
  if (!resolvedId) continue;
15966
16209
  pending.push(resolvedId);
15967
16210
  }
16211
+ for (const resolvedId of pending) {
16212
+ const baseName = removeExtensionDeep(resolvedId.id);
16213
+ if (!ctx.runtimeState.autoImport?.pendingEntriesByImporter.has(baseName)) continue;
16214
+ const entryType = entriesMap.get(ctx.configService.relativeAbsoluteSrcRoot(baseName))?.type === "component" ? "component" : "page";
16215
+ await loadEntry.call(this, resolvedId.id, entryType);
16216
+ }
15968
16217
  if (pending.length) await Promise.all(emitEntriesChunks.call(this, pending));
15969
16218
  const actualEmittedEntryIds = new Set(lastActualEmittedEntryIds);
15970
- const shouldEmitAllEntries = actualEmittedEntryIds.size > 0 && actualEmittedEntryIds.size === resolvedEntryMap.size;
16219
+ const actualChunkEmittedEntryIds = new Set(lastChunkEmittedEntryIds);
16220
+ const hmrEntryIds = new Set(actualEmittedEntryIds);
16221
+ const skipSharedChunkRefresh = actualChunkEmittedEntryIds.size === 0;
16222
+ const shouldEmitAllEntries = actualChunkEmittedEntryIds.size > 0 && (actualEmittedEntryIds.size === resolvedEntryMap.size || pendingResolution.shouldEmitAllEntries === true);
15971
16223
  options?.hmr?.setDidEmitAllEntries?.(shouldEmitAllEntries);
15972
- options?.hmr?.setLastEmittedEntries?.(actualEmittedEntryIds);
16224
+ options?.hmr?.setLastEmittedEntries?.(pendingResolution.forceFullSharedChunkRefresh === true ? new Set(resolvedEntryMap.keys()) : actualChunkEmittedEntryIds);
16225
+ options?.hmr?.setLastHmrEntries?.(hmrEntryIds);
16226
+ options?.hmr?.setSkipSharedChunkRefresh?.(skipSharedChunkRefresh);
15973
16227
  ctx.runtimeState.build.hmr.profile = {
15974
16228
  ...ctx.runtimeState.build.hmr.profile,
15975
16229
  emitMs: performance.now() - emitStartedAt,
@@ -15987,6 +16241,9 @@ function useLoadEntry(ctx, options) {
15987
16241
  //#region src/plugins/core/helpers/bundle.ts
15988
16242
  const IMPLICIT_REQUIRE_RE = /\b(?:const|let|var)\s+[A-Za-z_$][\w$]*\s*=\s*require\((`[^`]+`|'[^']+'|"[^"]+")\);?/g;
15989
16243
  const REQUIRE_CALL_RE = /\brequire\((`[^`]+`|'[^']+'|"[^"]+")\)/g;
16244
+ const WEVU_SRC_CHUNK_RE = /(?:^|\/)wevu-src\.js$/;
16245
+ const WEVU_EXPORT_ALIASES = [["defineComponent", "__wevuDefineComponent"], ["createWevuComponent", "__wevuCreateWevuComponent"]];
16246
+ const JS_IDENTIFIER_RE = /^[A-Z_$][\w$]*$/i;
15990
16247
  function filterPluginBundleOutputs(bundle, configService) {
15991
16248
  if (configService.pluginOnly) return;
15992
16249
  const pluginOutputRoot = configService.absolutePluginOutputRoot;
@@ -16094,6 +16351,122 @@ function syncChunkImportsFromRequireCalls(bundle) {
16094
16351
  chunk.imports = [...nextImports];
16095
16352
  }
16096
16353
  }
16354
+ function resolveRequireTarget(fromFile, specifier) {
16355
+ if (!specifier.startsWith(".")) return "";
16356
+ return resolveRelativeImport(fromFile, specifier);
16357
+ }
16358
+ function escapeRegExp(value) {
16359
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
16360
+ }
16361
+ function collectLocalRuntimeIdentifiers(code) {
16362
+ const identifiers = /* @__PURE__ */ new Set();
16363
+ for (const match of code.matchAll(/\b(?:function|class)\s+([A-Za-z_$][\w$]*)\b/g)) identifiers.add(match[1]);
16364
+ for (const match of code.matchAll(/\b(?:const|let|var)\s+([A-Za-z_$][\w$]*)\s*=/g)) identifiers.add(match[1]);
16365
+ return identifiers;
16366
+ }
16367
+ function resolveWevuExportAliasMap(wevuChunk) {
16368
+ const aliases = /* @__PURE__ */ new Map();
16369
+ const code = wevuChunk.code;
16370
+ const localIdentifiers = collectLocalRuntimeIdentifiers(code);
16371
+ for (const [exportName] of WEVU_EXPORT_ALIASES) {
16372
+ const exportMatch = new RegExp(`\\b([A-Za-z_$][\\w$]*)\\s+as\\s+${exportName}\\b`).exec(code);
16373
+ if (exportMatch?.[1]) aliases.set(exportName, exportMatch[1]);
16374
+ }
16375
+ const propertyExports = Array.from(code.matchAll(/Object\.defineProperty\(exports,\s*["']([^"']+)["'][\s\S]*?return\s+([A-Za-z_$][\w$]*)\s*(?:;\s*)?\}/g));
16376
+ for (const [exportName] of WEVU_EXPORT_ALIASES) {
16377
+ if (aliases.has(exportName)) continue;
16378
+ const semanticExport = propertyExports.find((match) => match[1] === exportName);
16379
+ if (semanticExport?.[2]) {
16380
+ aliases.set(exportName, semanticExport[2]);
16381
+ continue;
16382
+ }
16383
+ const stableExport = propertyExports.find((match) => match[1] === `__wevu${exportName[0].toUpperCase()}${exportName.slice(1)}`);
16384
+ if (stableExport?.[2]) {
16385
+ aliases.set(exportName, stableExport[2]);
16386
+ continue;
16387
+ }
16388
+ }
16389
+ if (!aliases.has("defineComponent") && localIdentifiers.has("eo")) aliases.set("defineComponent", "eo");
16390
+ if (!aliases.has("createWevuComponent") && localIdentifiers.has("to")) aliases.set("createWevuComponent", "to");
16391
+ if (!aliases.has("defineComponent")) {
16392
+ const createWevuComponentLocal = (propertyExports.find((match) => match[1] === "createWevuComponent") ?? propertyExports.find((match) => match[1] === "__wevuCreateWevuComponent"))?.[2];
16393
+ if (createWevuComponentLocal) {
16394
+ const functionMatch = new RegExp(`function\\s+${createWevuComponentLocal}\\s*\\([^)]*\\)\\s*\\{[\\s\\S]{0,500}?\\b([A-Za-z_$][\\w$]*)\\s*\\(`).exec(code);
16395
+ if (functionMatch?.[1]) aliases.set("defineComponent", functionMatch[1]);
16396
+ }
16397
+ }
16398
+ return aliases;
16399
+ }
16400
+ function collectExistingExportNames(code) {
16401
+ return new Set(Array.from(code.matchAll(/Object\.defineProperty\(exports,\s*["']([^"']+)["']/g), (match) => match[1]));
16402
+ }
16403
+ function collectImportedWevuRuntimeMembers(bundle, wevuChunkFileName) {
16404
+ const members = /* @__PURE__ */ new Set();
16405
+ for (const output of Object.values(bundle)) {
16406
+ if (!output || output.type !== "chunk" || typeof output.code !== "string" || output.fileName === wevuChunkFileName) continue;
16407
+ const chunk = output;
16408
+ const runtimeRefs = /* @__PURE__ */ new Set();
16409
+ for (const match of chunk.code.matchAll(/\b(?:const|let|var)\s+([A-Za-z_$][\w$]*)\s*=\s*require\((`[^`]+`|'[^']+'|"[^"]+")\);?/g)) if (resolveRequireTarget(chunk.fileName, stripQuotes(match[2])) === wevuChunkFileName) runtimeRefs.add(match[1]);
16410
+ for (const ref of runtimeRefs) {
16411
+ const memberRe = new RegExp(`\\b${escapeRegExp(ref)}\\.([A-Za-z_$][\\w$]*)\\b`, "g");
16412
+ for (const match of chunk.code.matchAll(memberRe)) members.add(match[1]);
16413
+ }
16414
+ for (const match of chunk.code.matchAll(/require\((`[^`]+`|'[^']+'|"[^"]+")\)\.([A-Za-z_$][\w$]*)\b/g)) if (resolveRequireTarget(chunk.fileName, stripQuotes(match[1])) === wevuChunkFileName) members.add(match[2]);
16415
+ }
16416
+ return members;
16417
+ }
16418
+ function appendWevuRuntimeExports(chunk, aliases, importedMembers) {
16419
+ const lines = [];
16420
+ const existingExports = collectExistingExportNames(chunk.code);
16421
+ const localIdentifiers = collectLocalRuntimeIdentifiers(chunk.code);
16422
+ for (const [exportName, stableName] of WEVU_EXPORT_ALIASES) {
16423
+ const localName = aliases.get(exportName);
16424
+ if (!localName || existingExports.has(stableName)) continue;
16425
+ lines.push(`Object.defineProperty(exports, ${JSON.stringify(stableName)}, { enumerable: false, get: function() { return ${localName}; } });`);
16426
+ existingExports.add(stableName);
16427
+ }
16428
+ for (const member of importedMembers) {
16429
+ if (!JS_IDENTIFIER_RE.test(member) || existingExports.has(member) || !localIdentifiers.has(member)) continue;
16430
+ lines.push(`Object.defineProperty(exports, ${JSON.stringify(member)}, { enumerable: true, get: function() { return ${member}; } });`);
16431
+ existingExports.add(member);
16432
+ }
16433
+ if (lines.length) chunk.code = `${chunk.code}\n${lines.join("\n")}`;
16434
+ }
16435
+ function rewriteStableWevuRuntimeAccess(chunk, wevuChunkFileName, aliases) {
16436
+ if (!aliases.size) return;
16437
+ let nextCode = chunk.code;
16438
+ for (const [exportName, stableName] of WEVU_EXPORT_ALIASES) {
16439
+ const localName = aliases.get(exportName);
16440
+ if (!localName) continue;
16441
+ nextCode = nextCode.replace(/require\((`[^`]+`|'[^']+'|"[^"]+")\)\.([A-Za-z_$][\w$]*)\s*\(/g, (full, rawSpecifier, property) => {
16442
+ if (property !== localName && property !== stableName) return full;
16443
+ if (resolveRequireTarget(chunk.fileName, stripQuotes(rawSpecifier)) !== wevuChunkFileName) return full;
16444
+ return `(require(${rawSpecifier}).${stableName} || require(${rawSpecifier}).${property})(`;
16445
+ });
16446
+ const localRequireRe = /\b((?:const|let|var)\s+([A-Za-z_$][\w$]*)\s*=\s*require\((`[^`]+`|'[^']+'|"[^"]+")\);?)/g;
16447
+ const runtimeRefs = /* @__PURE__ */ new Set();
16448
+ for (const match of nextCode.matchAll(localRequireRe)) if (resolveRequireTarget(chunk.fileName, stripQuotes(match[3])) === wevuChunkFileName) runtimeRefs.add(match[2]);
16449
+ for (const ref of runtimeRefs) {
16450
+ const memberRe = new RegExp(`\\b${escapeRegExp(ref)}\\.(?:${stableName}|${localName})\\s*\\(`, "g");
16451
+ nextCode = nextCode.replace(memberRe, (full) => {
16452
+ return `(${ref}.${stableName} || ${ref}.${full.includes(`.${stableName}`) ? stableName : localName})(`;
16453
+ });
16454
+ }
16455
+ }
16456
+ chunk.code = nextCode;
16457
+ }
16458
+ function stabilizeWevuRuntimeChunkAccess(bundle) {
16459
+ const wevuChunk = Object.values(bundle).find((output) => {
16460
+ return output?.type === "chunk" && WEVU_SRC_CHUNK_RE.test(output.fileName);
16461
+ });
16462
+ if (!wevuChunk) return;
16463
+ const aliases = resolveWevuExportAliasMap(wevuChunk);
16464
+ appendWevuRuntimeExports(wevuChunk, aliases, collectImportedWevuRuntimeMembers(bundle, wevuChunk.fileName));
16465
+ for (const output of Object.values(bundle)) {
16466
+ if (!output || output.type !== "chunk" || typeof output.code !== "string" || output.fileName === wevuChunk.fileName) continue;
16467
+ rewriteStableWevuRuntimeAccess(output, wevuChunk.fileName, aliases);
16468
+ }
16469
+ }
16097
16470
  //#endregion
16098
16471
  //#region src/plugins/core/helpers/bytes.ts
16099
16472
  function formatBytes(bytes) {
@@ -16347,114 +16720,576 @@ async function flushIndependentBuilds(state) {
16347
16720
  state.pendingIndependentBuilds = [];
16348
16721
  }
16349
16722
  //#endregion
16350
- //#region src/runtime/config/internal/injectRequestGlobals.ts
16351
- const FULL_REQUEST_GLOBAL_TARGETS = [
16352
- "fetch",
16353
- "Headers",
16354
- "Request",
16355
- "Response",
16356
- "TextEncoder",
16357
- "TextDecoder",
16358
- "AbortController",
16359
- "AbortSignal",
16360
- "XMLHttpRequest",
16361
- "WebSocket",
16362
- "atob",
16363
- "btoa",
16364
- "queueMicrotask",
16365
- "performance",
16366
- "crypto",
16367
- "Event",
16368
- "CustomEvent"
16369
- ];
16370
- const ABORT_REQUEST_GLOBAL_TARGETS = ["AbortController", "AbortSignal"];
16371
- const REQUEST_RUNTIME_REQUEST_TARGETS = [
16372
- "fetch",
16373
- "Headers",
16374
- "Request",
16375
- "Response",
16376
- "TextEncoder",
16377
- "TextDecoder",
16378
- "AbortController",
16379
- "AbortSignal",
16380
- "XMLHttpRequest"
16381
- ];
16382
- const REQUEST_RUNTIME_CORE_USAGE_TARGETS = new Set([
16383
- "fetch",
16384
- "Headers",
16385
- "Request",
16386
- "Response",
16387
- "XMLHttpRequest"
16388
- ]);
16389
- const DEFAULT_REQUEST_GLOBAL_DEPENDENCIES = [
16390
- "axios",
16391
- "graphql-request",
16392
- "socket.io-client",
16393
- "engine.io-client"
16394
- ];
16395
- const DEFAULT_ABORT_GLOBAL_DEPENDENCIES = ["@tanstack/query-core", "@tanstack/vue-query"];
16396
- const WEBSOCKET_USAGE_HINT_RE = /\bwebsocket\b/iu;
16397
- const REQUEST_GLOBAL_FREE_BINDING_TARGETS = new Set([
16398
- ...FULL_REQUEST_GLOBAL_TARGETS,
16399
- "URL",
16400
- "URLSearchParams",
16401
- "Blob",
16402
- "FormData"
16403
- ]);
16404
- const CODE_USAGE_AUTO_RULES = [
16405
- {
16406
- dependencyPatterns: ["axios", "graphql-request"],
16407
- targets: [...REQUEST_RUNTIME_REQUEST_TARGETS]
16408
- },
16409
- {
16410
- dependencyPatterns: ["socket.io-client", "engine.io-client"],
16411
- targets: [...FULL_REQUEST_GLOBAL_TARGETS]
16412
- },
16413
- {
16414
- dependencyPatterns: [...DEFAULT_ABORT_GLOBAL_DEPENDENCIES],
16415
- targets: [...ABORT_REQUEST_GLOBAL_TARGETS]
16416
- }
16417
- ];
16418
- function resolveAppPreludeWebRuntimeConfig(appPrelude, warn) {
16419
- if (!appPrelude || typeof appPrelude !== "object") return;
16420
- const webRuntime = appPrelude.webRuntime;
16421
- const requestRuntime = appPrelude.requestRuntime;
16422
- if (webRuntime !== void 0) {
16423
- if (requestRuntime !== void 0) warn?.("`weapp.appPrelude.requestRuntime` 已废弃,且当前会被 `weapp.appPrelude.webRuntime` 覆盖。请迁移到 `weapp.appPrelude.webRuntime`。");
16424
- if (typeof webRuntime === "boolean") return webRuntime ? {
16425
- enabled: true,
16426
- prelude: true
16427
- } : false;
16428
- return {
16429
- ...webRuntime,
16430
- prelude: true
16431
- };
16432
- }
16433
- if (requestRuntime === void 0) return;
16434
- warn?.("`weapp.appPrelude.requestRuntime` 已废弃,请迁移到 `weapp.appPrelude.webRuntime`。");
16435
- if (typeof requestRuntime === "boolean") return requestRuntime ? {
16436
- enabled: true,
16437
- prelude: true
16438
- } : false;
16439
- return {
16440
- ...requestRuntime,
16441
- prelude: true
16723
+ //#region src/postcss/constants.ts
16724
+ const IFDEF = "#ifdef";
16725
+ const IFNDEF = "#ifndef";
16726
+ //#endregion
16727
+ //#region src/postcss/post.ts
16728
+ function normalizeTargets(values) {
16729
+ return values.map((value) => value.trim().toLowerCase()).filter(Boolean);
16730
+ }
16731
+ function parseDirective(text) {
16732
+ const normalized = text.replace(/\*/g, "").trim();
16733
+ if (!normalized) return;
16734
+ const [keyword, ...rest] = normalized.split(/\s+/);
16735
+ if (!keyword) return;
16736
+ if (keyword === "#ifdef") return {
16737
+ type: "ifdef",
16738
+ targets: normalizeTargets(rest)
16739
+ };
16740
+ if (keyword === "#ifndef") return {
16741
+ type: "ifndef",
16742
+ targets: normalizeTargets(rest)
16743
+ };
16744
+ if (keyword === "#endif") return {
16745
+ type: "endif",
16746
+ targets: []
16442
16747
  };
16443
16748
  }
16444
- function hasMatchedDependency(packageJson, patterns) {
16445
- return [...new Set([
16446
- ...Object.keys(packageJson?.dependencies ?? {}),
16447
- ...Object.keys(packageJson?.devDependencies ?? {}),
16448
- ...Object.keys(packageJson?.peerDependencies ?? {})
16449
- ])].some((dependency) => {
16450
- return patterns.some((pattern) => {
16451
- if (typeof pattern === "string") return pattern === dependency;
16452
- pattern.lastIndex = 0;
16453
- return pattern.test(dependency);
16454
- });
16455
- });
16749
+ function removeConditionalBlock(start) {
16750
+ let depth = 1;
16751
+ let node = start.next();
16752
+ while (node && depth > 0) {
16753
+ if (node.type === "comment") {
16754
+ const directive = parseDirective(node.text);
16755
+ if (directive) if (directive.type === "endif") {
16756
+ depth -= 1;
16757
+ const comment = node;
16758
+ node = comment.next();
16759
+ comment.remove();
16760
+ continue;
16761
+ } else {
16762
+ depth += 1;
16763
+ const comment = node;
16764
+ node = comment.next();
16765
+ comment.remove();
16766
+ continue;
16767
+ }
16768
+ }
16769
+ const next = node.next();
16770
+ node.remove();
16771
+ node = next;
16772
+ }
16456
16773
  }
16457
- function resolveTargets(config) {
16774
+ const postCreator = (options = { platform: "weapp" }) => {
16775
+ const atRulePrefixRegExp = new RegExp(`^wv-`);
16776
+ const platform = options.platform.toLowerCase();
16777
+ return {
16778
+ postcssPlugin: "postcss-weapp-vite-plugin-post",
16779
+ prepare() {
16780
+ return {
16781
+ AtRule(atRule) {
16782
+ if (!atRulePrefixRegExp.test(atRule.name)) return;
16783
+ if (atRule.name === `wv-keep-import`) {
16784
+ atRule.name = "import";
16785
+ return;
16786
+ }
16787
+ if (atRule.name === `wv-if`) if (![...atRule.params.matchAll(/\(([^)]+)\)/g)].some((match) => {
16788
+ return match[1].trim() === platform;
16789
+ })) atRule.remove();
16790
+ else atRule.replaceWith(atRule.nodes);
16791
+ },
16792
+ Comment(comment) {
16793
+ const directive = parseDirective(comment.text);
16794
+ if (!directive) {
16795
+ comment.remove();
16796
+ return;
16797
+ }
16798
+ if (directive.type === "endif") {
16799
+ comment.remove();
16800
+ return;
16801
+ }
16802
+ const hasPlatform = directive.targets.includes(platform);
16803
+ if (!(directive.type === "ifdef" ? hasPlatform : !hasPlatform)) {
16804
+ removeConditionalBlock(comment);
16805
+ comment.remove();
16806
+ return;
16807
+ }
16808
+ comment.remove();
16809
+ }
16810
+ };
16811
+ }
16812
+ };
16813
+ };
16814
+ postCreator.postcss = true;
16815
+ //#endregion
16816
+ //#region src/postcss/index.ts
16817
+ const NEEDS_PROCESS_RE = new RegExp(`@wv-|${IFDEF}|${IFNDEF}`);
16818
+ async function cssPostProcess(code, options) {
16819
+ if (!NEEDS_PROCESS_RE.test(code)) return code;
16820
+ return (await postcss([postCreator(options)]).process(code, { from: void 0 })).css;
16821
+ }
16822
+ //#endregion
16823
+ //#region src/plugins/css/shared/preprocessor.ts
16824
+ const cssCodeCache = new LRUCache({ max: 512 });
16825
+ const sharedStyleCache = /* @__PURE__ */ new Map();
16826
+ const nodeRequire = (() => {
16827
+ try {
16828
+ return createRequire(import.meta.url);
16829
+ } catch {
16830
+ return null;
16831
+ }
16832
+ })();
16833
+ async function processCssWithCache(code, configService) {
16834
+ const cacheKey = createHash("sha1").update(configService.platform).update("\0").update(code).digest("base64url");
16835
+ let processed = cssCodeCache.get(cacheKey);
16836
+ if (!processed) {
16837
+ processed = await cssPostProcess(code, { platform: configService.platform });
16838
+ cssCodeCache.set(cacheKey, processed);
16839
+ }
16840
+ return processed;
16841
+ }
16842
+ function dedupeAndNormalizeDependencies(base, dependencies) {
16843
+ const seen = /* @__PURE__ */ new Set();
16844
+ const baseDir = path.dirname(base);
16845
+ for (const dep of dependencies) {
16846
+ if (!dep) continue;
16847
+ const normalized = path.isAbsolute(dep) ? dep : path.resolve(baseDir, dep);
16848
+ seen.add(normalized);
16849
+ }
16850
+ return Array.from(seen);
16851
+ }
16852
+ async function renderSharedStyleEntry(entry, _configService, resolvedConfig) {
16853
+ const absolutePath = entry.absolutePath;
16854
+ const cacheKey = `${absolutePath}:${resolvedConfig ? "resolved" : "raw"}`;
16855
+ let stats;
16856
+ try {
16857
+ stats = await fs.stat(absolutePath);
16858
+ } catch (error) {
16859
+ const reason = error instanceof Error ? error.message : String(error);
16860
+ throw new Error(`[分包] 编译共享样式 \`${entry.source}\` 失败:${reason}`);
16861
+ }
16862
+ const cached = sharedStyleCache.get(cacheKey);
16863
+ if (cached && cached.mtimeMs === stats.mtimeMs && cached.size === stats.size) return {
16864
+ css: cached.result.css,
16865
+ dependencies: [...cached.result.dependencies]
16866
+ };
16867
+ try {
16868
+ const css = await fs.readFile(absolutePath, "utf8");
16869
+ if (!resolvedConfig) {
16870
+ const result = {
16871
+ css,
16872
+ dependencies: []
16873
+ };
16874
+ sharedStyleCache.set(cacheKey, {
16875
+ mtimeMs: stats.mtimeMs,
16876
+ size: stats.size,
16877
+ result
16878
+ });
16879
+ return {
16880
+ css: result.css,
16881
+ dependencies: [...result.dependencies]
16882
+ };
16883
+ }
16884
+ const processed = await preprocessCSS(css, absolutePath, resolvedConfig);
16885
+ const dependencies = processed?.deps ? dedupeAndNormalizeDependencies(absolutePath, processed.deps) : [];
16886
+ const result = {
16887
+ css: processed.code,
16888
+ dependencies
16889
+ };
16890
+ sharedStyleCache.set(cacheKey, {
16891
+ mtimeMs: stats.mtimeMs,
16892
+ size: stats.size,
16893
+ result
16894
+ });
16895
+ return {
16896
+ css: result.css,
16897
+ dependencies: [...result.dependencies]
16898
+ };
16899
+ } catch (error) {
16900
+ const reason = error instanceof Error ? error.message : String(error);
16901
+ throw new Error(`[分包] 编译共享样式 \`${entry.source}\` 失败:${reason}`);
16902
+ }
16903
+ }
16904
+ function invalidateSharedStyleCache() {
16905
+ sharedStyleCache.clear();
16906
+ cssCodeCache.clear();
16907
+ try {
16908
+ const candidates = [
16909
+ "tailwindcss/lib/lib/sharedState.js",
16910
+ "tailwindcss/dist/sharedState.js",
16911
+ "tailwindcss/src/lib/sharedState.js",
16912
+ "tailwindcss/sharedState.js"
16913
+ ];
16914
+ if (!nodeRequire) return;
16915
+ for (const request of candidates) try {
16916
+ const sharedState = nodeRequire(request);
16917
+ if (sharedState) {
16918
+ sharedState.contextMap?.clear?.();
16919
+ sharedState.configContextMap?.clear?.();
16920
+ sharedState.contextSourcesMap?.clear?.();
16921
+ sharedState.sourceHashMap?.clear?.();
16922
+ break;
16923
+ }
16924
+ } catch {}
16925
+ } catch {}
16926
+ }
16927
+ //#endregion
16928
+ //#region src/plugins/css/shared/sharedStyles.ts
16929
+ const styleMatcherCache = /* @__PURE__ */ new WeakMap();
16930
+ function collectSharedStyleEntries(ctx, configService) {
16931
+ const map = /* @__PURE__ */ new Map();
16932
+ const registry = ctx.scanService?.subPackageMap;
16933
+ if (!registry?.size) return map;
16934
+ const currentRoot = configService.currentSubPackageRoot;
16935
+ for (const [root, meta] of registry.entries()) {
16936
+ if (!meta.styleEntries?.length) continue;
16937
+ if (currentRoot && root !== currentRoot) continue;
16938
+ map.set(root, meta.styleEntries);
16939
+ }
16940
+ return map;
16941
+ }
16942
+ function sanitizeRelativePath(value) {
16943
+ const normalized = toPosixPath(value);
16944
+ if (normalized.startsWith("./")) return normalized.slice(2);
16945
+ return normalized;
16946
+ }
16947
+ function isWithinRoot(pathname, root) {
16948
+ if (!root) return true;
16949
+ return pathname === root || pathname.startsWith(`${root}/`);
16950
+ }
16951
+ function relativeToRoot(pathname, root) {
16952
+ if (!pathname) return pathname;
16953
+ if (!root) return pathname;
16954
+ if (pathname === root) return "";
16955
+ if (pathname.startsWith(`${root}/`)) return pathname.slice(root.length + 1);
16956
+ }
16957
+ function getStyleMatcher(entry) {
16958
+ const cached = styleMatcherCache.get(entry);
16959
+ if (cached) return cached;
16960
+ const includePatterns = entry.include?.length ? entry.include : ["**/*"];
16961
+ const excludePatterns = entry.exclude?.length ? entry.exclude : void 0;
16962
+ const matcher = { include: pm(includePatterns, { dot: true }) };
16963
+ if (excludePatterns?.length) matcher.exclude = pm(excludePatterns, { dot: true });
16964
+ styleMatcherCache.set(entry, matcher);
16965
+ return matcher;
16966
+ }
16967
+ function matchesStyleEntry(entry, relativeModule, relativeFile) {
16968
+ const matcher = getStyleMatcher(entry);
16969
+ const candidates = [];
16970
+ if (typeof relativeFile === "string" && relativeFile.length > 0) candidates.push(relativeFile);
16971
+ if (typeof relativeModule === "string" && relativeModule.length > 0) candidates.push(relativeModule);
16972
+ if (!candidates.length) return false;
16973
+ if (!candidates.some((candidate) => matcher.include(candidate))) return false;
16974
+ if (matcher.exclude && candidates.some((candidate) => matcher.exclude(candidate))) return false;
16975
+ return true;
16976
+ }
16977
+ function findSharedStylesForModule(modulePath, fileName, sharedStyles) {
16978
+ const sanitizedModule = sanitizeRelativePath(modulePath);
16979
+ const sanitizedFile = sanitizeRelativePath(fileName);
16980
+ const matched = [];
16981
+ for (const [root, entries] of sharedStyles.entries()) {
16982
+ const normalizedRoot = normalizeRoot(root);
16983
+ if (!normalizedRoot) continue;
16984
+ if (!isWithinRoot(sanitizedFile, normalizedRoot)) continue;
16985
+ const relativeModule = relativeToRoot(sanitizedModule, normalizedRoot);
16986
+ const relativeFile = relativeToRoot(sanitizedFile, normalizedRoot);
16987
+ for (const entry of entries) if (matchesStyleEntry(entry, relativeModule, relativeFile)) matched.push(entry);
16988
+ }
16989
+ return matched;
16990
+ }
16991
+ function resolveImportSpecifiers(fileName, entries) {
16992
+ const posixFileName = toPosixPath(fileName);
16993
+ const dir = path.posix.dirname(posixFileName);
16994
+ const seen = /* @__PURE__ */ new Set();
16995
+ const specifiers = [];
16996
+ for (const entry of entries) {
16997
+ const target = toPosixPath(entry.outputRelativePath);
16998
+ if (target === posixFileName) continue;
16999
+ let specifier = path.posix.relative(dir, target) || path.posix.basename(target);
17000
+ if (!specifier || specifier === ".") continue;
17001
+ if (!specifier.startsWith(".")) specifier = `./${specifier}`;
17002
+ specifier = specifier.replace(/\/+/g, "/");
17003
+ if (specifier === "./") continue;
17004
+ if (seen.has(specifier)) continue;
17005
+ seen.add(specifier);
17006
+ specifiers.push(specifier);
17007
+ }
17008
+ return specifiers;
17009
+ }
17010
+ function prependImports(css, statements) {
17011
+ if (!statements.length) return css;
17012
+ const importBlock = statements.join("\n");
17013
+ const charsetMatch = css.match(/^(@charset\s+['"][^'"]+';\s*)+/);
17014
+ if (charsetMatch) {
17015
+ const prefix = charsetMatch[0];
17016
+ return `${prefix}${importBlock}\n${css.slice(prefix.length)}`;
17017
+ }
17018
+ return `${importBlock}\n${css}`;
17019
+ }
17020
+ function injectSharedStyleImports(css, modulePath, fileName, sharedStyles, configService) {
17021
+ const relativeModulePath = configService.relativeAbsoluteSrcRoot(modulePath);
17022
+ if (!relativeModulePath) return css;
17023
+ const normalizedModule = toPosixPath(relativeModulePath);
17024
+ if (normalizedModule.startsWith("..")) return css;
17025
+ const entries = findSharedStylesForModule(normalizedModule, toPosixPath(fileName), sharedStyles);
17026
+ if (!entries?.length) return css;
17027
+ const specifiers = resolveImportSpecifiers(fileName, entries);
17028
+ if (!specifiers.length) return css;
17029
+ const statements = [];
17030
+ const emitted = /* @__PURE__ */ new Set();
17031
+ for (const specifier of specifiers) {
17032
+ const statement = `@import '${specifier}';`;
17033
+ if (emitted.has(statement)) continue;
17034
+ if (css.includes(statement)) continue;
17035
+ emitted.add(statement);
17036
+ statements.push(statement);
17037
+ }
17038
+ if (!statements.length) return css;
17039
+ return prependImports(css, statements);
17040
+ }
17041
+ //#endregion
17042
+ //#region src/plugins/css.ts
17043
+ const LEADING_BLANK_LINES_RE = /^(?:[ \t]*\r?\n)+/;
17044
+ function stripLeadingBlankLines(code) {
17045
+ return code.replace(LEADING_BLANK_LINES_RE, "");
17046
+ }
17047
+ function emitCssAssetIfChanged(ctx, pluginCtx, bundle, fileName, source) {
17048
+ const normalizedFileName = toPosixPath(fileName);
17049
+ const cache = ctx.runtimeState?.css.emittedSource;
17050
+ const existing = bundle[fileName];
17051
+ if (existing?.type === "asset") {
17052
+ if ((existing.source?.toString?.() ?? "") !== source) existing.source = source;
17053
+ cache?.set(normalizedFileName, source);
17054
+ return true;
17055
+ }
17056
+ if (cache?.get(normalizedFileName) === source) return false;
17057
+ pluginCtx.emitFile({
17058
+ type: "asset",
17059
+ fileName,
17060
+ source
17061
+ });
17062
+ cache?.set(normalizedFileName, source);
17063
+ return true;
17064
+ }
17065
+ async function emitStyleSidecarAsset(ctx, pluginCtx, bundle, stylePath) {
17066
+ const { configService } = ctx;
17067
+ const fileName = configService.relativeOutputPath(stylePath);
17068
+ if (!fileName) return false;
17069
+ return emitCssAssetIfChanged(ctx, pluginCtx, bundle, fileName, injectSharedStyleImports(await processCssWithCache(stripLeadingBlankLines(await fs.readFile(stylePath, "utf8")), configService), stylePath, fileName, collectSharedStyleEntries(ctx, configService), configService));
17070
+ }
17071
+ async function handleBundleEntry(ctx, bundle, bundleKey, asset, configService, sharedStyles, emitted) {
17072
+ if (asset.type !== "asset") return;
17073
+ const toAbsolute = (id) => {
17074
+ return toAbsoluteId(id, configService, void 0, { base: "cwd" }) || id;
17075
+ };
17076
+ const normalizeOwnerId = (id) => {
17077
+ return normalizeFsResolvedId(id, { stripLeadingNullByte: true });
17078
+ };
17079
+ const collectCssOwnersFromChunks = () => {
17080
+ const owners = /* @__PURE__ */ new Set();
17081
+ for (const output of Object.values(bundle)) {
17082
+ if (output.type !== "chunk") continue;
17083
+ const importedCss = output.viteMetadata?.importedCss;
17084
+ if (!importedCss || importedCss.size === 0) continue;
17085
+ if (importedCss.has(bundleKey) && output.facadeModuleId) owners.add(output.facadeModuleId);
17086
+ }
17087
+ return owners;
17088
+ };
17089
+ if (bundleKey.endsWith(".wxss")) {
17090
+ const [rawOriginal] = asset.originalFileNames ?? [];
17091
+ const absOriginal = rawOriginal ? toAbsolute(rawOriginal) : path.resolve(configService.absoluteSrcRoot, bundleKey);
17092
+ const fileName = configService.relativeOutputPath(absOriginal);
17093
+ if (fileName) emitted.add(toPosixPath(fileName));
17094
+ if (fileName && fileName !== bundleKey) {
17095
+ delete bundle[bundleKey];
17096
+ const css = await fs.readFile(absOriginal, "utf8");
17097
+ emitCssAssetIfChanged(ctx, this, bundle, fileName, css);
17098
+ }
17099
+ return;
17100
+ }
17101
+ if (!bundleKey.endsWith(".css")) return;
17102
+ const ownersFromChunks = collectCssOwnersFromChunks();
17103
+ const owners = ownersFromChunks.size ? ownersFromChunks : new Set((asset.originalFileNames ?? []).map(normalizeOwnerId).filter((originalFileName) => {
17104
+ return isJsOrTs(originalFileName) || originalFileName.endsWith(".vue");
17105
+ }).map(toAbsolute));
17106
+ if (!owners.size) {
17107
+ delete bundle[bundleKey];
17108
+ return;
17109
+ }
17110
+ await Promise.all(Array.from(owners).map(async (owner) => {
17111
+ const modulePath = owner;
17112
+ const converted = changeFileExtension(modulePath, configService.outputExtensions.wxss);
17113
+ const fileName = configService.relativeOutputPath(converted);
17114
+ if (!fileName) return;
17115
+ const normalizedFileName = toPosixPath(fileName);
17116
+ const cssWithImports = injectSharedStyleImports(await processCssWithCache(stripLeadingBlankLines(asset.source.toString()), configService), modulePath, fileName, sharedStyles, configService);
17117
+ emitCssAssetIfChanged(ctx, this, bundle, fileName, cssWithImports);
17118
+ emitted.add(normalizedFileName);
17119
+ }));
17120
+ delete bundle[bundleKey];
17121
+ }
17122
+ async function emitSharedStyleEntries(ctx, sharedStyles, emitted, configService, bundle, resolvedConfig) {
17123
+ if (!sharedStyles.size) return;
17124
+ for (const entries of sharedStyles.values()) for (const entry of entries) {
17125
+ const fileName = toPosixPath(entry.outputRelativePath);
17126
+ if (emitted.has(fileName)) continue;
17127
+ const absolutePath = entry.absolutePath;
17128
+ if (typeof this.addWatchFile === "function") this.addWatchFile(normalizeWatchPath(absolutePath));
17129
+ if (!await pathExists(absolutePath, { ttlMs: getPathExistsTtlMs(configService) })) continue;
17130
+ const { css: renderedCss, dependencies } = await renderSharedStyleEntry(entry, configService, resolvedConfig);
17131
+ if (typeof this.addWatchFile === "function" && dependencies.length) {
17132
+ for (const dependency of dependencies) if (dependency && dependency !== absolutePath) this.addWatchFile(normalizeWatchPath(dependency));
17133
+ }
17134
+ const css = await processCssWithCache(renderedCss, configService);
17135
+ emitted.add(fileName);
17136
+ if (bundle[fileName]) delete bundle[fileName];
17137
+ emitCssAssetIfChanged(ctx, this, bundle, fileName, css);
17138
+ }
17139
+ }
17140
+ async function emitSharedStyleImportsForChunks(ctx, sharedStyles, emitted, configService, bundle) {
17141
+ if (!sharedStyles.size) return;
17142
+ const { outputExtensions } = configService;
17143
+ await Promise.all(Object.values(bundle).map(async (output) => {
17144
+ if (output.type !== "chunk") return;
17145
+ const moduleId = output.facadeModuleId;
17146
+ if (!moduleId) return;
17147
+ if (!configService.relativeAbsoluteSrcRoot(moduleId)) return;
17148
+ const converted = changeFileExtension(moduleId, outputExtensions.wxss);
17149
+ const fileName = configService.relativeOutputPath(converted);
17150
+ if (!fileName) return;
17151
+ const normalizedFileName = toPosixPath(fileName);
17152
+ if (emitted.has(normalizedFileName)) return;
17153
+ const cssWithImports = injectSharedStyleImports("", moduleId, fileName, sharedStyles, configService);
17154
+ if (!cssWithImports.trim()) return;
17155
+ const processedCss = await processCssWithCache(cssWithImports, configService);
17156
+ emitCssAssetIfChanged(ctx, this, bundle, fileName, processedCss);
17157
+ emitted.add(normalizedFileName);
17158
+ }));
17159
+ }
17160
+ async function generateBundleSharedCss(ctx, configService, bundle, resolvedConfig) {
17161
+ const sharedStyles = collectSharedStyleEntries(ctx, configService);
17162
+ const emitted = /* @__PURE__ */ new Set();
17163
+ const tasks = Object.entries(bundle).map(([bundleKey, asset]) => {
17164
+ return handleBundleEntry.call(this, ctx, bundle, bundleKey, asset, configService, sharedStyles, emitted);
17165
+ });
17166
+ await Promise.all(tasks);
17167
+ await emitSharedStyleEntries.call(this, ctx, sharedStyles, emitted, configService, bundle, resolvedConfig);
17168
+ await emitSharedStyleImportsForChunks.call(this, ctx, sharedStyles, emitted, configService, bundle);
17169
+ }
17170
+ function css(ctx) {
17171
+ const { configService } = ctx;
17172
+ let resolvedConfig;
17173
+ return [{
17174
+ name: "weapp-vite:css",
17175
+ enforce: "pre",
17176
+ configResolved(config) {
17177
+ resolvedConfig = config;
17178
+ },
17179
+ async generateBundle(_opts, bundle) {
17180
+ await generateBundleSharedCss.call(this, ctx, configService, bundle, resolvedConfig);
17181
+ }
17182
+ }];
17183
+ }
17184
+ //#endregion
17185
+ //#region src/runtime/config/internal/injectRequestGlobals.ts
17186
+ const FULL_REQUEST_GLOBAL_TARGETS = [
17187
+ "fetch",
17188
+ "Headers",
17189
+ "Request",
17190
+ "Response",
17191
+ "TextEncoder",
17192
+ "TextDecoder",
17193
+ "AbortController",
17194
+ "AbortSignal",
17195
+ "XMLHttpRequest",
17196
+ "WebSocket",
17197
+ "atob",
17198
+ "btoa",
17199
+ "queueMicrotask",
17200
+ "performance",
17201
+ "crypto",
17202
+ "Event",
17203
+ "CustomEvent"
17204
+ ];
17205
+ const ABORT_REQUEST_GLOBAL_TARGETS = ["AbortController", "AbortSignal"];
17206
+ const REQUEST_RUNTIME_REQUEST_TARGETS = [
17207
+ "fetch",
17208
+ "Headers",
17209
+ "Request",
17210
+ "Response",
17211
+ "TextEncoder",
17212
+ "TextDecoder",
17213
+ "AbortController",
17214
+ "AbortSignal",
17215
+ "XMLHttpRequest"
17216
+ ];
17217
+ const REQUEST_RUNTIME_CORE_USAGE_TARGETS = new Set([
17218
+ "fetch",
17219
+ "Headers",
17220
+ "Request",
17221
+ "Response",
17222
+ "XMLHttpRequest"
17223
+ ]);
17224
+ const DEFAULT_REQUEST_GLOBAL_DEPENDENCIES = [
17225
+ "axios",
17226
+ "graphql-request",
17227
+ "socket.io-client",
17228
+ "engine.io-client"
17229
+ ];
17230
+ const DEFAULT_ABORT_GLOBAL_DEPENDENCIES = ["@tanstack/query-core", "@tanstack/vue-query"];
17231
+ const WEBSOCKET_USAGE_HINT_RE = /\bwebsocket\b/iu;
17232
+ const REQUEST_GLOBAL_FREE_BINDING_TARGETS = new Set([
17233
+ ...FULL_REQUEST_GLOBAL_TARGETS,
17234
+ "URL",
17235
+ "URLSearchParams",
17236
+ "Blob",
17237
+ "FormData"
17238
+ ]);
17239
+ const CODE_USAGE_AUTO_RULES = [
17240
+ {
17241
+ dependencyPatterns: ["axios", "graphql-request"],
17242
+ targets: [...REQUEST_RUNTIME_REQUEST_TARGETS]
17243
+ },
17244
+ {
17245
+ dependencyPatterns: ["socket.io-client", "engine.io-client"],
17246
+ targets: [...FULL_REQUEST_GLOBAL_TARGETS]
17247
+ },
17248
+ {
17249
+ dependencyPatterns: [...DEFAULT_ABORT_GLOBAL_DEPENDENCIES],
17250
+ targets: [...ABORT_REQUEST_GLOBAL_TARGETS]
17251
+ }
17252
+ ];
17253
+ function resolveAppPreludeWebRuntimeConfig(appPrelude, warn) {
17254
+ if (!appPrelude || typeof appPrelude !== "object") return;
17255
+ const webRuntime = appPrelude.webRuntime;
17256
+ const requestRuntime = appPrelude.requestRuntime;
17257
+ if (webRuntime !== void 0) {
17258
+ if (requestRuntime !== void 0) warn?.("`weapp.appPrelude.requestRuntime` 已废弃,且当前会被 `weapp.appPrelude.webRuntime` 覆盖。请迁移到 `weapp.appPrelude.webRuntime`。");
17259
+ if (typeof webRuntime === "boolean") return webRuntime ? {
17260
+ enabled: true,
17261
+ prelude: true
17262
+ } : false;
17263
+ return {
17264
+ ...webRuntime,
17265
+ prelude: true
17266
+ };
17267
+ }
17268
+ if (requestRuntime === void 0) return;
17269
+ warn?.("`weapp.appPrelude.requestRuntime` 已废弃,请迁移到 `weapp.appPrelude.webRuntime`。");
17270
+ if (typeof requestRuntime === "boolean") return requestRuntime ? {
17271
+ enabled: true,
17272
+ prelude: true
17273
+ } : false;
17274
+ return {
17275
+ ...requestRuntime,
17276
+ prelude: true
17277
+ };
17278
+ }
17279
+ function hasMatchedDependency(packageJson, patterns) {
17280
+ return [...new Set([
17281
+ ...Object.keys(packageJson?.dependencies ?? {}),
17282
+ ...Object.keys(packageJson?.devDependencies ?? {}),
17283
+ ...Object.keys(packageJson?.peerDependencies ?? {})
17284
+ ])].some((dependency) => {
17285
+ return patterns.some((pattern) => {
17286
+ if (typeof pattern === "string") return pattern === dependency;
17287
+ pattern.lastIndex = 0;
17288
+ return pattern.test(dependency);
17289
+ });
17290
+ });
17291
+ }
17292
+ function resolveTargets(config) {
16458
17293
  if (config && typeof config === "object" && Array.isArray(config.targets) && config.targets.length > 0) return [...new Set(config.targets)];
16459
17294
  return [...FULL_REQUEST_GLOBAL_TARGETS];
16460
17295
  }
@@ -17854,6 +18689,29 @@ function resolveInjectWeapiGlobalName(state) {
17854
18689
  if (!(typeof injectWeapi === "object" ? injectWeapi.enabled === true : injectWeapi === true) || typeof injectWeapi !== "object" || injectWeapi.replaceWx !== true) return null;
17855
18690
  return injectWeapi.globalName?.trim() || "wpi";
17856
18691
  }
18692
+ function pruneHmrMetadataOnlyChunks(bundle, state) {
18693
+ if (!state.ctx.configService.isDev || !state.hmrState.hasBuiltOnce || !state.hmrState.skipSharedChunkRefresh) return;
18694
+ for (const [fileName, output] of Object.entries(bundle)) if (output?.type === "chunk") delete bundle[fileName];
18695
+ }
18696
+ function hasChunkOutputs(bundle) {
18697
+ return Object.values(bundle).some((output) => output?.type === "chunk");
18698
+ }
18699
+ function isStableHmrSharedChunk(fileName) {
18700
+ return fileName.startsWith("weapp-vendors/") || !fileName.includes("/") && fileName !== "app.js";
18701
+ }
18702
+ function prunePartialHmrStableSharedChunks(bundle, state) {
18703
+ if (!state.ctx.configService.isDev || !state.hmrState.hasBuiltOnce || state.hmrState.didEmitAllEntries || state.hmrState.skipSharedChunkRefresh || !state.hmrState.lastEmittedEntryIds?.size) return;
18704
+ for (const [fileName, output] of Object.entries(bundle)) {
18705
+ if (output?.type !== "chunk" || !isStableHmrSharedChunk(fileName)) continue;
18706
+ const knownImporters = state.hmrSharedChunkImporters.get(fileName);
18707
+ if (!knownImporters?.size) {
18708
+ delete bundle[fileName];
18709
+ continue;
18710
+ }
18711
+ const activeEntryIds = state.hmrState.lastHmrEntryIds?.size ? state.hmrState.lastHmrEntryIds : state.hmrState.lastEmittedEntryIds;
18712
+ if (!Array.from(knownImporters).every((entryId) => activeEntryIds?.has(entryId))) delete bundle[fileName];
18713
+ }
18714
+ }
17857
18715
  function createGenerateBundleHook(state, isPluginBuild) {
17858
18716
  const { ctx, subPackageMeta } = state;
17859
18717
  const { scanService, configService } = ctx;
@@ -17867,6 +18725,7 @@ function createGenerateBundleHook(state, isPluginBuild) {
17867
18725
  return async function generateBundle(_options, bundle) {
17868
18726
  const rolldownBundle = bundle;
17869
18727
  await flushIndependentBuilds.call(this, state);
18728
+ pruneHmrMetadataOnlyChunks(rolldownBundle, state);
17870
18729
  if (isPluginBuild) {
17871
18730
  filterPluginBundleOutputs(rolldownBundle, configService);
17872
18731
  if (!shouldRewriteBundleNpmImports(configService.platform)) {
@@ -17887,8 +18746,9 @@ function createGenerateBundleHook(state, isPluginBuild) {
17887
18746
  let redundantBytesTotal = 0;
17888
18747
  if (configService.isDev && state.hmrSharedChunksMode === "auto") {
17889
18748
  const forceFullSharedChunkRefresh = process.env.WEAPP_VITE_FORCE_FULL_HMR_SHARED_CHUNKS === "1";
17890
- if (state.hmrState.didEmitAllEntries || !state.hmrState.hasBuiltOnce) refreshSharedChunkImporters(rolldownBundle, state);
18749
+ if (state.hmrState.skipSharedChunkRefresh && state.hmrState.hasBuiltOnce && !forceFullSharedChunkRefresh && !hasChunkOutputs(rolldownBundle)) {} else if (state.hmrState.didEmitAllEntries || !state.hmrState.hasBuiltOnce) refreshSharedChunkImporters(rolldownBundle, state);
17891
18750
  else if (forceFullSharedChunkRefresh) refreshSharedChunkImporters(rolldownBundle, state);
18751
+ else if (state.hmrState.lastHmrEntryIds?.size) refreshPartialSharedChunkImporters(rolldownBundle, state, state.hmrState.lastHmrEntryIds);
17892
18752
  else if (state.hmrState.lastEmittedEntryIds?.size) refreshPartialSharedChunkImporters(rolldownBundle, state, state.hmrState.lastEmittedEntryIds);
17893
18753
  state.hmrState.hasBuiltOnce = true;
17894
18754
  }
@@ -18033,7 +18893,9 @@ function createGenerateBundleHook(state, isPluginBuild) {
18033
18893
  targets: injectRequestGlobalsOptions?.targets ?? []
18034
18894
  }, (asset) => this.emitFile(asset));
18035
18895
  if (injectRequestGlobalsOptions?.targets?.length) inlineRequestGlobalsAppRegisteredInstallerChunks(rolldownBundle, installerChunks, preservedRequestGlobalsInstallerChunks);
18896
+ stabilizeWevuRuntimeChunkAccess(rolldownBundle);
18036
18897
  syncChunkImportsFromRequireCalls(rolldownBundle);
18898
+ prunePartialHmrStableSharedChunks(rolldownBundle, state);
18037
18899
  refreshModuleGraph(this, state);
18038
18900
  if (configService.weappViteConfig?.debug?.watchFiles) {
18039
18901
  const watcherService = ctx.watcherService;
@@ -18049,9 +18911,16 @@ function createGenerateBundleHook(state, isPluginBuild) {
18049
18911
  }
18050
18912
  //#endregion
18051
18913
  //#region src/plugins/core/lifecycle/emit.ts
18914
+ function isCurrentStyleSidecarUpdate(state) {
18915
+ return state.ctx.runtimeState.build?.hmr?.profile.dirtyReasonSummary?.some((item) => item.startsWith("style-sidecar:")) === true;
18916
+ }
18052
18917
  function createRenderStartHook(state) {
18053
18918
  const { ctx, subPackageMeta, buildTarget } = state;
18054
- return function renderStart() {
18919
+ return async function renderStart() {
18920
+ if (isCurrentStyleSidecarUpdate(state)) {
18921
+ const currentFile = ctx.runtimeState.build.hmr.profile.file;
18922
+ if (typeof currentFile === "string" && path.extname(currentFile)) await emitStyleSidecarAsset(ctx, this, {}, currentFile);
18923
+ }
18055
18924
  emitJsonAssets.call(this, state);
18056
18925
  state.watchFilesSnapshot = emitWxmlAssetsWithCache({
18057
18926
  runtime: {
@@ -18230,6 +19099,8 @@ function createOptionsHook(state) {
18230
19099
  const { scanService, configService, buildService } = ctx;
18231
19100
  return async function options(options) {
18232
19101
  state.pendingIndependentBuilds = [];
19102
+ state.hmrRootInputIds ??= /* @__PURE__ */ new Set();
19103
+ state.hmrRootInputIds.clear();
18233
19104
  let scannedInput;
18234
19105
  if (subPackageMeta) scannedInput = subPackageMeta.entries.reduce((acc, entry) => {
18235
19106
  acc[entry] = path.resolve(configService.absoluteSrcRoot, entry);
@@ -18292,12 +19163,16 @@ function createOptionsHook(state) {
18292
19163
  }
18293
19164
  }
18294
19165
  options.input = scannedInput;
19166
+ for (const input of Object.values(scannedInput)) {
19167
+ const normalized = normalizeFsResolvedId(input);
19168
+ if (normalized) state.hmrRootInputIds.add(normalized);
19169
+ }
18295
19170
  };
18296
19171
  }
18297
19172
  //#endregion
18298
19173
  //#region src/plugins/core/lifecycle/load/index.ts
18299
19174
  function createLoadHook(state) {
18300
- const { ctx, subPackageMeta, loadEntry, loadedEntrySet } = state;
19175
+ const { ctx, subPackageMeta, loadEntry, loadedEntrySet, resolvedEntryMap } = state;
18301
19176
  const { configService } = ctx;
18302
19177
  const astEngine = resolveAstEngine(configService.weappViteConfig);
18303
19178
  const weapiResolution = {
@@ -18357,6 +19232,7 @@ function createLoadHook(state) {
18357
19232
  };
18358
19233
  if (relativeBasename === resolveRootEntryBasename(state)) {
18359
19234
  const result = await loadEntry.call(this, sourceId, "app");
19235
+ if (configService.isDev && sourceId && !sourceId.startsWith("\0")) resolvedEntryMap.set(sourceId, { id: sourceId });
18360
19236
  const requestGlobalsTargets = result && typeof result === "object" && "code" in result ? resolveRequestGlobalsTargetsForCode(result.code, sourceId, injectRequestGlobalsOptions) : injectRequestGlobalsOptions?.targets ?? [];
18361
19237
  const passiveRequestGlobalsTargets = result && typeof result === "object" && "code" in result ? resolvePassiveRequestGlobalsTargets(result.code, requestGlobalsTargets) : [];
18362
19238
  if (requestGlobalsTargets.length === 0 && passiveRequestGlobalsTargets.length > 0) return injectRequestGlobalsIntoLoadResult(result, sourceId, passiveRequestGlobalsTargets, {
@@ -18501,211 +19377,6 @@ function createTransformHook(state) {
18501
19377
  };
18502
19378
  }
18503
19379
  //#endregion
18504
- //#region src/postcss/constants.ts
18505
- const IFDEF = "#ifdef";
18506
- const IFNDEF = "#ifndef";
18507
- //#endregion
18508
- //#region src/postcss/post.ts
18509
- function normalizeTargets(values) {
18510
- return values.map((value) => value.trim().toLowerCase()).filter(Boolean);
18511
- }
18512
- function parseDirective(text) {
18513
- const normalized = text.replace(/\*/g, "").trim();
18514
- if (!normalized) return;
18515
- const [keyword, ...rest] = normalized.split(/\s+/);
18516
- if (!keyword) return;
18517
- if (keyword === "#ifdef") return {
18518
- type: "ifdef",
18519
- targets: normalizeTargets(rest)
18520
- };
18521
- if (keyword === "#ifndef") return {
18522
- type: "ifndef",
18523
- targets: normalizeTargets(rest)
18524
- };
18525
- if (keyword === "#endif") return {
18526
- type: "endif",
18527
- targets: []
18528
- };
18529
- }
18530
- function removeConditionalBlock(start) {
18531
- let depth = 1;
18532
- let node = start.next();
18533
- while (node && depth > 0) {
18534
- if (node.type === "comment") {
18535
- const directive = parseDirective(node.text);
18536
- if (directive) if (directive.type === "endif") {
18537
- depth -= 1;
18538
- const comment = node;
18539
- node = comment.next();
18540
- comment.remove();
18541
- continue;
18542
- } else {
18543
- depth += 1;
18544
- const comment = node;
18545
- node = comment.next();
18546
- comment.remove();
18547
- continue;
18548
- }
18549
- }
18550
- const next = node.next();
18551
- node.remove();
18552
- node = next;
18553
- }
18554
- }
18555
- const postCreator = (options = { platform: "weapp" }) => {
18556
- const atRulePrefixRegExp = new RegExp(`^wv-`);
18557
- const platform = options.platform.toLowerCase();
18558
- return {
18559
- postcssPlugin: "postcss-weapp-vite-plugin-post",
18560
- prepare() {
18561
- return {
18562
- AtRule(atRule) {
18563
- if (!atRulePrefixRegExp.test(atRule.name)) return;
18564
- if (atRule.name === `wv-keep-import`) {
18565
- atRule.name = "import";
18566
- return;
18567
- }
18568
- if (atRule.name === `wv-if`) if (![...atRule.params.matchAll(/\(([^)]+)\)/g)].some((match) => {
18569
- return match[1].trim() === platform;
18570
- })) atRule.remove();
18571
- else atRule.replaceWith(atRule.nodes);
18572
- },
18573
- Comment(comment) {
18574
- const directive = parseDirective(comment.text);
18575
- if (!directive) {
18576
- comment.remove();
18577
- return;
18578
- }
18579
- if (directive.type === "endif") {
18580
- comment.remove();
18581
- return;
18582
- }
18583
- const hasPlatform = directive.targets.includes(platform);
18584
- if (!(directive.type === "ifdef" ? hasPlatform : !hasPlatform)) {
18585
- removeConditionalBlock(comment);
18586
- comment.remove();
18587
- return;
18588
- }
18589
- comment.remove();
18590
- }
18591
- };
18592
- }
18593
- };
18594
- };
18595
- postCreator.postcss = true;
18596
- //#endregion
18597
- //#region src/postcss/index.ts
18598
- const NEEDS_PROCESS_RE = new RegExp(`@wv-|${IFDEF}|${IFNDEF}`);
18599
- async function cssPostProcess(code, options) {
18600
- if (!NEEDS_PROCESS_RE.test(code)) return code;
18601
- return (await postcss([postCreator(options)]).process(code, { from: void 0 })).css;
18602
- }
18603
- //#endregion
18604
- //#region src/plugins/css/shared/preprocessor.ts
18605
- const cssCodeCache = new LRUCache({ max: 512 });
18606
- const sharedStyleCache = /* @__PURE__ */ new Map();
18607
- const nodeRequire = (() => {
18608
- try {
18609
- return createRequire(import.meta.url);
18610
- } catch {
18611
- return null;
18612
- }
18613
- })();
18614
- async function processCssWithCache(code, configService) {
18615
- const cacheKey = createHash("sha1").update(configService.platform).update("\0").update(code).digest("base64url");
18616
- let processed = cssCodeCache.get(cacheKey);
18617
- if (!processed) {
18618
- processed = await cssPostProcess(code, { platform: configService.platform });
18619
- cssCodeCache.set(cacheKey, processed);
18620
- }
18621
- return processed;
18622
- }
18623
- function dedupeAndNormalizeDependencies(base, dependencies) {
18624
- const seen = /* @__PURE__ */ new Set();
18625
- const baseDir = path.dirname(base);
18626
- for (const dep of dependencies) {
18627
- if (!dep) continue;
18628
- const normalized = path.isAbsolute(dep) ? dep : path.resolve(baseDir, dep);
18629
- seen.add(normalized);
18630
- }
18631
- return Array.from(seen);
18632
- }
18633
- async function renderSharedStyleEntry(entry, _configService, resolvedConfig) {
18634
- const absolutePath = entry.absolutePath;
18635
- const cacheKey = `${absolutePath}:${resolvedConfig ? "resolved" : "raw"}`;
18636
- let stats;
18637
- try {
18638
- stats = await fs.stat(absolutePath);
18639
- } catch (error) {
18640
- const reason = error instanceof Error ? error.message : String(error);
18641
- throw new Error(`[分包] 编译共享样式 \`${entry.source}\` 失败:${reason}`);
18642
- }
18643
- const cached = sharedStyleCache.get(cacheKey);
18644
- if (cached && cached.mtimeMs === stats.mtimeMs && cached.size === stats.size) return {
18645
- css: cached.result.css,
18646
- dependencies: [...cached.result.dependencies]
18647
- };
18648
- try {
18649
- const css = await fs.readFile(absolutePath, "utf8");
18650
- if (!resolvedConfig) {
18651
- const result = {
18652
- css,
18653
- dependencies: []
18654
- };
18655
- sharedStyleCache.set(cacheKey, {
18656
- mtimeMs: stats.mtimeMs,
18657
- size: stats.size,
18658
- result
18659
- });
18660
- return {
18661
- css: result.css,
18662
- dependencies: [...result.dependencies]
18663
- };
18664
- }
18665
- const processed = await preprocessCSS(css, absolutePath, resolvedConfig);
18666
- const dependencies = processed?.deps ? dedupeAndNormalizeDependencies(absolutePath, processed.deps) : [];
18667
- const result = {
18668
- css: processed.code,
18669
- dependencies
18670
- };
18671
- sharedStyleCache.set(cacheKey, {
18672
- mtimeMs: stats.mtimeMs,
18673
- size: stats.size,
18674
- result
18675
- });
18676
- return {
18677
- css: result.css,
18678
- dependencies: [...result.dependencies]
18679
- };
18680
- } catch (error) {
18681
- const reason = error instanceof Error ? error.message : String(error);
18682
- throw new Error(`[分包] 编译共享样式 \`${entry.source}\` 失败:${reason}`);
18683
- }
18684
- }
18685
- function invalidateSharedStyleCache() {
18686
- sharedStyleCache.clear();
18687
- cssCodeCache.clear();
18688
- try {
18689
- const candidates = [
18690
- "tailwindcss/lib/lib/sharedState.js",
18691
- "tailwindcss/dist/sharedState.js",
18692
- "tailwindcss/src/lib/sharedState.js",
18693
- "tailwindcss/sharedState.js"
18694
- ];
18695
- if (!nodeRequire) return;
18696
- for (const request of candidates) try {
18697
- const sharedState = nodeRequire(request);
18698
- if (sharedState) {
18699
- sharedState.contextMap?.clear?.();
18700
- sharedState.configContextMap?.clear?.();
18701
- sharedState.contextSourcesMap?.clear?.();
18702
- sharedState.sourceHashMap?.clear?.();
18703
- break;
18704
- }
18705
- } catch {}
18706
- } catch {}
18707
- }
18708
- //#endregion
18709
19380
  //#region src/plugins/utils/invalidateEntry/cssGraph.ts
18710
19381
  const importProtocols = /^(?:https?:|data:|blob:|\/)/i;
18711
19382
  const cssImportRE = /@(?:import|wv-keep-import)\s+(?:url\()?['"]?([^'")\s]+)['"]?\)?/gi;
@@ -18813,6 +19484,7 @@ function syncVueSfcStyleDependencies(ctx, filename, styleBlocks) {
18813
19484
  if (typeof block.src === "string" && block.src.trim()) addResolvedCssSpecifier(ctx, dependencies, filename, block.src.trim());
18814
19485
  }
18815
19486
  registerCssImports(ctx, filename, dependencies);
19487
+ return dependencies;
18816
19488
  }
18817
19489
  function collectCssImporters(ctx, dependency) {
18818
19490
  const graph = ensureCssGraph(ctx);
@@ -18999,7 +19671,7 @@ function ensureSidecarWatcher(ctx, rootDir) {
18999
19671
  const wasKnown = knownSidecarFiles.has(resolved);
19000
19672
  let derivedEvent;
19001
19673
  if (exists) {
19002
- derivedEvent = wasKnown ? "update" : "create";
19674
+ derivedEvent = wasKnown || isReady ? "update" : "create";
19003
19675
  knownSidecarFiles.add(resolved);
19004
19676
  } else if (wasKnown) {
19005
19677
  derivedEvent = "delete";
@@ -19100,7 +19772,16 @@ function isCurrentSubPackageFile(relativeSrc, subPackageMeta) {
19100
19772
  const root = subPackageMeta?.subPackage.root;
19101
19773
  return !root || relativeSrc === root || relativeSrc.startsWith(`${root}/`);
19102
19774
  }
19103
- async function normalizeWatchEvent(id, event) {
19775
+ async function normalizeWatchEvent(id, event, options) {
19776
+ if (event === "create" && (options.loadedEntrySet.has(id) || options.resolvedEntryMap.has(id)) && await fs.pathExists(id)) return "update";
19777
+ if (event === "create" && await fs.pathExists(id)) {
19778
+ const ext = path.extname(id);
19779
+ if (ext) {
19780
+ const primaryScript = await findJsEntry(id.slice(0, -ext.length));
19781
+ const primaryScriptId = primaryScript.path ? normalizeFsResolvedId(primaryScript.path) : "";
19782
+ if (primaryScriptId && options.resolvedEntryMap.has(primaryScriptId)) return "update";
19783
+ }
19784
+ }
19104
19785
  if (event !== "delete") return event;
19105
19786
  for (const delayMs of ATOMIC_SAVE_RECHECK_DELAYS_MS) {
19106
19787
  if (await fs.pathExists(id)) return "update";
@@ -19133,6 +19814,27 @@ async function isVueEntryJsonOnlyUpdate(state, normalizedId) {
19133
19814
  return false;
19134
19815
  }
19135
19816
  }
19817
+ async function isVueEntryLocalAssetOnlyUpdate(state, normalizedId) {
19818
+ if (!normalizedId.endsWith(".vue")) return false;
19819
+ const previous = state.ctx.runtimeState.build.hmr.vueEntryScriptSignatures.get(normalizedId);
19820
+ if (!previous) return false;
19821
+ try {
19822
+ return resolveVueSfcScriptSignature(await fs.readFile(normalizedId, "utf-8"), normalizedId) === previous;
19823
+ } catch {
19824
+ return false;
19825
+ }
19826
+ }
19827
+ async function isAppShellTopologyUpdate(state, normalizedId) {
19828
+ if (!isAppVueFile(normalizedId)) return false;
19829
+ const previous = state.ctx.runtimeState.build.hmr.vueEntryHasTemplate.get(normalizedId);
19830
+ if (previous === void 0) return false;
19831
+ try {
19832
+ const current = resolveVueSfcHasTemplate(await fs.readFile(normalizedId, "utf-8"), normalizedId);
19833
+ return current !== void 0 && current !== previous;
19834
+ } catch {
19835
+ return false;
19836
+ }
19837
+ }
19136
19838
  async function processChangedFile(state, id, event) {
19137
19839
  const { ctx, subPackageMeta, loadEntry, loadedEntrySet, resolvedEntryMap } = state;
19138
19840
  const { scanService, configService, buildService } = ctx;
@@ -19144,6 +19846,11 @@ async function processChangedFile(state, id, event) {
19144
19846
  const dirtyReasonStats = /* @__PURE__ */ new Map();
19145
19847
  const markEntryDirtyWithCause = (entryId, reason, cause) => {
19146
19848
  state.markEntryDirty(entryId, reason);
19849
+ if (entryId.endsWith(".vue")) {
19850
+ const hmr = ctx.runtimeState.build.hmr;
19851
+ hmr.dirtyVueEntryIds ??= /* @__PURE__ */ new Set();
19852
+ hmr.dirtyVueEntryIds.add(entryId);
19853
+ }
19147
19854
  dirtyReasonStats.set(cause, (dirtyReasonStats.get(cause) ?? 0) + 1);
19148
19855
  };
19149
19856
  const declaredEntryType = state.entriesMap.get(removeExtensionDeep(relativeSrc))?.type;
@@ -19151,6 +19858,9 @@ async function processChangedFile(state, id, event) {
19151
19858
  const isAutoRouteFile = Boolean(ctx.autoRoutesService?.isRouteFile(normalizedId));
19152
19859
  const isTemplateSidecar = Boolean(path.extname(normalizedId) && watchedTemplateExts.has(path.extname(normalizedId)));
19153
19860
  const isScriptModuleSidecar = Array.from(watchedScriptModuleExts).some((suffix) => normalizedId.endsWith(suffix));
19861
+ const concreteChangedEntryId = isAppVueFile(normalizedId) && scanService.appEntry?.path ? normalizeFsResolvedId(scanService.appEntry.path) : normalizedId;
19862
+ let isAppShellTopologyChanged = false;
19863
+ let handledSidecarMetadataUpdate = false;
19154
19864
  const addWxmlImporterEntries = async (startId) => {
19155
19865
  const wxmlService = ctx.wxmlService;
19156
19866
  if (!wxmlService || typeof wxmlService.getImporters !== "function") return;
@@ -19169,9 +19879,11 @@ async function processChangedFile(state, id, event) {
19169
19879
  const primaryScript = await findJsEntry(normalizedImporter.slice(0, -ext.length));
19170
19880
  if (!primaryScript.path) continue;
19171
19881
  const primaryScriptId = normalizeFsResolvedId(primaryScript.path);
19172
- const reason = isLayoutSourcePath(configService.relativeAbsoluteSrcRoot(primaryScriptId)) ? "dependency" : "direct";
19173
- if (reason === "dependency") affectedLayoutEntryIds.add(primaryScriptId);
19174
- else markEntryDirtyWithCause(primaryScriptId, reason, "wxml-importer");
19882
+ if ((isLayoutSourcePath(configService.relativeAbsoluteSrcRoot(primaryScriptId)) ? "dependency" : "direct") === "dependency") affectedLayoutEntryIds.add(primaryScriptId);
19883
+ else {
19884
+ markEntryDirtyWithCause(primaryScriptId, "metadata", "wxml-importer");
19885
+ handledSidecarMetadataUpdate = true;
19886
+ }
19175
19887
  }
19176
19888
  }
19177
19889
  };
@@ -19179,7 +19891,16 @@ async function processChangedFile(state, id, event) {
19179
19891
  const normalizedScriptId = normalizeFsResolvedId(scriptId);
19180
19892
  const reason = isLayoutSourcePath(configService.relativeAbsoluteSrcRoot(normalizedScriptId)) ? "dependency" : "direct";
19181
19893
  if (reason === "dependency") affectedLayoutEntryIds.add(normalizedScriptId);
19182
- else markEntryDirtyWithCause(normalizedScriptId, reason, cause);
19894
+ else markEntryDirtyWithCause(normalizedScriptId, cause === "sidecar-direct" || cause === "json-sidecar" || cause === "style-sidecar" ? "metadata" : reason, cause);
19895
+ };
19896
+ const markChangedEntryDirty = (reason, cause) => {
19897
+ if (isAppVueFile(normalizedId)) {
19898
+ if (concreteChangedEntryId !== normalizedId) {
19899
+ markEntryDirtyWithCause(concreteChangedEntryId, reason, cause);
19900
+ return;
19901
+ }
19902
+ }
19903
+ markEntryDirtyWithCause(normalizedId, reason, cause);
19183
19904
  };
19184
19905
  const addCssImporterEntries = async (startId) => {
19185
19906
  const { importers, scripts } = await collectAffectedScriptsAndImporters(ctx, startId);
@@ -19189,22 +19910,35 @@ async function processChangedFile(state, id, event) {
19189
19910
  }
19190
19911
  for (const script of scripts) markScriptDirty(script, "css-importer");
19191
19912
  };
19192
- if (isDeletedMissingSelf) ctx.runtimeState.build.hmr.vueEntryNonJsonSignatures.delete(normalizedId);
19913
+ if (isDeletedMissingSelf) {
19914
+ ctx.runtimeState.build.hmr.vueEntryHasTemplate.delete(normalizedId);
19915
+ ctx.runtimeState.build.hmr.vueEntryNonJsonSignatures.delete(normalizedId);
19916
+ ctx.runtimeState.build.hmr.vueEntryScriptSignatures.delete(normalizedId);
19917
+ }
19193
19918
  if ((event === "create" || isDeletedMissingSelf) && isAutoRouteFile) {
19194
- if (await ctx.autoRoutesService?.handleFileChange(normalizedId, event)) dirtyReasonStats.set("auto-routes-topology", 1);
19919
+ if (await ctx.autoRoutesService?.handleFileChange(normalizedId, event)) {
19920
+ dirtyReasonStats.set("auto-routes-topology", 1);
19921
+ const appEntryId = scanService.appEntry?.path ? normalizeFsResolvedId(scanService.appEntry.path) : void 0;
19922
+ if (appEntryId && resolvedEntryMap.has(appEntryId)) state.markEntryDirty(appEntryId, "direct");
19923
+ }
19195
19924
  }
19196
19925
  if (event === "update" && isAppVueFile(normalizedId) && resolvedEntryMap.size) {
19197
- loadEntry?.invalidateResolveCache?.();
19198
- for (const entryId of resolvedEntryMap.keys()) {
19199
- if (entryId === normalizedId) continue;
19200
- markEntryDirtyWithCause(entryId, "dependency", "app-shell-dependent");
19926
+ const isJsonOnlyVueEntryUpdate = await isVueEntryJsonOnlyUpdate(state, normalizedId);
19927
+ isAppShellTopologyChanged = !isJsonOnlyVueEntryUpdate && await isAppShellTopologyUpdate(state, normalizedId);
19928
+ const isLocalAssetOnlyVueEntryUpdate = !isJsonOnlyVueEntryUpdate && !isAppShellTopologyChanged && await isVueEntryLocalAssetOnlyUpdate(state, normalizedId);
19929
+ if (!isJsonOnlyVueEntryUpdate && !isLocalAssetOnlyVueEntryUpdate) {
19930
+ loadEntry?.invalidateResolveCache?.();
19931
+ for (const entryId of resolvedEntryMap.keys()) {
19932
+ if (entryId === normalizedId || entryId === concreteChangedEntryId) continue;
19933
+ markEntryDirtyWithCause(entryId, "dependency", "app-shell-dependent");
19934
+ }
19201
19935
  }
19202
19936
  }
19203
19937
  invalidateFileCache(normalizedId);
19204
- if (event === "update") {
19938
+ const isStyleFile = styleSuffixes.some((suffix) => normalizedId.endsWith(suffix));
19939
+ if (event === "update" || event === "create" && isStyleFile && await fs.pathExists(normalizedId)) {
19205
19940
  const isTemplateFile = isTemplate(normalizedId);
19206
19941
  const configSuffix = configSuffixes.find((suffix) => normalizedId.endsWith(suffix));
19207
- const isStyleFile = styleSuffixes.some((suffix) => normalizedId.endsWith(suffix));
19208
19942
  if (isTemplateFile) {
19209
19943
  const wxmlService = ctx.wxmlService;
19210
19944
  if (wxmlService) await wxmlService.scan(normalizedId);
@@ -19216,8 +19950,13 @@ async function processChangedFile(state, id, event) {
19216
19950
  const ext = path.extname(normalizedId);
19217
19951
  return ext ? normalizedId.slice(0, -ext.length) : normalizedId;
19218
19952
  })());
19219
- if (primaryScript.path) markScriptDirty(primaryScript.path, "sidecar-direct");
19220
- else if (isStyleFile) await addCssImporterEntries(normalizedId);
19953
+ if (primaryScript.path) {
19954
+ markScriptDirty(primaryScript.path, configSuffix ? "json-sidecar" : isStyleFile ? "style-sidecar" : "sidecar-direct");
19955
+ handledSidecarMetadataUpdate = true;
19956
+ } else if (isStyleFile) {
19957
+ await addCssImporterEntries(normalizedId);
19958
+ handledSidecarMetadataUpdate = true;
19959
+ }
19221
19960
  }
19222
19961
  }
19223
19962
  if (event === "update" && isLayoutSourcePath(relativeSrc) && (loadedEntrySet.has(normalizedId) || resolvedEntryMap.has(normalizedId))) affectedLayoutEntryIds.add(normalizedId);
@@ -19240,9 +19979,10 @@ async function processChangedFile(state, id, event) {
19240
19979
  for (const entryId of resolvedEntryMap.keys()) markEntryDirtyWithCause(entryId, "dependency", "layout-fallback-full");
19241
19980
  return [...dirtyReasonStats.entries()].map(([cause, count]) => `${cause}:${count}`);
19242
19981
  }
19243
- if (!isDeletedMissingSelf && isCurrentSubPackageFile(relativeSrc, subPackageMeta) && (loadedEntrySet.has(normalizedId) || declaredEntryType === "page" || declaredEntryType === "component")) {
19982
+ if (!isDeletedMissingSelf && isCurrentSubPackageFile(relativeSrc, subPackageMeta) && !handledSidecarMetadataUpdate && (loadedEntrySet.has(normalizedId) || loadedEntrySet.has(concreteChangedEntryId) || resolvedEntryMap.has(normalizedId) || resolvedEntryMap.has(concreteChangedEntryId) || declaredEntryType === "page" || declaredEntryType === "component")) {
19244
19983
  const isJsonOnlyVueEntryUpdate = event === "update" && await isVueEntryJsonOnlyUpdate(state, normalizedId);
19245
- markEntryDirtyWithCause(normalizedId, isJsonOnlyVueEntryUpdate ? "metadata" : "direct", isJsonOnlyVueEntryUpdate ? "entry-json-only" : "entry-direct");
19984
+ const isLocalAssetOnlyVueEntryUpdate = !isJsonOnlyVueEntryUpdate && !isAppShellTopologyChanged && event === "update" && await isVueEntryLocalAssetOnlyUpdate(state, normalizedId);
19985
+ markChangedEntryDirty(isJsonOnlyVueEntryUpdate || isLocalAssetOnlyVueEntryUpdate ? "metadata" : "direct", isJsonOnlyVueEntryUpdate ? "entry-json-only" : isAppShellTopologyChanged ? "entry-direct" : isLocalAssetOnlyVueEntryUpdate ? "entry-local-asset" : "entry-direct");
19246
19986
  } else if (state.layoutEntryDependents.size && state.layoutEntryDependents.get(normalizedId)?.size) {
19247
19987
  const affectedEntries = state.layoutEntryDependents.get(normalizedId);
19248
19988
  for (const entryId of affectedEntries) markEntryDirtyWithCause(entryId, "dependency", "layout-dependent");
@@ -19253,7 +19993,7 @@ async function processChangedFile(state, id, event) {
19253
19993
  markEntryDirtyWithCause(entryId, "dependency", "importer-graph");
19254
19994
  }
19255
19995
  }
19256
- const sharedChunkAffected = !dirtyReasonStats.has("sidecar-direct") && !dirtyReasonStats.has("css-importer") ? collectAffectedEntriesFromSharedChunks(state, normalizedId) : /* @__PURE__ */ new Set();
19996
+ const sharedChunkAffected = !dirtyReasonStats.has("sidecar-direct") && !dirtyReasonStats.has("json-sidecar") && !dirtyReasonStats.has("style-sidecar") && !dirtyReasonStats.has("css-importer") ? collectAffectedEntriesFromSharedChunks(state, normalizedId) : /* @__PURE__ */ new Set();
19257
19997
  if (sharedChunkAffected.size) for (const entryId of sharedChunkAffected) {
19258
19998
  if (importerGraphAffectedEntryIds.has(entryId)) continue;
19259
19999
  markEntryDirtyWithCause(entryId, "dependency", "shared-chunk-source");
@@ -19299,7 +20039,10 @@ function createWatchChangeHook(state) {
19299
20039
  const normalizedId = normalizeFsResolvedId(id);
19300
20040
  if (isSkippableResolvedId(normalizedId)) return;
19301
20041
  if (isOutputFileChange(state, normalizedId)) return;
19302
- const event = await normalizeWatchEvent(normalizedId, change.event);
20042
+ const event = await normalizeWatchEvent(normalizedId, change.event, {
20043
+ loadedEntrySet: state.loadedEntrySet,
20044
+ resolvedEntryMap: state.resolvedEntryMap
20045
+ });
19303
20046
  const dirtyReasonSummary = await processChangedFile(state, normalizedId, event);
19304
20047
  state.ctx.runtimeState.build.hmr.profile = {
19305
20048
  ...state.ctx.runtimeState.build.hmr.profile,
@@ -19350,357 +20093,118 @@ function createRequireAnalysisPlugin(state) {
19350
20093
  meta: { requireTokens }
19351
20094
  };
19352
20095
  } catch (error) {
19353
- logger_default.error(error);
19354
- }
19355
- }
19356
- },
19357
- async moduleParsed(moduleInfo) {
19358
- const requireTokens = moduleInfo.meta.requireTokens;
19359
- if (!Array.isArray(requireTokens)) return;
19360
- for (const requireModule of requireTokens) {
19361
- const absPath = path.resolve(path.dirname(moduleInfo.id), requireModule.value);
19362
- const resolved = await this.resolve(absPath, moduleInfo.id);
19363
- if (!resolved) continue;
19364
- await this.load(resolved);
19365
- if (requireAsyncEmittedChunks.has(resolved.id)) continue;
19366
- requireAsyncEmittedChunks.add(resolved.id);
19367
- this.emitFile({
19368
- type: "chunk",
19369
- id: resolved.id,
19370
- fileName: resolveRelativeOutputFileNameWithExtension(configService, resolved.id, ".js"),
19371
- preserveSignature: "exports-only"
19372
- });
19373
- }
19374
- }
19375
- };
19376
- }
19377
- //#endregion
19378
- //#region src/plugins/core/wxss.ts
19379
- function createWxssResolverPlugin(_state) {
19380
- return {
19381
- name: "weapp-vite:pre:wxss",
19382
- enforce: "pre",
19383
- resolveId: {
19384
- filter: { id: /\.wxss$/ },
19385
- handler(id) {
19386
- return id.replace(/\.wxss$/, ".css?wxss");
19387
- }
19388
- }
19389
- };
19390
- }
19391
- //#endregion
19392
- //#region src/plugins/core/index.ts
19393
- function weappVite(ctx, subPackageMeta) {
19394
- const buildTarget = ctx.currentBuildTarget ?? "app";
19395
- const hmrSharedChunksMode = ctx.configService?.weappViteConfig?.hmr?.sharedChunks ?? "auto";
19396
- const hmrSharedChunkImporters = /* @__PURE__ */ new Map();
19397
- const hmrSharedChunksByEntry = /* @__PURE__ */ new Map();
19398
- const hmrSharedChunkDependencies = /* @__PURE__ */ new Map();
19399
- const hmrSharedChunksByModule = /* @__PURE__ */ new Map();
19400
- const hmrSourceSharedChunks = /* @__PURE__ */ new Set();
19401
- const hmrState = {
19402
- didEmitAllEntries: false,
19403
- hasBuiltOnce: false,
19404
- lastEmittedEntryIds: /* @__PURE__ */ new Set()
19405
- };
19406
- const { loadEntry, loadedEntrySet, jsonEmitFilesMap, entriesMap, resolvedEntryMap, layoutEntryDependents, markEntryDirty, emitDirtyEntries } = useLoadEntry(ctx, {
19407
- buildTarget,
19408
- hmr: {
19409
- sharedChunks: hmrSharedChunksMode,
19410
- sharedChunkImporters: hmrSharedChunkImporters,
19411
- sharedChunksByEntry: hmrSharedChunksByEntry,
19412
- sourceSharedChunks: hmrSourceSharedChunks,
19413
- setDidEmitAllEntries: (value) => {
19414
- hmrState.didEmitAllEntries = value;
19415
- if (ctx.runtimeState?.build?.hmr) ctx.runtimeState.build.hmr.didEmitAllEntries = value;
19416
- },
19417
- setLastEmittedEntries: (entryIds) => {
19418
- hmrState.lastEmittedEntryIds = new Set(entryIds);
19419
- if (ctx.runtimeState?.build?.hmr) ctx.runtimeState.build.hmr.lastEmittedEntryIds = new Set(entryIds);
19420
- }
19421
- }
19422
- });
19423
- const state = {
19424
- ctx,
19425
- subPackageMeta,
19426
- loadEntry,
19427
- loadedEntrySet,
19428
- markEntryDirty,
19429
- emitDirtyEntries,
19430
- entriesMap,
19431
- jsonEmitFilesMap,
19432
- resolvedEntryMap,
19433
- layoutEntryDependents,
19434
- requireAsyncEmittedChunks: /* @__PURE__ */ new Set(),
19435
- pendingIndependentBuilds: [],
19436
- watchFilesSnapshot: [],
19437
- buildTarget,
19438
- moduleImporters: /* @__PURE__ */ new Map(),
19439
- entryModuleIds: /* @__PURE__ */ new Set(),
19440
- hmrState,
19441
- hmrSharedChunksMode,
19442
- hmrSharedChunkImporters,
19443
- hmrSharedChunksByEntry,
19444
- hmrSharedChunkDependencies,
19445
- hmrSharedChunksByModule,
19446
- hmrSourceSharedChunks
19447
- };
19448
- return [
19449
- createWxssResolverPlugin(state),
19450
- createCoreLifecyclePlugin(state),
19451
- createRequireAnalysisPlugin(state)
19452
- ];
19453
- }
19454
- //#endregion
19455
- //#region src/plugins/css/shared/sharedStyles.ts
19456
- const styleMatcherCache = /* @__PURE__ */ new WeakMap();
19457
- function collectSharedStyleEntries(ctx, configService) {
19458
- const map = /* @__PURE__ */ new Map();
19459
- const registry = ctx.scanService?.subPackageMap;
19460
- if (!registry?.size) return map;
19461
- const currentRoot = configService.currentSubPackageRoot;
19462
- for (const [root, meta] of registry.entries()) {
19463
- if (!meta.styleEntries?.length) continue;
19464
- if (currentRoot && root !== currentRoot) continue;
19465
- map.set(root, meta.styleEntries);
19466
- }
19467
- return map;
19468
- }
19469
- function sanitizeRelativePath(value) {
19470
- const normalized = toPosixPath(value);
19471
- if (normalized.startsWith("./")) return normalized.slice(2);
19472
- return normalized;
19473
- }
19474
- function isWithinRoot(pathname, root) {
19475
- if (!root) return true;
19476
- return pathname === root || pathname.startsWith(`${root}/`);
19477
- }
19478
- function relativeToRoot(pathname, root) {
19479
- if (!pathname) return pathname;
19480
- if (!root) return pathname;
19481
- if (pathname === root) return "";
19482
- if (pathname.startsWith(`${root}/`)) return pathname.slice(root.length + 1);
19483
- }
19484
- function getStyleMatcher(entry) {
19485
- const cached = styleMatcherCache.get(entry);
19486
- if (cached) return cached;
19487
- const includePatterns = entry.include?.length ? entry.include : ["**/*"];
19488
- const excludePatterns = entry.exclude?.length ? entry.exclude : void 0;
19489
- const matcher = { include: pm(includePatterns, { dot: true }) };
19490
- if (excludePatterns?.length) matcher.exclude = pm(excludePatterns, { dot: true });
19491
- styleMatcherCache.set(entry, matcher);
19492
- return matcher;
19493
- }
19494
- function matchesStyleEntry(entry, relativeModule, relativeFile) {
19495
- const matcher = getStyleMatcher(entry);
19496
- const candidates = [];
19497
- if (typeof relativeFile === "string" && relativeFile.length > 0) candidates.push(relativeFile);
19498
- if (typeof relativeModule === "string" && relativeModule.length > 0) candidates.push(relativeModule);
19499
- if (!candidates.length) return false;
19500
- if (!candidates.some((candidate) => matcher.include(candidate))) return false;
19501
- if (matcher.exclude && candidates.some((candidate) => matcher.exclude(candidate))) return false;
19502
- return true;
19503
- }
19504
- function findSharedStylesForModule(modulePath, fileName, sharedStyles) {
19505
- const sanitizedModule = sanitizeRelativePath(modulePath);
19506
- const sanitizedFile = sanitizeRelativePath(fileName);
19507
- const matched = [];
19508
- for (const [root, entries] of sharedStyles.entries()) {
19509
- const normalizedRoot = normalizeRoot(root);
19510
- if (!normalizedRoot) continue;
19511
- if (!isWithinRoot(sanitizedFile, normalizedRoot)) continue;
19512
- const relativeModule = relativeToRoot(sanitizedModule, normalizedRoot);
19513
- const relativeFile = relativeToRoot(sanitizedFile, normalizedRoot);
19514
- for (const entry of entries) if (matchesStyleEntry(entry, relativeModule, relativeFile)) matched.push(entry);
19515
- }
19516
- return matched;
19517
- }
19518
- function resolveImportSpecifiers(fileName, entries) {
19519
- const posixFileName = toPosixPath(fileName);
19520
- const dir = path.posix.dirname(posixFileName);
19521
- const seen = /* @__PURE__ */ new Set();
19522
- const specifiers = [];
19523
- for (const entry of entries) {
19524
- const target = toPosixPath(entry.outputRelativePath);
19525
- if (target === posixFileName) continue;
19526
- let specifier = path.posix.relative(dir, target) || path.posix.basename(target);
19527
- if (!specifier || specifier === ".") continue;
19528
- if (!specifier.startsWith(".")) specifier = `./${specifier}`;
19529
- specifier = specifier.replace(/\/+/g, "/");
19530
- if (specifier === "./") continue;
19531
- if (seen.has(specifier)) continue;
19532
- seen.add(specifier);
19533
- specifiers.push(specifier);
19534
- }
19535
- return specifiers;
19536
- }
19537
- function prependImports(css, statements) {
19538
- if (!statements.length) return css;
19539
- const importBlock = statements.join("\n");
19540
- const charsetMatch = css.match(/^(@charset\s+['"][^'"]+';\s*)+/);
19541
- if (charsetMatch) {
19542
- const prefix = charsetMatch[0];
19543
- return `${prefix}${importBlock}\n${css.slice(prefix.length)}`;
19544
- }
19545
- return `${importBlock}\n${css}`;
19546
- }
19547
- function injectSharedStyleImports(css, modulePath, fileName, sharedStyles, configService) {
19548
- const relativeModulePath = configService.relativeAbsoluteSrcRoot(modulePath);
19549
- if (!relativeModulePath) return css;
19550
- const normalizedModule = toPosixPath(relativeModulePath);
19551
- if (normalizedModule.startsWith("..")) return css;
19552
- const entries = findSharedStylesForModule(normalizedModule, toPosixPath(fileName), sharedStyles);
19553
- if (!entries?.length) return css;
19554
- const specifiers = resolveImportSpecifiers(fileName, entries);
19555
- if (!specifiers.length) return css;
19556
- const statements = [];
19557
- const emitted = /* @__PURE__ */ new Set();
19558
- for (const specifier of specifiers) {
19559
- const statement = `@import '${specifier}';`;
19560
- if (emitted.has(statement)) continue;
19561
- if (css.includes(statement)) continue;
19562
- emitted.add(statement);
19563
- statements.push(statement);
19564
- }
19565
- if (!statements.length) return css;
19566
- return prependImports(css, statements);
19567
- }
19568
- //#endregion
19569
- //#region src/plugins/css.ts
19570
- const LEADING_BLANK_LINES_RE = /^(?:[ \t]*\r?\n)+/;
19571
- function stripLeadingBlankLines(code) {
19572
- return code.replace(LEADING_BLANK_LINES_RE, "");
19573
- }
19574
- function emitCssAssetIfChanged(ctx, pluginCtx, bundle, fileName, source) {
19575
- const normalizedFileName = toPosixPath(fileName);
19576
- const cache = ctx.runtimeState?.css.emittedSource;
19577
- const existing = bundle[fileName];
19578
- if (existing?.type === "asset") {
19579
- if ((existing.source?.toString?.() ?? "") !== source) existing.source = source;
19580
- cache?.set(normalizedFileName, source);
19581
- return true;
19582
- }
19583
- if (cache?.get(normalizedFileName) === source) return false;
19584
- pluginCtx.emitFile({
19585
- type: "asset",
19586
- fileName,
19587
- source
19588
- });
19589
- cache?.set(normalizedFileName, source);
19590
- return true;
19591
- }
19592
- async function handleBundleEntry(ctx, bundle, bundleKey, asset, configService, sharedStyles, emitted) {
19593
- if (asset.type !== "asset") return;
19594
- const toAbsolute = (id) => {
19595
- return toAbsoluteId(id, configService, void 0, { base: "cwd" }) || id;
19596
- };
19597
- const normalizeOwnerId = (id) => {
19598
- return normalizeFsResolvedId(id, { stripLeadingNullByte: true });
19599
- };
19600
- const collectCssOwnersFromChunks = () => {
19601
- const owners = /* @__PURE__ */ new Set();
19602
- for (const output of Object.values(bundle)) {
19603
- if (output.type !== "chunk") continue;
19604
- const importedCss = output.viteMetadata?.importedCss;
19605
- if (!importedCss || importedCss.size === 0) continue;
19606
- if (importedCss.has(bundleKey) && output.facadeModuleId) owners.add(output.facadeModuleId);
20096
+ logger_default.error(error);
20097
+ }
20098
+ }
20099
+ },
20100
+ async moduleParsed(moduleInfo) {
20101
+ const requireTokens = moduleInfo.meta.requireTokens;
20102
+ if (!Array.isArray(requireTokens)) return;
20103
+ for (const requireModule of requireTokens) {
20104
+ const absPath = path.resolve(path.dirname(moduleInfo.id), requireModule.value);
20105
+ const resolved = await this.resolve(absPath, moduleInfo.id);
20106
+ if (!resolved) continue;
20107
+ await this.load(resolved);
20108
+ if (requireAsyncEmittedChunks.has(resolved.id)) continue;
20109
+ requireAsyncEmittedChunks.add(resolved.id);
20110
+ this.emitFile({
20111
+ type: "chunk",
20112
+ id: resolved.id,
20113
+ fileName: resolveRelativeOutputFileNameWithExtension(configService, resolved.id, ".js"),
20114
+ preserveSignature: "exports-only"
20115
+ });
20116
+ }
19607
20117
  }
19608
- return owners;
19609
20118
  };
19610
- if (bundleKey.endsWith(".wxss")) {
19611
- const [rawOriginal] = asset.originalFileNames ?? [];
19612
- const absOriginal = rawOriginal ? toAbsolute(rawOriginal) : path.resolve(configService.absoluteSrcRoot, bundleKey);
19613
- const fileName = configService.relativeOutputPath(absOriginal);
19614
- if (fileName) emitted.add(toPosixPath(fileName));
19615
- if (fileName && fileName !== bundleKey) {
19616
- delete bundle[bundleKey];
19617
- const css = await fs.readFile(absOriginal, "utf8");
19618
- emitCssAssetIfChanged(ctx, this, bundle, fileName, css);
19619
- }
19620
- return;
19621
- }
19622
- if (!bundleKey.endsWith(".css")) return;
19623
- const ownersFromChunks = collectCssOwnersFromChunks();
19624
- const owners = ownersFromChunks.size ? ownersFromChunks : new Set((asset.originalFileNames ?? []).map(normalizeOwnerId).filter((originalFileName) => {
19625
- return isJsOrTs(originalFileName) || originalFileName.endsWith(".vue");
19626
- }).map(toAbsolute));
19627
- if (!owners.size) {
19628
- delete bundle[bundleKey];
19629
- return;
19630
- }
19631
- await Promise.all(Array.from(owners).map(async (owner) => {
19632
- const modulePath = owner;
19633
- const converted = changeFileExtension(modulePath, configService.outputExtensions.wxss);
19634
- const fileName = configService.relativeOutputPath(converted);
19635
- if (!fileName) return;
19636
- const normalizedFileName = toPosixPath(fileName);
19637
- const cssWithImports = injectSharedStyleImports(await processCssWithCache(stripLeadingBlankLines(asset.source.toString()), configService), modulePath, fileName, sharedStyles, configService);
19638
- emitCssAssetIfChanged(ctx, this, bundle, fileName, cssWithImports);
19639
- emitted.add(normalizedFileName);
19640
- }));
19641
- delete bundle[bundleKey];
19642
20119
  }
19643
- async function emitSharedStyleEntries(ctx, sharedStyles, emitted, configService, bundle, resolvedConfig) {
19644
- if (!sharedStyles.size) return;
19645
- for (const entries of sharedStyles.values()) for (const entry of entries) {
19646
- const fileName = toPosixPath(entry.outputRelativePath);
19647
- if (emitted.has(fileName)) continue;
19648
- const absolutePath = entry.absolutePath;
19649
- if (typeof this.addWatchFile === "function") this.addWatchFile(normalizeWatchPath(absolutePath));
19650
- if (!await pathExists(absolutePath, { ttlMs: getPathExistsTtlMs(configService) })) continue;
19651
- const { css: renderedCss, dependencies } = await renderSharedStyleEntry(entry, configService, resolvedConfig);
19652
- if (typeof this.addWatchFile === "function" && dependencies.length) {
19653
- for (const dependency of dependencies) if (dependency && dependency !== absolutePath) this.addWatchFile(normalizeWatchPath(dependency));
20120
+ //#endregion
20121
+ //#region src/plugins/core/wxss.ts
20122
+ function createWxssResolverPlugin(_state) {
20123
+ return {
20124
+ name: "weapp-vite:pre:wxss",
20125
+ enforce: "pre",
20126
+ resolveId: {
20127
+ filter: { id: /\.wxss$/ },
20128
+ handler(id) {
20129
+ return id.replace(/\.wxss$/, ".css?wxss");
20130
+ }
19654
20131
  }
19655
- const css = await processCssWithCache(renderedCss, configService);
19656
- emitted.add(fileName);
19657
- if (bundle[fileName]) delete bundle[fileName];
19658
- emitCssAssetIfChanged(ctx, this, bundle, fileName, css);
19659
- }
19660
- }
19661
- async function emitSharedStyleImportsForChunks(ctx, sharedStyles, emitted, configService, bundle) {
19662
- if (!sharedStyles.size) return;
19663
- const { outputExtensions } = configService;
19664
- await Promise.all(Object.values(bundle).map(async (output) => {
19665
- if (output.type !== "chunk") return;
19666
- const moduleId = output.facadeModuleId;
19667
- if (!moduleId) return;
19668
- if (!configService.relativeAbsoluteSrcRoot(moduleId)) return;
19669
- const converted = changeFileExtension(moduleId, outputExtensions.wxss);
19670
- const fileName = configService.relativeOutputPath(converted);
19671
- if (!fileName) return;
19672
- const normalizedFileName = toPosixPath(fileName);
19673
- if (emitted.has(normalizedFileName)) return;
19674
- const cssWithImports = injectSharedStyleImports("", moduleId, fileName, sharedStyles, configService);
19675
- if (!cssWithImports.trim()) return;
19676
- const processedCss = await processCssWithCache(cssWithImports, configService);
19677
- emitCssAssetIfChanged(ctx, this, bundle, fileName, processedCss);
19678
- emitted.add(normalizedFileName);
19679
- }));
19680
- }
19681
- async function generateBundleSharedCss(ctx, configService, bundle, resolvedConfig) {
19682
- const sharedStyles = collectSharedStyleEntries(ctx, configService);
19683
- const emitted = /* @__PURE__ */ new Set();
19684
- const tasks = Object.entries(bundle).map(([bundleKey, asset]) => {
19685
- return handleBundleEntry.call(this, ctx, bundle, bundleKey, asset, configService, sharedStyles, emitted);
19686
- });
19687
- await Promise.all(tasks);
19688
- await emitSharedStyleEntries.call(this, ctx, sharedStyles, emitted, configService, bundle, resolvedConfig);
19689
- await emitSharedStyleImportsForChunks.call(this, ctx, sharedStyles, emitted, configService, bundle);
20132
+ };
19690
20133
  }
19691
- function css(ctx) {
19692
- const { configService } = ctx;
19693
- let resolvedConfig;
19694
- return [{
19695
- name: "weapp-vite:css",
19696
- enforce: "pre",
19697
- configResolved(config) {
19698
- resolvedConfig = config;
19699
- },
19700
- async generateBundle(_opts, bundle) {
19701
- await generateBundleSharedCss.call(this, ctx, configService, bundle, resolvedConfig);
20134
+ //#endregion
20135
+ //#region src/plugins/core/index.ts
20136
+ function weappVite(ctx, subPackageMeta) {
20137
+ const buildTarget = ctx.currentBuildTarget ?? "app";
20138
+ const hmrSharedChunksMode = ctx.configService?.weappViteConfig?.hmr?.sharedChunks ?? "auto";
20139
+ const hmrSharedChunkImporters = /* @__PURE__ */ new Map();
20140
+ const hmrSharedChunksByEntry = /* @__PURE__ */ new Map();
20141
+ const hmrSharedChunkDependencies = /* @__PURE__ */ new Map();
20142
+ const hmrSharedChunksByModule = /* @__PURE__ */ new Map();
20143
+ const hmrSourceSharedChunks = /* @__PURE__ */ new Set();
20144
+ const hmrRootInputIds = /* @__PURE__ */ new Set();
20145
+ const hmrState = {
20146
+ didEmitAllEntries: false,
20147
+ hasBuiltOnce: false,
20148
+ lastHmrEntryIds: /* @__PURE__ */ new Set(),
20149
+ lastEmittedEntryIds: /* @__PURE__ */ new Set(),
20150
+ skipSharedChunkRefresh: false
20151
+ };
20152
+ const { loadEntry, loadedEntrySet, jsonEmitFilesMap, entriesMap, resolvedEntryMap, layoutEntryDependents, markEntryDirty, emitDirtyEntries } = useLoadEntry(ctx, {
20153
+ buildTarget,
20154
+ hmr: {
20155
+ sharedChunks: hmrSharedChunksMode,
20156
+ sharedChunkImporters: hmrSharedChunkImporters,
20157
+ sharedChunksByEntry: hmrSharedChunksByEntry,
20158
+ sourceSharedChunks: hmrSourceSharedChunks,
20159
+ rootInputIds: hmrRootInputIds,
20160
+ setDidEmitAllEntries: (value) => {
20161
+ hmrState.didEmitAllEntries = value;
20162
+ if (ctx.runtimeState?.build?.hmr) ctx.runtimeState.build.hmr.didEmitAllEntries = value;
20163
+ },
20164
+ setLastEmittedEntries: (entryIds) => {
20165
+ hmrState.lastEmittedEntryIds = new Set(entryIds);
20166
+ if (ctx.runtimeState?.build?.hmr) ctx.runtimeState.build.hmr.lastEmittedEntryIds = new Set(entryIds);
20167
+ },
20168
+ setLastHmrEntries: (entryIds) => {
20169
+ hmrState.lastHmrEntryIds = new Set(entryIds);
20170
+ if (ctx.runtimeState?.build?.hmr) ctx.runtimeState.build.hmr.lastHmrEntryIds = new Set(entryIds);
20171
+ },
20172
+ setSkipSharedChunkRefresh: (value) => {
20173
+ hmrState.skipSharedChunkRefresh = value;
20174
+ }
19702
20175
  }
19703
- }];
20176
+ });
20177
+ const state = {
20178
+ ctx,
20179
+ subPackageMeta,
20180
+ loadEntry,
20181
+ loadedEntrySet,
20182
+ markEntryDirty,
20183
+ emitDirtyEntries,
20184
+ entriesMap,
20185
+ jsonEmitFilesMap,
20186
+ resolvedEntryMap,
20187
+ layoutEntryDependents,
20188
+ requireAsyncEmittedChunks: /* @__PURE__ */ new Set(),
20189
+ pendingIndependentBuilds: [],
20190
+ watchFilesSnapshot: [],
20191
+ buildTarget,
20192
+ moduleImporters: /* @__PURE__ */ new Map(),
20193
+ entryModuleIds: /* @__PURE__ */ new Set(),
20194
+ hmrState,
20195
+ hmrSharedChunksMode,
20196
+ hmrSharedChunkImporters,
20197
+ hmrSharedChunksByEntry,
20198
+ hmrSharedChunkDependencies,
20199
+ hmrSharedChunksByModule,
20200
+ hmrSourceSharedChunks,
20201
+ hmrRootInputIds
20202
+ };
20203
+ return [
20204
+ createWxssResolverPlugin(state),
20205
+ createCoreLifecyclePlugin(state),
20206
+ createRequireAnalysisPlugin(state)
20207
+ ];
19704
20208
  }
19705
20209
  //#endregion
19706
20210
  //#region src/plugins/preflight.ts
@@ -19739,6 +20243,11 @@ function preflight(ctx) {
19739
20243
  //#region src/plugins/vue/transform/styleRequest.ts
19740
20244
  const WEAPP_VUE_STYLE_VIRTUAL_PREFIX = "\0weapp-vite:vue-style:";
19741
20245
  const WEAPP_VUE_STYLE_VIRTUAL_PREFIX_PLAIN = "weapp-vite:vue-style:";
20246
+ function appendHmrToken(query, token) {
20247
+ if (typeof token === "number") return Number.isFinite(token) && token > 0 ? `${query}&hmr=${token}` : query;
20248
+ if (typeof token === "string" && token.trim()) return `${query}&hmr=${encodeURIComponent(token)}`;
20249
+ return query;
20250
+ }
19742
20251
  function resolveEncodedStyleRequestFilename(filename) {
19743
20252
  const normalizedFilename = normalizeFsResolvedId(filename);
19744
20253
  return {
@@ -19774,13 +20283,14 @@ function parseWeappVueStyleRequest(id) {
19774
20283
  index
19775
20284
  };
19776
20285
  }
19777
- function buildWeappVueStyleRequests(filename, styleBlocks) {
20286
+ function buildWeappVueStyleRequests(filename, styleBlocks, options = {}) {
19778
20287
  const { encodedFilename } = resolveEncodedStyleRequestFilename(filename);
19779
20288
  return styleBlocks.map((styleBlock, index) => {
19780
20289
  const lang = styleBlock.lang || "css";
19781
20290
  let query = `weapp-vite-vue&type=style&index=${index}`;
19782
20291
  if (styleBlock.scoped) query += "&scoped=true";
19783
20292
  if (styleBlock.module) query += typeof styleBlock.module === "string" ? `&module=${encodeURIComponent(styleBlock.module)}` : "&module=true";
20293
+ query = appendHmrToken(query, options.hmrToken);
19784
20294
  query += `&lang.${lang}`;
19785
20295
  return `${WEAPP_VUE_STYLE_VIRTUAL_PREFIX}${encodedFilename}?${query}`;
19786
20296
  });
@@ -20224,9 +20734,14 @@ function emitFallbackPageBundleAssets(options) {
20224
20734
  }
20225
20735
  function emitCompiledEntryBundleAssets(options) {
20226
20736
  const isAppVue = APP_VUE_LIKE_FILE_RE$1.test(options.filename);
20737
+ const hmrState = options.ctx.runtimeState?.build?.hmr;
20227
20738
  const shouldEmitComponentJson = !isAppVue && !options.isPage;
20228
20739
  const shouldMergeJsonAsset = isAppVue;
20229
20740
  const jsonKind = isAppVue ? "app" : options.isPage ? "page" : "component";
20741
+ const isAssetOnlyHmr = (hmrState?.profile?.dirtyReasonSummary)?.some((item) => item.startsWith("entry-local-asset:") || item.startsWith("style-sidecar:")) === true;
20742
+ const isAppVueHmrUpdate = Boolean(isAppVue && options.configService.isDev && hmrState?.profile?.file === options.filename);
20743
+ const sfcStyle = options.result.style;
20744
+ const shouldEmitSfcStyleAsset = typeof sfcStyle === "string" && sfcStyle.length > 0 && (isAppVue && (!options.configService.isDev || isAppVueHmrUpdate) || options.configService.isDev && isAssetOnlyHmr && hmrState?.lastHmrEntryIds?.has(options.filename));
20230
20745
  const { jsonConfig } = emitBundleVueEntryAssets({
20231
20746
  bundle: options.bundle,
20232
20747
  pluginCtx: options.pluginCtx,
@@ -20240,6 +20755,7 @@ function emitCompiledEntryBundleAssets(options) {
20240
20755
  outputExtensions: options.outputExtensions,
20241
20756
  platformAssetOptions: options.platformAssetOptions
20242
20757
  });
20758
+ if (shouldEmitSfcStyleAsset) emitSfcStyleIfMissing(options.pluginCtx, options.bundle, options.relativeBase, sfcStyle, options.outputExtensions.wxss, isAppVue ? { updateExisting: false } : void 0);
20243
20759
  if (options.result.config || shouldEmitComponentJson) emitSharedVueEntryJsonAsset({
20244
20760
  bundle: options.bundle,
20245
20761
  pluginCtx: options.pluginCtx,
@@ -20336,6 +20852,14 @@ function isAutoSetDataPickEnabledWithPreset(config) {
20336
20852
  if (typeof explicit === "boolean") return explicit;
20337
20853
  return resolveWevuPreset(config) === "performance";
20338
20854
  }
20855
+ /**
20856
+ * 读取 wevu 输出是否压缩。
20857
+ */
20858
+ function isWevuMinifyEnabled(config, isDev = false) {
20859
+ const explicit = config?.wevu?.minify;
20860
+ if (typeof explicit === "boolean") return explicit;
20861
+ return !isDev;
20862
+ }
20339
20863
  //#endregion
20340
20864
  //#region src/plugins/vue/transform/compileOptions.ts
20341
20865
  function getCompileVueFileOptionsCacheKey(vuePath, isPage, isApp) {
@@ -20390,6 +20914,7 @@ function buildCompileVueFileOptions(ctx, pluginCtx, vuePath, isPage, isApp, conf
20390
20914
  if (resolvedWxsExtension && relativeBase) classStyleWxsSrc = resolveClassStyleWxsLocationForBase(ctx, relativeBase, resolvedWxsExtension, configService).src;
20391
20915
  const jsonConfig = configService.weappViteConfig?.json;
20392
20916
  const wevuDefaults = resolveWevuDefaultsWithPreset(configService.weappViteConfig);
20917
+ const wevuMinify = isWevuMinifyEnabled(configService.weappViteConfig, configService.isDev);
20393
20918
  const jsonKind = isApp ? "app" : isPage ? "page" : "component";
20394
20919
  async function resolveAutoImportComponentSourceType(match) {
20395
20920
  if (match.kind === "local") {
@@ -20470,7 +20995,8 @@ function buildCompileVueFileOptions(ctx, pluginCtx, vuePath, isPage, isApp, conf
20470
20995
  mergeStrategy: jsonConfig?.mergeStrategy
20471
20996
  },
20472
20997
  sfcSrc: createSfcResolveSrcOptions(pluginCtx, configService),
20473
- wevuDefaults
20998
+ wevuDefaults,
20999
+ minify: wevuMinify
20474
21000
  };
20475
21001
  }
20476
21002
  function createCompileVueFileOptions(ctx, pluginCtx, vuePath, isPage, isApp, configService, state) {
@@ -20530,7 +21056,8 @@ async function injectWevuPageFeaturesInJsWithViteResolver(ctx, source, id, optio
20530
21056
  const checkMtime = options?.checkMtime ?? true;
20531
21057
  const injected = await injectWevuPageFeaturesInJsWithResolver(source, {
20532
21058
  id,
20533
- resolver: createViteResolverAdapter({ resolve: (source, importer) => ctx.resolve(source, importer) }, { readFile: readFile$1 }, { checkMtime })
21059
+ resolver: createViteResolverAdapter({ resolve: (source, importer) => ctx.resolve(source, importer) }, { readFile: readFile$1 }, { checkMtime }),
21060
+ minify: options?.minify
20534
21061
  });
20535
21062
  return {
20536
21063
  ...injected,
@@ -20814,1066 +21341,1101 @@ function transformTargetWevuOptionsInJs(source, transformOptions) {
20814
21341
  }
20815
21342
  /**
20816
21343
  * 从编译后的 WXML 模板提取渲染相关的顶层 key。
20817
- */
20818
- function collectSetDataPickKeysFromTemplate(template, options) {
20819
- return collectSetDataPickKeysFromTemplateCode(template, options);
20820
- }
20821
- /**
20822
- * 在 wevu 组件脚本中注入 setData.pick。
20823
- */
20824
- function injectSetDataPickInJs(source, pickKeys) {
20825
- if (!pickKeys.length) return {
20826
- code: source,
20827
- transformed: false
20828
- };
20829
- return transformTargetWevuOptionsInJs(source, (optionsObject) => injectPickIntoOptionsObject(optionsObject, pickKeys));
20830
- }
20831
- /**
20832
- * 在含有 scoped slot outlet 的 wevu 组件脚本中注入宿主内部属性。
20833
- */
20834
- function injectScopedSlotHostPropertiesInJs(source) {
20835
- return transformTargetWevuOptionsInJs(source, injectScopedSlotHostPropertiesIntoOptionsObject);
20836
- }
20837
- //#endregion
20838
- //#region src/plugins/vue/transform/bundle/shared/types.ts
20839
- function getVueBundlePageLayoutPlan(result) {
20840
- return result.meta?.pageLayoutPlan;
20841
- }
20842
- function setVueBundlePageLayoutPlan(result, plan) {
20843
- const current = result;
20844
- current.meta = {
20845
- ...current.meta,
20846
- pageLayoutPlan: plan
20847
- };
20848
- }
20849
- //#endregion
20850
- //#region src/plugins/vue/transform/bundle/shared/layout.ts
20851
- const APP_VUE_LIKE_FILE_RE = /[\\/]app\.(?:vue|jsx|tsx)$/;
20852
- function addBundleWatchFile(pluginCtx, filePath) {
20853
- if (typeof pluginCtx.addWatchFile !== "function") return;
20854
- pluginCtx.addWatchFile(normalizeWatchPath(filePath));
20855
- }
20856
- function getEntryBaseName(filename) {
20857
- const extIndex = filename.lastIndexOf(".");
20858
- if (extIndex < 0) return filename;
20859
- return filename.slice(0, extIndex);
20860
- }
20861
- function isAppVueLikeFile(filename) {
20862
- return APP_VUE_LIKE_FILE_RE.test(filename);
20863
- }
20864
- async function resolveFallbackPageEntryFile(options) {
20865
- return await findFirstResolvedVueLikeEntry(options.entryId, { resolve: async (candidate) => {
20866
- if (options.compilationCache.has(candidate)) return null;
20867
- return await options.pathExists(candidate);
20868
- } });
20869
- }
20870
- async function resolveFallbackPageEmitState(options) {
20871
- const relativeBase = options.configService.relativeOutputPath(options.entryId);
20872
- if (!relativeBase) return;
20873
- const entryFilePath = await resolveFallbackPageEntryFile({
20874
- entryId: options.entryId,
20875
- compilationCache: options.compilationCache,
20876
- pathExists: options.pathExists
20877
- });
20878
- if (!entryFilePath) return;
20879
- return {
20880
- relativeBase,
20881
- entryFilePath
20882
- };
21344
+ */
21345
+ function collectSetDataPickKeysFromTemplate(template, options) {
21346
+ return collectSetDataPickKeysFromTemplateCode(template, options);
20883
21347
  }
20884
- async function handleFallbackPageLayouts(options) {
20885
- const resolvedLayoutPlan = await resolvePageLayoutPlan(options.source, options.entryFilePath, options.configService);
20886
- await options.emitLayouts(resolvedLayoutPlan?.layouts);
21348
+ /**
21349
+ * wevu 组件脚本中注入 setData.pick。
21350
+ */
21351
+ function injectSetDataPickInJs(source, pickKeys) {
21352
+ if (!pickKeys.length) return {
21353
+ code: source,
21354
+ transformed: false
21355
+ };
21356
+ return transformTargetWevuOptionsInJs(source, (optionsObject) => injectPickIntoOptionsObject(optionsObject, pickKeys));
20887
21357
  }
20888
- async function handleCompiledEntryPageLayouts(options) {
20889
- const resolvedLayoutPlan = getVueBundlePageLayoutPlan(options.result) ?? await resolvePageLayoutPlan(options.source, options.filename, options.configService);
20890
- if (resolvedLayoutPlan) applyPageLayoutPlan(options.result, options.filename, resolvedLayoutPlan, { platform: options.configService.platform });
20891
- await options.emitLayouts(resolvedLayoutPlan?.layouts);
21358
+ /**
21359
+ * 在含有 scoped slot outlet wevu 组件脚本中注入宿主内部属性。
21360
+ */
21361
+ function injectScopedSlotHostPropertiesInJs(source) {
21362
+ return transformTargetWevuOptionsInJs(source, injectScopedSlotHostPropertiesIntoOptionsObject);
20892
21363
  }
20893
21364
  //#endregion
20894
- //#region src/plugins/vue/transform/bundle/shared/compile.ts
20895
- async function compileVueLikeFile(options) {
20896
- const { source, filename, ctx, pluginCtx, isPage, isApp, configService, compileOptionsState } = options;
20897
- const compileOptions = createCompileVueFileOptions(ctx, pluginCtx, filename, isPage, isApp, configService, compileOptionsState);
20898
- if (filename.endsWith(".vue")) {
20899
- const result = await compileVueFile(source, filename, compileOptions);
20900
- if (isPage && result.template) {
20901
- const resolvedLayoutPlan = await resolvePageLayoutPlan(source, filename, configService);
20902
- if (resolvedLayoutPlan) {
20903
- setVueBundlePageLayoutPlan(result, resolvedLayoutPlan);
20904
- applyPageLayoutPlan(result, filename, resolvedLayoutPlan, { platform: configService.platform });
20905
- await addResolvedPageLayoutWatchFiles(pluginCtx, resolvedLayoutPlan.layouts);
20906
- }
20907
- }
20908
- return result;
20909
- }
20910
- const result = await compileJsxFile(source, filename, compileOptions);
20911
- if (isPage && result.template) {
20912
- const resolvedLayoutPlan = await resolvePageLayoutPlan(source, filename, configService);
20913
- if (resolvedLayoutPlan) {
20914
- setVueBundlePageLayoutPlan(result, resolvedLayoutPlan);
20915
- applyPageLayoutPlan(result, filename, resolvedLayoutPlan, { platform: configService.platform });
20916
- await addResolvedPageLayoutWatchFiles(pluginCtx, resolvedLayoutPlan.layouts);
20917
- }
20918
- }
20919
- return result;
20920
- }
20921
- async function finalizeCompiledVueLikeResult(options) {
20922
- const { result, filename, pluginCtx, configService, isPage, isApp } = options;
20923
- if (isPage && result.script) {
20924
- const injected = await injectWevuPageFeaturesInJsWithViteResolver(pluginCtx, result.script, filename, { checkMtime: configService.isDev });
20925
- if (injected.transformed) result.script = injected.code;
20926
- }
20927
- if (!isApp && result.script && result.template && isAutoSetDataPickEnabled(configService.weappViteConfig) && mayNeedInjectSetDataPickInJs(result.script)) {
20928
- const keys = collectSetDataPickKeysFromTemplate(result.template);
20929
- const injectedPick = injectSetDataPickInJs(result.script, keys);
20930
- if (injectedPick.transformed) result.script = injectedPick.code;
20931
- }
20932
- if (!isPage && !isApp && result.script && result.template?.includes(WEVU_SLOT_OWNER_ID_PROP)) {
20933
- const injectedProps = injectScopedSlotHostPropertiesInJs(result.script);
20934
- if (injectedProps.transformed) result.script = injectedProps.code;
20935
- }
20936
- return result;
21365
+ //#region src/plugins/vue/transform/plugin/shared/autoRoutes.ts
21366
+ const AUTO_ROUTES_DYNAMIC_IMPORT_RE = /import\(\s*['"](?:weapp-vite\/auto-routes|virtual:weapp-vite-auto-routes)['"]\s*\)/g;
21367
+ const AUTO_ROUTES_ID = "weapp-vite/auto-routes";
21368
+ const AUTO_ROUTES_VIRTUAL_ID = "virtual:weapp-vite-auto-routes";
21369
+ const AUTO_ROUTES_NAMED_IMPORT_ALIAS_RE = /\s+as\s+/g;
21370
+ const AUTO_ROUTES_DEFAULT_AND_NAMED_IMPORT_RE = /^([A-Z_$][\w$]*)\s*,\s*(\{[^}]+\})$/i;
21371
+ function mayNeedInlineAutoRoutes(source) {
21372
+ return source.includes(AUTO_ROUTES_ID) || source.includes(AUTO_ROUTES_VIRTUAL_ID);
20937
21373
  }
20938
- async function compileAndFinalizeVueLikeFile(options) {
20939
- return await finalizeCompiledVueLikeResult({
20940
- result: await compileVueLikeFile(options),
20941
- filename: options.filename,
20942
- pluginCtx: options.pluginCtx,
20943
- configService: options.configService,
20944
- isPage: options.isPage,
20945
- isApp: options.isApp
20946
- });
21374
+ function toObjectDestructureClause(namedImportClause) {
21375
+ return namedImportClause.replace(AUTO_ROUTES_NAMED_IMPORT_ALIAS_RE, ": ");
20947
21376
  }
20948
- async function refreshCompiledVueEntryCacheInDev(options) {
20949
- const { filename, cached, ctx, pluginCtx, configService, compileOptionsState } = options;
20950
- if (!configService.isDev) return cached.result;
20951
- try {
20952
- const source = await fs.readFile(filename, "utf-8");
20953
- if (source === cached.source) return cached.result;
20954
- const compiled = await compileAndFinalizeVueLikeFile({
20955
- source,
20956
- filename,
20957
- ctx,
20958
- pluginCtx,
20959
- isPage: cached.isPage,
20960
- isApp: isAppVueLikeFile(filename),
20961
- configService,
20962
- compileOptionsState
20963
- });
20964
- cached.source = source;
20965
- cached.result = compiled;
20966
- return compiled;
20967
- } catch {
20968
- return cached.result;
21377
+ function resolveInlineAutoRoutesImport(line, inlineRoutes, replacementIndex) {
21378
+ const trimmedLine = line.trim();
21379
+ if (!trimmedLine.startsWith("import ") || !trimmedLine.includes(" from ") || !trimmedLine.includes(`'${AUTO_ROUTES_ID}'`) && !trimmedLine.includes(`"${AUTO_ROUTES_ID}"`) && !trimmedLine.includes(`'${AUTO_ROUTES_VIRTUAL_ID}'`) && !trimmedLine.includes(`"${AUTO_ROUTES_VIRTUAL_ID}"`)) return;
21380
+ const clause = trimmedLine.slice(7, trimmedLine.lastIndexOf(" from ")).trim();
21381
+ const inlineLiteral = JSON.stringify(inlineRoutes);
21382
+ if (clause.startsWith("{")) return `const ${toObjectDestructureClause(clause)} = ${inlineLiteral};`;
21383
+ if (clause.startsWith("* as ")) return `const ${clause.slice(5).trim()} = ${inlineLiteral};`;
21384
+ const defaultAndNamedMatch = clause.match(AUTO_ROUTES_DEFAULT_AND_NAMED_IMPORT_RE);
21385
+ if (defaultAndNamedMatch) {
21386
+ const [, defaultName, namedClause] = defaultAndNamedMatch;
21387
+ const localRef = `__weappViteAutoRoutesInline${replacementIndex}`;
21388
+ return `const ${localRef} = ${inlineLiteral};\nconst ${defaultName} = ${localRef};\nconst ${toObjectDestructureClause(namedClause)} = ${localRef};`;
20969
21389
  }
21390
+ return `const ${clause} = ${inlineLiteral};`;
20970
21391
  }
20971
- async function resolveCompiledEntryEmitState(options) {
20972
- const result = await refreshCompiledVueEntryCacheInDev({
20973
- filename: options.filename,
20974
- cached: options.cached,
20975
- ctx: options.ctx,
20976
- pluginCtx: options.pluginCtx,
20977
- configService: options.configService,
20978
- compileOptionsState: options.compileOptionsState
20979
- });
20980
- const baseName = getEntryBaseName(options.filename);
20981
- const relativeBase = options.configService.relativeOutputPath(baseName);
20982
- if (!relativeBase) return;
21392
+ function createTransformStageMeasurer(vueTransformTiming) {
21393
+ const stageTimings = {};
21394
+ const totalStart = vueTransformTiming ? performance$1.now() : 0;
21395
+ const measureStage = async (label, task) => {
21396
+ if (!vueTransformTiming) return await task();
21397
+ const start = performance$1.now();
21398
+ const result = await task();
21399
+ stageTimings[label] = Number((performance$1.now() - start).toFixed(2));
21400
+ return result;
21401
+ };
21402
+ const reportTiming = (id, isPage) => {
21403
+ if (!vueTransformTiming) return;
21404
+ vueTransformTiming({
21405
+ id,
21406
+ isPage,
21407
+ totalMs: Number((performance$1.now() - totalStart).toFixed(2)),
21408
+ stages: stageTimings
21409
+ });
21410
+ };
20983
21411
  return {
20984
- result,
20985
- relativeBase
21412
+ measureStage,
21413
+ reportTiming
20986
21414
  };
20987
21415
  }
20988
- async function loadFallbackPageEntryCompilation(options) {
20989
- const source = await fs.readFile(options.entryFilePath, "utf-8");
20990
- return {
21416
+ async function resolveTransformAutoRoutesSource(options) {
21417
+ const { source, autoRoutesService } = options;
21418
+ if (!mayNeedInlineAutoRoutes(source)) return {
20991
21419
  source,
20992
- result: await compileAndFinalizeVueLikeFile({
20993
- source,
20994
- filename: options.entryFilePath,
20995
- ctx: options.ctx,
20996
- pluginCtx: options.pluginCtx,
20997
- isPage: true,
20998
- isApp: false,
20999
- configService: options.configService,
21000
- compileOptionsState: options.compileOptionsState
21001
- })
21420
+ signature: void 0
21421
+ };
21422
+ AUTO_ROUTES_DYNAMIC_IMPORT_RE.lastIndex = 0;
21423
+ await autoRoutesService?.ensureFresh?.();
21424
+ const routesRef = autoRoutesService?.getReference?.();
21425
+ const inlineRoutes = {
21426
+ pages: routesRef?.pages ?? [],
21427
+ entries: routesRef?.entries ?? [],
21428
+ subPackages: routesRef?.subPackages ?? []
21429
+ };
21430
+ const signature = autoRoutesService?.getSignature?.();
21431
+ let importReplacementIndex = 0;
21432
+ return {
21433
+ source: source.split("\n").map((line) => {
21434
+ const replaced = resolveInlineAutoRoutesImport(line, inlineRoutes, importReplacementIndex);
21435
+ if (replaced) {
21436
+ importReplacementIndex += 1;
21437
+ return replaced;
21438
+ }
21439
+ return line;
21440
+ }).join("\n").replace(AUTO_ROUTES_DYNAMIC_IMPORT_RE, `Promise.resolve(${JSON.stringify(inlineRoutes)})`),
21441
+ signature
21002
21442
  };
21003
21443
  }
21004
21444
  //#endregion
21005
- //#region src/plugins/vue/transform/bundle/layoutAssets.ts
21006
- function resolveVueLayoutAssetOptions(options) {
21007
- return resolveNativeLayoutOutputOptions(options);
21445
+ //#region src/plugins/vue/transform/plugin/shared/state.ts
21446
+ const APP_ENTRY_RE = /[\\/]app\.(?:vue|jsx|tsx)$/;
21447
+ const TEMPLATE_MUSTACHE_HINT = "{{";
21448
+ const TEMPLATE_EVENT_HINT_RE = /\b(?:bind|catch)[A-Za-z:_-]+=/;
21449
+ const PAGE_FEATURE_HOOK_HINTS = [
21450
+ "onPageScroll",
21451
+ "onPullDownRefresh",
21452
+ "onReachBottom",
21453
+ "onRouteDone",
21454
+ "onTabItemTap",
21455
+ "onResize",
21456
+ "onShareAppMessage",
21457
+ "onShareTimeline",
21458
+ "onAddToFavorites",
21459
+ "onSaveExitState"
21460
+ ];
21461
+ const PAGE_SCROLL_HOOK_HINT = "onPageScroll";
21462
+ function resolveScriptlessVueEntryStub(isPage) {
21463
+ return isPage ? "Page({})" : "Component({})";
21008
21464
  }
21009
- async function emitResolvedBundleLayouts(options) {
21010
- for (const layout of options.layouts) {
21011
- if (layout.kind === "native") {
21012
- await options.emitNativeLayout(layout.file);
21013
- continue;
21014
- }
21015
- await options.emitVueLayout(layout.file);
21016
- }
21465
+ function isAppEntry(filename) {
21466
+ return APP_ENTRY_RE.test(filename);
21017
21467
  }
21018
- async function resolveNativeLayoutScriptChunkState(options) {
21019
- const resolvedOptions = resolveVueLayoutAssetOptions({
21020
- configService: options.configService,
21021
- layoutBasePath: options.layoutBasePath,
21022
- outputExtensions: options.outputExtensions
21023
- });
21024
- if (!resolvedOptions) return;
21025
- const assets = await collectNativeLayoutAssets(options.layoutBasePath);
21026
- if (!assets.script) return;
21027
- return {
21028
- fileName: resolveScriptlessComponentFileName(resolvedOptions.relativeBase, resolvedOptions.scriptExtension),
21029
- scriptId: assets.script
21030
- };
21468
+ function isVueLikeId(id) {
21469
+ return isVueLikeFile(id);
21031
21470
  }
21032
- async function emitNativeLayoutScriptChunkIfNeeded(options) {
21033
- const nativeScriptChunkState = await resolveNativeLayoutScriptChunkState(options);
21034
- if (!nativeScriptChunkState) return;
21035
- emitNativeLayoutScriptChunkIfNeeded$1({
21036
- pluginCtx: options.pluginCtx,
21037
- scriptId: nativeScriptChunkState.scriptId,
21038
- fileName: nativeScriptChunkState.fileName
21039
- });
21471
+ function mayNeedTransformSetDataPick(template, options) {
21472
+ if (template.includes(TEMPLATE_MUSTACHE_HINT)) return true;
21473
+ const directivePrefix = getWxmlDirectivePrefix(options?.platform);
21474
+ if (new RegExp(`${escapeStringRegexp(directivePrefix)}:`).test(template)) return true;
21475
+ return TEMPLATE_EVENT_HINT_RE.test(template);
21040
21476
  }
21041
- async function resolveNativeLayoutAssetState(options) {
21042
- const resolvedOptions = resolveVueLayoutAssetOptions({
21043
- configService: options.configService,
21044
- layoutBasePath: options.layoutBasePath,
21045
- outputExtensions: options.outputExtensions
21046
- });
21047
- if (!resolvedOptions) return;
21477
+ function mayNeedTransformPageFeatureInjection(script) {
21478
+ return PAGE_FEATURE_HOOK_HINTS.some((hint) => script.includes(hint));
21479
+ }
21480
+ function mayNeedTransformPageScrollDiagnostics(script) {
21481
+ return script.includes(PAGE_SCROLL_HOOK_HINT);
21482
+ }
21483
+ function resolveTransformFilename(options) {
21484
+ const { id, configService, pluginCtx, getSourceFromVirtualId, addWatchFile } = options;
21485
+ const filename = toAbsoluteId(getSourceFromVirtualId(id), configService, void 0, { base: "cwd" });
21486
+ if (!filename || !path.isAbsolute(filename)) return null;
21487
+ if (typeof pluginCtx.addWatchFile === "function") addWatchFile(pluginCtx, filename);
21488
+ return filename;
21489
+ }
21490
+ async function loadTransformPageEntries(scanService) {
21491
+ if (!scanService) return {
21492
+ pages: [],
21493
+ subPackages: [],
21494
+ pluginPages: []
21495
+ };
21496
+ const appEntry = await scanService.loadAppEntry();
21497
+ const subPackages = scanService.loadSubPackages().map((meta) => ({
21498
+ root: meta.subPackage.root,
21499
+ pages: meta.subPackage.pages
21500
+ }));
21501
+ const pluginPages = scanService.pluginJson ? Object.values(scanService.pluginJson.pages ?? {}).map((page) => String(page)) : [];
21048
21502
  return {
21049
- resolvedOptions,
21050
- assets: await collectNativeLayoutAssets(options.layoutBasePath)
21503
+ pages: appEntry.json?.pages ?? [],
21504
+ subPackages,
21505
+ pluginPages
21051
21506
  };
21052
21507
  }
21053
- async function emitResolvedNativeLayoutStaticAssets(options) {
21054
- const staticAssetEntries = await resolveNativeLayoutStaticAssetEntries({
21055
- assets: options.assets,
21056
- resolvedOptions: options.resolvedOptions,
21057
- readFile: fs.readFile
21058
- });
21059
- for (const asset of staticAssetEntries) {
21060
- if (asset.kind === "template") {
21061
- assertTemplateHasDefaultSlot({
21062
- filename: options.assets.template,
21063
- kind: "page-layout",
21064
- template: asset.source
21065
- });
21066
- emitSfcTemplateIfMissing(options.pluginCtx, options.bundle, options.resolvedOptions.relativeBase, asset.source, options.resolvedOptions.templateExtension);
21067
- continue;
21068
- }
21069
- emitSfcStyleIfMissing(options.pluginCtx, options.bundle, options.resolvedOptions.relativeBase, asset.source, options.resolvedOptions.styleExtension);
21508
+ function invalidatePageLayoutCaches(configService, compilationCache, styleBlocksCache) {
21509
+ if (!configService) return;
21510
+ for (const [cachedId, cached] of compilationCache.entries()) {
21511
+ if (cached.isPage) cached.source = void 0;
21512
+ styleBlocksCache.delete(cachedId);
21070
21513
  }
21071
21514
  }
21072
- async function emitNativeLayoutAssetsIfNeeded(options) {
21073
- const { pluginCtx, bundle } = options;
21074
- const nativeLayoutState = await resolveNativeLayoutAssetState(options);
21075
- if (!nativeLayoutState) return;
21076
- const { resolvedOptions, assets } = nativeLayoutState;
21077
- if (assets.json) {
21078
- const source = await fs.readFile(assets.json, "utf8");
21079
- emitSfcJsonAsset(pluginCtx, bundle, resolvedOptions.relativeBase, { config: source }, {
21080
- emitIfMissingOnly: true,
21081
- extension: resolvedOptions.jsonExtension,
21082
- kind: "component"
21083
- });
21515
+ function invalidateVueFileCaches(file, compilationCache, styleBlocksCache, options) {
21516
+ if (!options.existsSync(file)) compilationCache.delete(file);
21517
+ else {
21518
+ const cached = compilationCache.get(file);
21519
+ if (cached) {
21520
+ cached.source = void 0;
21521
+ cached.refreshToken = (cached.refreshToken ?? 0) + 1;
21522
+ }
21084
21523
  }
21085
- await emitResolvedNativeLayoutStaticAssets({
21086
- pluginCtx,
21087
- bundle,
21088
- assets,
21089
- resolvedOptions
21090
- });
21091
- }
21092
- function emitScriptlessComponentJsFallbackIfMissing(options) {
21093
- const { pluginCtx, bundle, relativeBase, scriptExtension } = options;
21094
- ensureScriptlessComponentAsset(pluginCtx, bundle, relativeBase, scriptExtension);
21524
+ styleBlocksCache.delete(file);
21095
21525
  }
21096
- function resolveVueLayoutScriptFallbackState(options) {
21097
- const resolvedOptions = resolveVueLayoutAssetOptions({
21098
- configService: options.configService,
21099
- layoutBasePath: getEntryBaseName(options.layoutFilePath),
21100
- outputExtensions: options.outputExtensions
21101
- });
21102
- if (!resolvedOptions) return;
21103
- const scriptFileName = resolveScriptlessComponentFileName(resolvedOptions.relativeBase, resolvedOptions.scriptExtension);
21104
- if (options.bundle[scriptFileName]) return;
21105
- return {
21106
- resolvedOptions,
21107
- scriptFileName
21108
- };
21526
+ function handleTransformLayoutInvalidation(file, options) {
21527
+ const { configService, compilationCache, styleBlocksCache, isLayoutFile, invalidateResolvedPageLayoutsCache } = options;
21528
+ if (!configService || !isLayoutFile(file, configService)) return false;
21529
+ invalidateResolvedPageLayoutsCache(configService.absoluteSrcRoot);
21530
+ invalidatePageLayoutCaches(configService, compilationCache, styleBlocksCache);
21531
+ return true;
21109
21532
  }
21110
- async function emitVueLayoutScriptFallbackIfNeeded(options) {
21111
- const { pluginCtx, bundle, layoutFilePath, ctx, configService, compileOptionsState, outputExtensions } = options;
21112
- const fallbackState = resolveVueLayoutScriptFallbackState({
21113
- bundle,
21114
- layoutFilePath,
21115
- configService,
21116
- outputExtensions
21117
- });
21118
- if (!fallbackState) return;
21119
- const { resolvedOptions } = fallbackState;
21120
- const result = await compileVueLikeFile({
21121
- source: await fs.readFile(layoutFilePath, "utf-8"),
21122
- filename: layoutFilePath,
21123
- ctx,
21124
- pluginCtx,
21125
- isPage: false,
21126
- isApp: false,
21127
- configService,
21128
- compileOptionsState
21129
- });
21130
- assertTemplateHasDefaultSlot({
21131
- filename: layoutFilePath,
21132
- kind: "page-layout",
21133
- template: result.template
21134
- });
21135
- if (result.script?.trim()) return;
21136
- emitScriptlessComponentJsFallbackIfMissing({
21137
- pluginCtx,
21138
- bundle,
21139
- relativeBase: resolvedOptions.relativeBase,
21140
- scriptExtension: resolvedOptions.scriptExtension
21141
- });
21533
+ function handleTransformVueFileInvalidation(file, options) {
21534
+ if (!isVueLikeId(file)) return false;
21535
+ invalidateVueFileCaches(file, options.compilationCache, options.styleBlocksCache, { existsSync: options.existsSync });
21536
+ return true;
21142
21537
  }
21143
- function createBundleLayoutEmitters(options) {
21144
- return {
21145
- emitNativeLayout: async (layoutFilePath) => {
21146
- await emitNativeLayoutAssetsIfNeeded({
21147
- pluginCtx: options.pluginCtx,
21148
- bundle: options.bundle,
21149
- layoutBasePath: layoutFilePath,
21150
- configService: options.configService,
21151
- outputExtensions: options.outputExtensions
21152
- });
21153
- },
21154
- emitVueLayout: async (layoutFilePath) => {
21155
- await emitVueLayoutScriptFallbackIfNeeded({
21156
- pluginCtx: options.pluginCtx,
21157
- bundle: options.bundle,
21158
- layoutFilePath,
21159
- ctx: options.ctx,
21160
- configService: options.configService,
21161
- compileOptionsState: options.compileOptionsState,
21162
- outputExtensions: options.outputExtensions
21163
- });
21164
- }
21165
- };
21538
+ async function ensureSfcStyleBlocks(filename, styleBlocksCache, options) {
21539
+ const cached = styleBlocksCache.get(filename);
21540
+ if (cached) return cached;
21541
+ const styles = await options.load(filename);
21542
+ styleBlocksCache.set(filename, styles);
21543
+ return styles;
21166
21544
  }
21167
- async function emitBundlePageLayoutsIfNeeded(options) {
21168
- if (!options.layouts?.length) return;
21169
- const layoutEmitters = createBundleLayoutEmitters(options);
21170
- await emitResolvedBundleLayouts({
21171
- layouts: options.layouts,
21172
- emitNativeLayout: layoutEmitters.emitNativeLayout,
21173
- emitVueLayout: layoutEmitters.emitVueLayout
21174
- });
21545
+ async function loadTransformSource(options) {
21546
+ const { code, filename, isDev, readFileCached } = options;
21547
+ if (typeof code === "string") return code;
21548
+ return isDev ? await readFileCached(filename, {
21549
+ checkMtime: true,
21550
+ encoding: "utf8"
21551
+ }) : await fs.readFile(filename, "utf-8");
21175
21552
  }
21176
- function resolveAppShellComponentConfig(config) {
21177
- const shellConfig = { styleIsolation: "apply-shared" };
21178
- if (!config) return JSON.stringify(shellConfig, null, 2);
21553
+ async function preloadTransformSfcStyleBlocks(options) {
21554
+ const { filename, source, styleBlocksCache, load } = options;
21555
+ if (!filename.endsWith(".vue") || !source.includes("<style")) return;
21179
21556
  try {
21180
- const parsed = JSON.parse(config);
21181
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return JSON.stringify(shellConfig, null, 2);
21182
- for (const key of ["usingComponents", "componentGenerics"]) {
21183
- const value = parsed[key];
21184
- if (value && typeof value === "object" && !Array.isArray(value)) shellConfig[key] = value;
21185
- }
21186
- return Object.keys(shellConfig).length ? JSON.stringify(shellConfig, null, 2) : void 0;
21557
+ return await ensureSfcStyleBlocks(filename, styleBlocksCache, { load: async (target) => await load(target, source) });
21187
21558
  } catch {
21188
21559
  return;
21189
21560
  }
21190
21561
  }
21191
- function emitAppShellAssetsIfNeeded(options) {
21192
- const { relativeBase, result } = options;
21193
- if (!relativeBase || !result.template?.trim()) return;
21194
- assertTemplateHasDefaultSlot({
21195
- filename: options.filename,
21196
- kind: "app-shell",
21197
- template: result.template
21198
- });
21199
- emitBundleVueEntryAssets({
21200
- bundle: options.bundle,
21201
- pluginCtx: options.pluginCtx,
21202
- ctx: options.ctx,
21203
- filename: relativeBase,
21204
- relativeBase,
21205
- result,
21206
- configService: options.configService,
21207
- templateExtension: options.templateExtension,
21208
- scriptModuleExtension: options.scriptModuleExtension,
21209
- outputExtensions: options.outputExtensions,
21210
- platformAssetOptions: options.platformAssetOptions
21211
- });
21212
- emitSharedVueEntryJsonAsset({
21213
- bundle: options.bundle,
21214
- pluginCtx: options.pluginCtx,
21215
- relativeBase,
21216
- config: resolveAppShellComponentConfig(result.config),
21217
- outputExtensions: options.outputExtensions,
21218
- platformAssetOptions: options.platformAssetOptions,
21219
- jsonOptions: {
21220
- defaultConfig: { component: true },
21221
- kind: "component",
21222
- extension: options.jsonExtension
21223
- }
21224
- });
21225
- emitScriptlessComponentJsFallbackIfMissing({
21226
- pluginCtx: options.pluginCtx,
21227
- bundle: options.bundle,
21228
- relativeBase,
21229
- scriptExtension: options.scriptExtension
21230
- });
21231
- }
21232
21562
  //#endregion
21233
- //#region src/plugins/vue/transform/bundle/emitCompiledEntry.ts
21234
- async function emitResolvedCompiledVueEntryAssets(options) {
21235
- const { bundle, state, filename, cached, result, relativeBase, compileOptionsState } = options;
21236
- const { ctx, pluginCtx } = state;
21237
- const { configService } = ctx;
21563
+ //#region src/plugins/vue/transform/plugin/shared/layout.ts
21564
+ async function handleTransformEntryPageLayoutFlow(options) {
21565
+ const configService = options.ctx.configService;
21238
21566
  if (!configService) return;
21239
- if (isAppVueFile(filename) && hasAppShellTemplate(result)) emitAppShellAssetsIfNeeded({
21240
- bundle,
21241
- pluginCtx,
21242
- ctx,
21243
- filename,
21244
- relativeBase: resolveAppShellRelativeBase(configService),
21245
- result,
21246
- configService,
21247
- templateExtension: options.templateExtension,
21248
- jsonExtension: options.jsonExtension,
21249
- scriptExtension: options.scriptExtension,
21250
- scriptModuleExtension: options.scriptModuleExtension,
21251
- outputExtensions: options.outputExtensions,
21252
- platformAssetOptions: options.platformAssetOptions
21253
- });
21254
- if (cached.isPage && cached.source) {
21255
- await handleCompiledEntryPageLayouts({
21256
- source: cached.source,
21257
- filename,
21258
- result,
21567
+ const resolvedLayoutPlan = await resolvePageLayoutPlan(options.source, options.filename, configService);
21568
+ if (!resolvedLayoutPlan) return;
21569
+ if (options.result) applyPageLayoutPlan(options.result, options.filename, resolvedLayoutPlan, { platform: configService.platform });
21570
+ await addResolvedPageLayoutWatchFiles(options.pluginCtx, resolvedLayoutPlan.layouts);
21571
+ for (const layout of resolvedLayoutPlan.layouts) {
21572
+ if (layout.kind !== "native") continue;
21573
+ await emitNativeLayoutScriptChunkIfNeeded({
21574
+ pluginCtx: options.pluginCtx,
21575
+ layoutBasePath: layout.file,
21259
21576
  configService,
21260
- emitLayouts: async (layouts) => {
21261
- await emitBundlePageLayoutsIfNeeded({
21262
- layouts,
21263
- pluginCtx,
21264
- bundle,
21265
- ctx,
21266
- configService,
21267
- compileOptionsState,
21268
- outputExtensions: options.outputExtensions
21269
- });
21270
- }
21577
+ outputExtensions: configService.outputExtensions
21271
21578
  });
21272
- applyAppShell(result, filename, state.appShell);
21273
21579
  }
21274
- if (isLayoutFile(filename, configService)) assertTemplateHasDefaultSlot({
21275
- filename,
21276
- kind: "page-layout",
21277
- template: result.template
21278
- });
21279
- const { shouldEmitComponentJson } = emitCompiledEntryBundleAssets({
21280
- bundle,
21281
- pluginCtx,
21282
- ctx,
21283
- filename,
21284
- relativeBase,
21285
- result,
21286
- isPage: cached.isPage,
21287
- configService,
21288
- templateExtension: options.templateExtension,
21289
- jsonExtension: options.jsonExtension,
21290
- scriptModuleExtension: options.scriptModuleExtension,
21291
- outputExtensions: options.outputExtensions,
21292
- platformAssetOptions: options.platformAssetOptions
21293
- });
21294
- if (shouldEmitComponentJson && !result.script?.trim()) emitScriptlessComponentJsFallbackIfMissing({
21295
- pluginCtx,
21296
- bundle,
21297
- relativeBase,
21298
- scriptExtension: options.scriptExtension
21299
- });
21580
+ return resolvedLayoutPlan;
21300
21581
  }
21301
- async function emitCompiledVueEntryAssets(bundle, state, filename, cached) {
21302
- const { ctx, pluginCtx, reExportResolutionCache, classStyleRuntimeWarned, compileOptionsCache } = state;
21303
- const { configService } = ctx;
21304
- if (!configService) return;
21305
- addBundleWatchFile(pluginCtx, filename);
21306
- const compileOptionsState = {
21307
- reExportResolutionCache,
21308
- classStyleRuntimeWarned,
21309
- compileOptionsCache
21582
+ async function resolveTransformEntryFlags(options) {
21583
+ const { pageMatcher, setPageMatcher, createPageMatcher, configService, scanService, scanDirty, scanDirtySynced, setScanDirtySynced, filename } = options;
21584
+ if (configService.weappLibConfig?.enabled) return {
21585
+ isPage: false,
21586
+ isApp: false,
21587
+ pageMatcher: pageMatcher ?? null
21310
21588
  };
21311
- const { outputExtensions, templateExtension, jsonExtension, scriptExtension, scriptModuleExtension, platformAssetOptions } = resolveVueBundleAssetContext(configService);
21312
- const emitState = await resolveCompiledEntryEmitState({
21313
- filename,
21314
- cached,
21315
- ctx,
21316
- pluginCtx,
21317
- configService,
21318
- compileOptionsState
21589
+ const currentPageMatcher = pageMatcher ?? createPageMatcher({
21590
+ srcRoot: configService.absoluteSrcRoot,
21591
+ loadEntries: async () => await loadTransformPageEntries(scanService),
21592
+ warn: () => {}
21319
21593
  });
21320
- if (!emitState) return;
21321
- await emitResolvedCompiledVueEntryAssets({
21322
- bundle,
21323
- state,
21594
+ setPageMatcher(currentPageMatcher);
21595
+ if (scanDirty && !scanDirtySynced) {
21596
+ currentPageMatcher.markDirty();
21597
+ setScanDirtySynced(true);
21598
+ } else if (!scanDirty && scanDirtySynced) setScanDirtySynced(false);
21599
+ return {
21600
+ isPage: await currentPageMatcher.isPageFile(filename),
21601
+ isApp: isAppEntry(filename),
21602
+ pageMatcher: currentPageMatcher
21603
+ };
21604
+ }
21605
+ async function registerNativeLayoutChunksForEntry(pluginCtx, ctx, filename, source) {
21606
+ await handleTransformEntryPageLayoutFlow({
21607
+ pluginCtx,
21608
+ ctx,
21324
21609
  filename,
21325
- cached,
21326
- result: emitState.result,
21327
- relativeBase: emitState.relativeBase,
21328
- compileOptionsState,
21329
- outputExtensions,
21330
- templateExtension,
21331
- jsonExtension,
21332
- scriptExtension,
21333
- scriptModuleExtension,
21334
- platformAssetOptions
21610
+ source
21335
21611
  });
21336
21612
  }
21337
- //#endregion
21338
- //#region src/plugins/vue/transform/collectVuePages.ts
21339
- async function collectVuePages(root) {
21340
- const results = [];
21341
- try {
21342
- const entries = await fs.readdir(root);
21343
- for (const entry of entries) {
21344
- const full = path.join(root, entry);
21345
- if ((await fs.stat(full)).isDirectory()) {
21346
- const nested = await collectVuePages(full);
21347
- results.push(...nested);
21348
- } else if (isVueLikeFile(full)) results.push(stripVueLikeExtension(full));
21349
- }
21350
- } catch {}
21351
- return results;
21352
- }
21353
- //#endregion
21354
- //#region src/plugins/vue/transform/fallbackEntries.ts
21355
- async function collectFallbackPageEntryIds(configService, scanService) {
21356
- let pageList = [];
21357
- if (scanService?.appEntry?.json?.pages?.length) pageList = scanService.appEntry.json.pages;
21358
- else {
21359
- const appJsonPath = path.join(configService.cwd, "dist", "app.json");
21613
+ async function preloadNativeLayoutEntries(options) {
21614
+ const { pluginCtx, ctx, configService, scanService, collectFallbackPageEntryIds, findFirstResolvedVueLikeEntry, pathExists, readFile } = options;
21615
+ if (!configService || !scanService) return;
21616
+ const entryIds = await collectFallbackPageEntryIds(configService, scanService);
21617
+ for (const entryId of entryIds) {
21618
+ const entryFilePath = await findFirstResolvedVueLikeEntry(entryId, { resolve: async (candidate) => await pathExists(candidate) ? candidate : void 0 });
21619
+ if (!entryFilePath) continue;
21360
21620
  try {
21361
- const appJsonContent = await fs.readFile(appJsonPath, "utf-8");
21362
- pageList = JSON.parse(appJsonContent).pages || [];
21621
+ await registerNativeLayoutChunksForEntry(pluginCtx, ctx, entryFilePath, await readFile(entryFilePath, "utf8"));
21363
21622
  } catch {}
21364
21623
  }
21365
- const collectedEntries = /* @__PURE__ */ new Set();
21366
- pageList.forEach((p) => collectedEntries.add(path.join(configService.absoluteSrcRoot, p)));
21367
- (await collectVuePages(path.join(configService.absoluteSrcRoot, "pages"))).forEach((f) => collectedEntries.add(f.slice(0, -4)));
21368
- return collectedEntries;
21369
21624
  }
21370
- //#endregion
21371
- //#region src/plugins/vue/transform/bundle/emitFallbackPage.ts
21372
- function isFallbackEntryPending(entryId, emittedEntryIds, configService) {
21373
- const normalizedEntryId = removeExtensionDeep(configService.relativeOutputPath(entryId));
21374
- for (const emittedEntryId of emittedEntryIds) {
21375
- const normalizedEmitted = normalizeFsResolvedId(emittedEntryId);
21376
- if (!normalizedEmitted) continue;
21377
- if (removeExtensionDeep(configService.relativeOutputPath(normalizedEmitted)) === normalizedEntryId) return true;
21625
+ async function loadTransformStyleBlock(options) {
21626
+ const { id, pluginCtx, ctx, configService, styleBlocksCache, loadScopedSlotModule, scopedSlotModules, parseWeappVueStyleRequest, readAndParseSfc, createReadAndParseSfcOptions } = options;
21627
+ const scopedSlot = loadScopedSlotModule(id, scopedSlotModules);
21628
+ if (scopedSlot) return scopedSlot;
21629
+ const parsed = parseWeappVueStyleRequest(id);
21630
+ if (!parsed) return null;
21631
+ const { filename, index } = parsed;
21632
+ let styles;
21633
+ try {
21634
+ styles = await ensureSfcStyleBlocks(filename, styleBlocksCache, { load: async (target) => (await readAndParseSfc(target, { ...createReadAndParseSfcOptions(pluginCtx, configService) })).descriptor.styles });
21635
+ } catch {
21636
+ return null;
21378
21637
  }
21379
- return false;
21638
+ const block = styles[index];
21639
+ if (!block) return null;
21640
+ const dependencies = syncVueSfcStyleDependencies(ctx, filename, styles);
21641
+ addNormalizedWatchFiles(options.pluginCtx, dependencies);
21642
+ return {
21643
+ code: block.content,
21644
+ map: null
21645
+ };
21380
21646
  }
21381
- async function emitResolvedFallbackPageEntryAssets(options) {
21382
- const { source, result } = await loadFallbackPageEntryCompilation({
21383
- entryFilePath: options.entryFilePath,
21384
- ctx: options.ctx,
21385
- pluginCtx: options.pluginCtx,
21386
- configService: options.configService,
21387
- compileOptionsState: options.compileOptionsState
21388
- });
21389
- await handleFallbackPageLayouts({
21390
- source,
21391
- entryFilePath: options.entryFilePath,
21392
- configService: options.configService,
21393
- emitLayouts: async (layouts) => {
21394
- await emitBundlePageLayoutsIfNeeded({
21395
- layouts,
21396
- pluginCtx: options.pluginCtx,
21397
- bundle: options.bundle,
21398
- ctx: options.ctx,
21399
- configService: options.configService,
21400
- compileOptionsState: options.compileOptionsState,
21401
- outputExtensions: options.outputExtensions
21647
+ //#endregion
21648
+ //#region src/plugins/vue/transform/plugin/shared/compile.ts
21649
+ function normalizeVueTransformResult(result) {
21650
+ return {
21651
+ ...result,
21652
+ scriptMap: normalizeEncodedSourceMapLike(result.scriptMap)
21653
+ };
21654
+ }
21655
+ async function finalizeTransformEntryScript(options) {
21656
+ const { result, filename, pluginCtx, configService, isPage, isApp, forcePageFeatureInjection = false } = options;
21657
+ if (isPage && result.script) {
21658
+ if (mayNeedTransformPageScrollDiagnostics(result.script)) for (const warning of collectOnPageScrollPerformanceWarnings(result.script, filename, { engine: resolveAstEngine(configService.weappViteConfig) })) logger_default.warn(warning);
21659
+ if (forcePageFeatureInjection || mayNeedTransformPageFeatureInjection(result.script)) {
21660
+ const injected = await injectWevuPageFeaturesInJsWithViteResolver(pluginCtx, result.script, filename, {
21661
+ checkMtime: configService.isDev,
21662
+ minify: isWevuMinifyEnabled(configService.weappViteConfig, configService.isDev)
21402
21663
  });
21664
+ if (injected.transformed) {
21665
+ result.script = injected.code;
21666
+ result.scriptMap = composeSourceMaps(injected.map, result.scriptMap);
21667
+ }
21668
+ }
21669
+ }
21670
+ if (!isApp && result.script && result.template && isAutoSetDataPickEnabled(configService.weappViteConfig) && mayNeedTransformSetDataPick(result.template, { platform: configService.platform }) && mayNeedInjectSetDataPickInJs(result.script)) {
21671
+ const keys = collectSetDataPickKeysFromTemplate(result.template, { astEngine: resolveAstEngine(configService.weappViteConfig) });
21672
+ const injectedPick = injectSetDataPickInJs(result.script, keys);
21673
+ if (injectedPick.transformed) {
21674
+ result.script = injectedPick.code;
21675
+ result.scriptMap = composeSourceMaps(injectedPick.map, result.scriptMap);
21676
+ }
21677
+ }
21678
+ if (!isPage && !isApp && result.script && result.template?.includes(WEVU_SLOT_OWNER_ID_PROP)) {
21679
+ const injectedProps = injectScopedSlotHostPropertiesInJs(result.script);
21680
+ if (injectedProps.transformed) {
21681
+ result.script = injectedProps.code;
21682
+ result.scriptMap = composeSourceMaps(injectedProps.map, result.scriptMap);
21403
21683
  }
21684
+ }
21685
+ return result;
21686
+ }
21687
+ function finalizeTransformEntryCode(options) {
21688
+ const { result, filename, styleBlocks, isPage, isApp, isDev, hmrStyleToken } = options;
21689
+ const returned = new MagicString(result.script ?? "");
21690
+ let hasMutation = false;
21691
+ if (styleBlocks?.length) {
21692
+ const styleImports = buildWeappVueStyleRequests(filename, styleBlocks, { hmrToken: hmrStyleToken }).map((request) => `import ${JSON.stringify(request)};\n`).join("");
21693
+ returned.prepend(styleImports);
21694
+ hasMutation = true;
21695
+ }
21696
+ if (!isApp && !result.script?.trim()) {
21697
+ returned.append(resolveScriptlessVueEntryStub(isPage));
21698
+ hasMutation = true;
21699
+ }
21700
+ const macroHash = result.meta?.jsonMacroHash;
21701
+ if (macroHash && isDev) {
21702
+ returned.append(`\n;Object.defineProperty({}, '__weappViteJsonMacroHash', { value: ${JSON.stringify(macroHash)} })\n`);
21703
+ hasMutation = true;
21704
+ }
21705
+ const defineOptionsHash = result.meta?.defineOptionsHash;
21706
+ if (defineOptionsHash && isDev) {
21707
+ returned.append(`\n;Object.defineProperty({}, '__weappViteDefineOptionsHash', { value: ${JSON.stringify(defineOptionsHash)} })\n`);
21708
+ hasMutation = true;
21709
+ }
21710
+ const generatedMap = hasMutation ? returned.generateMap({
21711
+ hires: true,
21712
+ includeContent: true,
21713
+ source: filename,
21714
+ file: filename
21715
+ }) : null;
21716
+ return {
21717
+ code: returned.toString(),
21718
+ map: composeSourceMaps(generatedMap, result.scriptMap)
21719
+ };
21720
+ }
21721
+ async function compileTransformEntryResult(options) {
21722
+ const { transformedSource, filename, compileOptions, compileVueFile, compileJsxFile } = options;
21723
+ return filename.endsWith(".vue") ? await compileVueFile(transformedSource, filename, compileOptions) : await compileJsxFile(transformedSource, filename, compileOptions);
21724
+ }
21725
+ async function finalizeTransformCompiledResult(options) {
21726
+ const { ctx, pluginCtx, filename, source, autoRoutesSignature, result, compilationCache, setAppShell, configService, isPage, isApp, scopedSlotModules, emittedScopedSlotChunks, addWatchFile, emitScopedSlotChunks } = options;
21727
+ const transformResult = result;
21728
+ if (isPage && result.template) await handleTransformEntryPageLayoutFlow({
21729
+ pluginCtx,
21730
+ ctx,
21731
+ filename,
21732
+ source,
21733
+ result
21404
21734
  });
21405
- applyAppShell(result, options.entryFilePath, options.appShell);
21406
- emitFallbackPageBundleAssets({
21407
- bundle: options.bundle,
21408
- pluginCtx: options.pluginCtx,
21409
- ctx: options.ctx,
21410
- filename: options.entryFilePath,
21411
- relativeBase: options.relativeBase,
21735
+ if (isApp) setAppShell?.(hasAppShellTemplate(result) ? resolveAppShellLayout(configService) : void 0);
21736
+ if (!isApp) registerVueTemplateToken(ctx, filename, result.template);
21737
+ if (Array.isArray(result.meta?.sfcSrcDeps) && typeof pluginCtx.addWatchFile === "function") for (const dep of result.meta.sfcSrcDeps) addWatchFile(pluginCtx, dep);
21738
+ await finalizeTransformEntryScript({
21739
+ result: transformResult,
21740
+ filename,
21741
+ pluginCtx,
21742
+ configService,
21743
+ isPage,
21744
+ isApp,
21745
+ forcePageFeatureInjection: isPage
21746
+ });
21747
+ compilationCache.set(filename, {
21412
21748
  result,
21413
- configService: options.configService,
21414
- templateExtension: options.templateExtension,
21415
- styleExtension: options.styleExtension,
21416
- jsonExtension: options.jsonExtension,
21417
- scriptModuleExtension: options.scriptModuleExtension,
21418
- outputExtensions: options.outputExtensions,
21419
- platformAssetOptions: options.platformAssetOptions
21749
+ source,
21750
+ isPage,
21751
+ autoRoutesSignature,
21752
+ refreshToken: 0
21420
21753
  });
21754
+ const relativeBase = resolveVueOutputBase(configService, filename);
21755
+ if (relativeBase) emitScopedSlotChunks(pluginCtx, relativeBase, result, scopedSlotModules, emittedScopedSlotChunks, configService.outputExtensions);
21756
+ return transformResult;
21421
21757
  }
21422
- async function emitFallbackPageAssets(bundle, state, options) {
21423
- const { ctx, pluginCtx, compilationCache, reExportResolutionCache, classStyleRuntimeWarned, compileOptionsCache } = state;
21424
- const { configService, scanService } = ctx;
21425
- if (!configService || !scanService) return;
21426
- const compileOptionsState = {
21427
- reExportResolutionCache,
21428
- classStyleRuntimeWarned,
21429
- compileOptionsCache
21758
+ function logTransformFileError(filename, error) {
21759
+ const message = error instanceof Error ? error.message : String(error);
21760
+ logger_default.error(`[Vue 编译] 编译 ${filename} 失败:${message}`);
21761
+ }
21762
+ //#endregion
21763
+ //#region src/plugins/vue/transform/bundle/shared/types.ts
21764
+ function getVueBundlePageLayoutPlan(result) {
21765
+ return result.meta?.pageLayoutPlan;
21766
+ }
21767
+ function setVueBundlePageLayoutPlan(result, plan) {
21768
+ const current = result;
21769
+ current.meta = {
21770
+ ...current.meta,
21771
+ pageLayoutPlan: plan
21430
21772
  };
21431
- const { outputExtensions, templateExtension, styleExtension, jsonExtension, scriptModuleExtension, platformAssetOptions } = resolveVueBundleAssetContext(configService);
21432
- const collectedEntries = await collectFallbackPageEntryIds(configService, scanService);
21433
- for (const entryId of collectedEntries) {
21434
- if (options?.emittedEntryIds && !isFallbackEntryPending(entryId, options.emittedEntryIds, configService)) continue;
21435
- const emitState = await resolveFallbackPageEmitState({
21436
- entryId,
21437
- configService,
21438
- compilationCache,
21439
- pathExists: async (candidate) => {
21440
- return await pathExists(candidate, { ttlMs: getPathExistsTtlMs(configService) }) ? candidate : void 0;
21441
- }
21442
- });
21443
- if (!emitState) continue;
21444
- const { relativeBase, entryFilePath } = emitState;
21445
- addBundleWatchFile(pluginCtx, entryFilePath);
21446
- try {
21447
- await emitResolvedFallbackPageEntryAssets({
21448
- bundle,
21449
- pluginCtx,
21450
- entryFilePath,
21451
- ctx,
21452
- relativeBase,
21453
- configService,
21454
- compileOptionsState,
21455
- templateExtension,
21456
- styleExtension,
21457
- jsonExtension,
21458
- scriptModuleExtension,
21459
- outputExtensions,
21460
- platformAssetOptions,
21461
- appShell: state.appShell
21462
- });
21463
- } catch (error) {
21464
- const message = error instanceof Error ? error.message : String(error);
21465
- logger_default.error(`[Vue 编译] 编译 ${entryFilePath} 失败:${message}`);
21466
- }
21467
- }
21468
21773
  }
21469
21774
  //#endregion
21470
- //#region src/plugins/vue/transform/bundle/index.ts
21471
- function resolveVueBundleEmitState(state) {
21472
- const { ctx, compilationCache } = state;
21473
- const { configService, scanService } = ctx;
21474
- if (!configService || !scanService) return;
21475
- state.appShell = Array.from(compilationCache.entries()).find(([filename, cached]) => {
21476
- return isAppVueFile(filename) && hasAppShellTemplate(cached.result);
21477
- }) ? resolveAppShellLayout(configService) : void 0;
21478
- const hmrState = ctx.runtimeState?.build?.hmr;
21479
- const isAppVueHmrUpdate = Boolean(configService.isDev && hmrState?.profile?.file && isAppVueFile(hmrState.profile.file));
21480
- const emittedEntryIds = Boolean(configService.isDev && hmrState && !isAppVueHmrUpdate && !hmrState.didEmitAllEntries && hmrState.lastEmittedEntryIds.size > 0) && hmrState ? hmrState.lastEmittedEntryIds : void 0;
21775
+ //#region src/plugins/vue/transform/bundle/shared/layout.ts
21776
+ const APP_VUE_LIKE_FILE_RE = /[\\/]app\.(?:vue|jsx|tsx)$/;
21777
+ function addBundleWatchFile(pluginCtx, filePath) {
21778
+ if (typeof pluginCtx.addWatchFile !== "function") return;
21779
+ pluginCtx.addWatchFile(normalizeWatchPath(filePath));
21780
+ }
21781
+ function getEntryBaseName(filename) {
21782
+ const extIndex = filename.lastIndexOf(".");
21783
+ if (extIndex < 0) return filename;
21784
+ return filename.slice(0, extIndex);
21785
+ }
21786
+ function isAppVueLikeFile(filename) {
21787
+ return APP_VUE_LIKE_FILE_RE.test(filename);
21788
+ }
21789
+ async function resolveFallbackPageEntryFile(options) {
21790
+ return await findFirstResolvedVueLikeEntry(options.entryId, { resolve: async (candidate) => {
21791
+ if (options.compilationCache.has(candidate)) return null;
21792
+ return await options.pathExists(candidate);
21793
+ } });
21794
+ }
21795
+ async function resolveFallbackPageEmitState(options) {
21796
+ const relativeBase = options.configService.relativeOutputPath(options.entryId);
21797
+ if (!relativeBase) return;
21798
+ const entryFilePath = await resolveFallbackPageEntryFile({
21799
+ entryId: options.entryId,
21800
+ compilationCache: options.compilationCache,
21801
+ pathExists: options.pathExists
21802
+ });
21803
+ if (!entryFilePath) return;
21481
21804
  return {
21482
- compilationEntries: Array.from(compilationCache.entries()).filter(([id]) => {
21483
- return !emittedEntryIds || emittedEntryIds.has(normalizeFsResolvedId(id));
21484
- }),
21485
- emittedEntryIds
21805
+ relativeBase,
21806
+ entryFilePath
21486
21807
  };
21487
21808
  }
21488
- async function emitCompiledBundleEntries(bundle, state, compilationEntries) {
21489
- for (const [filename, cached] of compilationEntries) await emitCompiledVueEntryAssets(bundle, state, filename, cached);
21809
+ async function handleFallbackPageLayouts(options) {
21810
+ const resolvedLayoutPlan = await resolvePageLayoutPlan(options.source, options.entryFilePath, options.configService);
21811
+ await options.emitLayouts(resolvedLayoutPlan?.layouts);
21490
21812
  }
21491
- async function emitVueBundleAssets(bundle, state) {
21492
- const emitState = resolveVueBundleEmitState(state);
21493
- if (!emitState) return;
21494
- await emitCompiledBundleEntries(bundle, state, emitState.compilationEntries);
21495
- await emitFallbackPageAssets(bundle, state, { emittedEntryIds: emitState.emittedEntryIds });
21813
+ async function handleCompiledEntryPageLayouts(options) {
21814
+ const resolvedLayoutPlan = getVueBundlePageLayoutPlan(options.result) ?? await resolvePageLayoutPlan(options.source, options.filename, options.configService);
21815
+ if (resolvedLayoutPlan) applyPageLayoutPlan(options.result, options.filename, resolvedLayoutPlan, { platform: options.configService.platform });
21816
+ await options.emitLayouts(resolvedLayoutPlan?.layouts);
21496
21817
  }
21497
21818
  //#endregion
21498
- //#region src/plugins/vue/transform/plugin/shared/autoRoutes.ts
21499
- const AUTO_ROUTES_DYNAMIC_IMPORT_RE = /import\(\s*['"](?:weapp-vite\/auto-routes|virtual:weapp-vite-auto-routes)['"]\s*\)/g;
21500
- const AUTO_ROUTES_ID = "weapp-vite/auto-routes";
21501
- const AUTO_ROUTES_VIRTUAL_ID = "virtual:weapp-vite-auto-routes";
21502
- const AUTO_ROUTES_NAMED_IMPORT_ALIAS_RE = /\s+as\s+/g;
21503
- const AUTO_ROUTES_DEFAULT_AND_NAMED_IMPORT_RE = /^([A-Z_$][\w$]*)\s*,\s*(\{[^}]+\})$/i;
21504
- function mayNeedInlineAutoRoutes(source) {
21505
- return source.includes(AUTO_ROUTES_ID) || source.includes(AUTO_ROUTES_VIRTUAL_ID);
21506
- }
21507
- function toObjectDestructureClause(namedImportClause) {
21508
- return namedImportClause.replace(AUTO_ROUTES_NAMED_IMPORT_ALIAS_RE, ": ");
21819
+ //#region src/plugins/vue/transform/bundle/shared/compile.ts
21820
+ async function compileVueLikeFile(options) {
21821
+ const { source, filename, ctx, pluginCtx, isPage, isApp, configService, compileOptionsState } = options;
21822
+ const compileOptions = createCompileVueFileOptions(ctx, pluginCtx, filename, isPage, isApp, configService, compileOptionsState);
21823
+ if (filename.endsWith(".vue")) {
21824
+ const result = await compileVueFile(source, filename, compileOptions);
21825
+ if (isPage && result.template) {
21826
+ const resolvedLayoutPlan = await resolvePageLayoutPlan(source, filename, configService);
21827
+ if (resolvedLayoutPlan) {
21828
+ setVueBundlePageLayoutPlan(result, resolvedLayoutPlan);
21829
+ applyPageLayoutPlan(result, filename, resolvedLayoutPlan, { platform: configService.platform });
21830
+ await addResolvedPageLayoutWatchFiles(pluginCtx, resolvedLayoutPlan.layouts);
21831
+ }
21832
+ }
21833
+ return result;
21834
+ }
21835
+ const result = await compileJsxFile(source, filename, compileOptions);
21836
+ if (isPage && result.template) {
21837
+ const resolvedLayoutPlan = await resolvePageLayoutPlan(source, filename, configService);
21838
+ if (resolvedLayoutPlan) {
21839
+ setVueBundlePageLayoutPlan(result, resolvedLayoutPlan);
21840
+ applyPageLayoutPlan(result, filename, resolvedLayoutPlan, { platform: configService.platform });
21841
+ await addResolvedPageLayoutWatchFiles(pluginCtx, resolvedLayoutPlan.layouts);
21842
+ }
21843
+ }
21844
+ return result;
21509
21845
  }
21510
- function resolveInlineAutoRoutesImport(line, inlineRoutes, replacementIndex) {
21511
- const trimmedLine = line.trim();
21512
- if (!trimmedLine.startsWith("import ") || !trimmedLine.includes(" from ") || !trimmedLine.includes(`'${AUTO_ROUTES_ID}'`) && !trimmedLine.includes(`"${AUTO_ROUTES_ID}"`) && !trimmedLine.includes(`'${AUTO_ROUTES_VIRTUAL_ID}'`) && !trimmedLine.includes(`"${AUTO_ROUTES_VIRTUAL_ID}"`)) return;
21513
- const clause = trimmedLine.slice(7, trimmedLine.lastIndexOf(" from ")).trim();
21514
- const inlineLiteral = JSON.stringify(inlineRoutes);
21515
- if (clause.startsWith("{")) return `const ${toObjectDestructureClause(clause)} = ${inlineLiteral};`;
21516
- if (clause.startsWith("* as ")) return `const ${clause.slice(5).trim()} = ${inlineLiteral};`;
21517
- const defaultAndNamedMatch = clause.match(AUTO_ROUTES_DEFAULT_AND_NAMED_IMPORT_RE);
21518
- if (defaultAndNamedMatch) {
21519
- const [, defaultName, namedClause] = defaultAndNamedMatch;
21520
- const localRef = `__weappViteAutoRoutesInline${replacementIndex}`;
21521
- return `const ${localRef} = ${inlineLiteral};\nconst ${defaultName} = ${localRef};\nconst ${toObjectDestructureClause(namedClause)} = ${localRef};`;
21846
+ async function finalizeCompiledVueLikeResult(options) {
21847
+ const { result, filename, pluginCtx, configService, isPage, isApp } = options;
21848
+ if (isPage && result.script) {
21849
+ const injected = await injectWevuPageFeaturesInJsWithViteResolver(pluginCtx, result.script, filename, {
21850
+ checkMtime: configService.isDev,
21851
+ minify: isWevuMinifyEnabled(configService.weappViteConfig, configService.isDev)
21852
+ });
21853
+ if (injected.transformed) result.script = injected.code;
21522
21854
  }
21523
- return `const ${clause} = ${inlineLiteral};`;
21855
+ if (!isApp && result.script && result.template && isAutoSetDataPickEnabled(configService.weappViteConfig) && mayNeedInjectSetDataPickInJs(result.script)) {
21856
+ const keys = collectSetDataPickKeysFromTemplate(result.template);
21857
+ const injectedPick = injectSetDataPickInJs(result.script, keys);
21858
+ if (injectedPick.transformed) result.script = injectedPick.code;
21859
+ }
21860
+ if (!isPage && !isApp && result.script && result.template?.includes(WEVU_SLOT_OWNER_ID_PROP)) {
21861
+ const injectedProps = injectScopedSlotHostPropertiesInJs(result.script);
21862
+ if (injectedProps.transformed) result.script = injectedProps.code;
21863
+ }
21864
+ return result;
21524
21865
  }
21525
- function createTransformStageMeasurer(vueTransformTiming) {
21526
- const stageTimings = {};
21527
- const totalStart = vueTransformTiming ? performance$1.now() : 0;
21528
- const measureStage = async (label, task) => {
21529
- if (!vueTransformTiming) return await task();
21530
- const start = performance$1.now();
21531
- const result = await task();
21532
- stageTimings[label] = Number((performance$1.now() - start).toFixed(2));
21533
- return result;
21534
- };
21535
- const reportTiming = (id, isPage) => {
21536
- if (!vueTransformTiming) return;
21537
- vueTransformTiming({
21538
- id,
21539
- isPage,
21540
- totalMs: Number((performance$1.now() - totalStart).toFixed(2)),
21541
- stages: stageTimings
21866
+ async function compileAndFinalizeVueLikeFile(options) {
21867
+ return await finalizeCompiledVueLikeResult({
21868
+ result: await compileVueLikeFile(options),
21869
+ filename: options.filename,
21870
+ pluginCtx: options.pluginCtx,
21871
+ configService: options.configService,
21872
+ isPage: options.isPage,
21873
+ isApp: options.isApp
21874
+ });
21875
+ }
21876
+ async function refreshCompiledVueEntryCacheInDev(options) {
21877
+ const { filename, cached, ctx, pluginCtx, configService, compileOptionsState } = options;
21878
+ if (!configService.isDev) return cached.result;
21879
+ try {
21880
+ const rawSource = await fs.readFile(filename, "utf-8");
21881
+ const isApp = isAppVueLikeFile(filename);
21882
+ const transformed = isApp ? await resolveTransformAutoRoutesSource({
21883
+ source: rawSource,
21884
+ autoRoutesService: ctx.autoRoutesService
21885
+ }) : {
21886
+ source: rawSource,
21887
+ signature: void 0
21888
+ };
21889
+ const source = transformed.source;
21890
+ const dirtyVueEntryIds = ctx.runtimeState?.build?.hmr?.dirtyVueEntryIds;
21891
+ const normalizedDirtyFilename = normalizeFsResolvedId(filename);
21892
+ const currentRefreshToken = (cached.refreshToken ?? 0) + (dirtyVueEntryIds?.has(normalizedDirtyFilename) ? 1 : 0);
21893
+ if (source === cached.source && transformed.signature === cached.autoRoutesSignature && currentRefreshToken === 0) return cached.result;
21894
+ const compiled = await compileAndFinalizeVueLikeFile({
21895
+ source,
21896
+ filename,
21897
+ ctx,
21898
+ pluginCtx,
21899
+ isPage: cached.isPage,
21900
+ isApp,
21901
+ configService,
21902
+ compileOptionsState
21542
21903
  });
21543
- };
21904
+ cached.source = source;
21905
+ cached.autoRoutesSignature = transformed.signature;
21906
+ cached.refreshToken = 0;
21907
+ dirtyVueEntryIds?.delete(normalizedDirtyFilename);
21908
+ cached.result = compiled;
21909
+ return compiled;
21910
+ } catch {
21911
+ return cached.result;
21912
+ }
21913
+ }
21914
+ async function resolveCompiledEntryEmitState(options) {
21915
+ const result = await refreshCompiledVueEntryCacheInDev({
21916
+ filename: options.filename,
21917
+ cached: options.cached,
21918
+ ctx: options.ctx,
21919
+ pluginCtx: options.pluginCtx,
21920
+ configService: options.configService,
21921
+ compileOptionsState: options.compileOptionsState
21922
+ });
21923
+ const baseName = getEntryBaseName(options.filename);
21924
+ const relativeBase = options.configService.relativeOutputPath(baseName);
21925
+ if (!relativeBase) return;
21544
21926
  return {
21545
- measureStage,
21546
- reportTiming
21927
+ result,
21928
+ relativeBase
21547
21929
  };
21548
21930
  }
21549
- async function inlineTransformAutoRoutes(options) {
21550
- const { source, autoRoutesService } = options;
21551
- if (!mayNeedInlineAutoRoutes(source)) return source;
21552
- AUTO_ROUTES_DYNAMIC_IMPORT_RE.lastIndex = 0;
21553
- await autoRoutesService?.ensureFresh?.();
21554
- const routesRef = autoRoutesService?.getReference?.();
21555
- const inlineRoutes = {
21556
- pages: routesRef?.pages ?? [],
21557
- entries: routesRef?.entries ?? [],
21558
- subPackages: routesRef?.subPackages ?? []
21931
+ async function loadFallbackPageEntryCompilation(options) {
21932
+ const source = await fs.readFile(options.entryFilePath, "utf-8");
21933
+ return {
21934
+ source,
21935
+ result: await compileAndFinalizeVueLikeFile({
21936
+ source,
21937
+ filename: options.entryFilePath,
21938
+ ctx: options.ctx,
21939
+ pluginCtx: options.pluginCtx,
21940
+ isPage: true,
21941
+ isApp: false,
21942
+ configService: options.configService,
21943
+ compileOptionsState: options.compileOptionsState
21944
+ })
21559
21945
  };
21560
- let importReplacementIndex = 0;
21561
- return source.split("\n").map((line) => {
21562
- const replaced = resolveInlineAutoRoutesImport(line, inlineRoutes, importReplacementIndex);
21563
- if (replaced) {
21564
- importReplacementIndex += 1;
21565
- return replaced;
21566
- }
21567
- return line;
21568
- }).join("\n").replace(AUTO_ROUTES_DYNAMIC_IMPORT_RE, `Promise.resolve(${JSON.stringify(inlineRoutes)})`);
21569
21946
  }
21570
21947
  //#endregion
21571
- //#region src/plugins/vue/transform/plugin/shared/state.ts
21572
- const APP_ENTRY_RE = /[\\/]app\.(?:vue|jsx|tsx)$/;
21573
- const TEMPLATE_MUSTACHE_HINT = "{{";
21574
- const TEMPLATE_EVENT_HINT_RE = /\b(?:bind|catch)[A-Za-z:_-]+=/;
21575
- const PAGE_FEATURE_HOOK_HINTS = [
21576
- "onPageScroll",
21577
- "onPullDownRefresh",
21578
- "onReachBottom",
21579
- "onRouteDone",
21580
- "onTabItemTap",
21581
- "onResize",
21582
- "onShareAppMessage",
21583
- "onShareTimeline",
21584
- "onAddToFavorites",
21585
- "onSaveExitState"
21586
- ];
21587
- const PAGE_SCROLL_HOOK_HINT = "onPageScroll";
21588
- function resolveScriptlessVueEntryStub(isPage) {
21589
- return isPage ? "Page({})" : "Component({})";
21590
- }
21591
- function isAppEntry(filename) {
21592
- return APP_ENTRY_RE.test(filename);
21593
- }
21594
- function isVueLikeId(id) {
21595
- return isVueLikeFile(id);
21596
- }
21597
- function mayNeedTransformSetDataPick(template, options) {
21598
- if (template.includes(TEMPLATE_MUSTACHE_HINT)) return true;
21599
- const directivePrefix = getWxmlDirectivePrefix(options?.platform);
21600
- if (new RegExp(`${escapeStringRegexp(directivePrefix)}:`).test(template)) return true;
21601
- return TEMPLATE_EVENT_HINT_RE.test(template);
21948
+ //#region src/plugins/vue/transform/bundle/layoutAssets.ts
21949
+ function resolveVueLayoutAssetOptions(options) {
21950
+ return resolveNativeLayoutOutputOptions(options);
21602
21951
  }
21603
- function mayNeedTransformPageFeatureInjection(script) {
21604
- return PAGE_FEATURE_HOOK_HINTS.some((hint) => script.includes(hint));
21952
+ async function emitResolvedBundleLayouts(options) {
21953
+ for (const layout of options.layouts) {
21954
+ if (layout.kind === "native") {
21955
+ await options.emitNativeLayout(layout.file);
21956
+ continue;
21957
+ }
21958
+ await options.emitVueLayout(layout.file);
21959
+ }
21605
21960
  }
21606
- function mayNeedTransformPageScrollDiagnostics(script) {
21607
- return script.includes(PAGE_SCROLL_HOOK_HINT);
21961
+ async function resolveNativeLayoutScriptChunkState(options) {
21962
+ const resolvedOptions = resolveVueLayoutAssetOptions({
21963
+ configService: options.configService,
21964
+ layoutBasePath: options.layoutBasePath,
21965
+ outputExtensions: options.outputExtensions
21966
+ });
21967
+ if (!resolvedOptions) return;
21968
+ const assets = await collectNativeLayoutAssets(options.layoutBasePath);
21969
+ if (!assets.script) return;
21970
+ return {
21971
+ fileName: resolveScriptlessComponentFileName(resolvedOptions.relativeBase, resolvedOptions.scriptExtension),
21972
+ scriptId: assets.script
21973
+ };
21608
21974
  }
21609
- function resolveTransformFilename(options) {
21610
- const { id, configService, pluginCtx, getSourceFromVirtualId, addWatchFile } = options;
21611
- const filename = toAbsoluteId(getSourceFromVirtualId(id), configService, void 0, { base: "cwd" });
21612
- if (!filename || !path.isAbsolute(filename)) return null;
21613
- if (typeof pluginCtx.addWatchFile === "function") addWatchFile(pluginCtx, filename);
21614
- return filename;
21975
+ async function emitNativeLayoutScriptChunkIfNeeded(options) {
21976
+ const nativeScriptChunkState = await resolveNativeLayoutScriptChunkState(options);
21977
+ if (!nativeScriptChunkState) return;
21978
+ emitNativeLayoutScriptChunkIfNeeded$1({
21979
+ pluginCtx: options.pluginCtx,
21980
+ scriptId: nativeScriptChunkState.scriptId,
21981
+ fileName: nativeScriptChunkState.fileName
21982
+ });
21615
21983
  }
21616
- async function loadTransformPageEntries(scanService) {
21617
- if (!scanService) return {
21618
- pages: [],
21619
- subPackages: [],
21620
- pluginPages: []
21621
- };
21622
- const appEntry = await scanService.loadAppEntry();
21623
- const subPackages = scanService.loadSubPackages().map((meta) => ({
21624
- root: meta.subPackage.root,
21625
- pages: meta.subPackage.pages
21626
- }));
21627
- const pluginPages = scanService.pluginJson ? Object.values(scanService.pluginJson.pages ?? {}).map((page) => String(page)) : [];
21984
+ async function resolveNativeLayoutAssetState(options) {
21985
+ const resolvedOptions = resolveVueLayoutAssetOptions({
21986
+ configService: options.configService,
21987
+ layoutBasePath: options.layoutBasePath,
21988
+ outputExtensions: options.outputExtensions
21989
+ });
21990
+ if (!resolvedOptions) return;
21628
21991
  return {
21629
- pages: appEntry.json?.pages ?? [],
21630
- subPackages,
21631
- pluginPages
21992
+ resolvedOptions,
21993
+ assets: await collectNativeLayoutAssets(options.layoutBasePath)
21632
21994
  };
21633
21995
  }
21634
- function invalidatePageLayoutCaches(configService, compilationCache, styleBlocksCache) {
21635
- if (!configService) return;
21636
- for (const [cachedId, cached] of compilationCache.entries()) {
21637
- if (cached.isPage) cached.source = void 0;
21638
- styleBlocksCache.delete(cachedId);
21996
+ async function emitResolvedNativeLayoutStaticAssets(options) {
21997
+ const staticAssetEntries = await resolveNativeLayoutStaticAssetEntries({
21998
+ assets: options.assets,
21999
+ resolvedOptions: options.resolvedOptions,
22000
+ readFile: fs.readFile
22001
+ });
22002
+ for (const asset of staticAssetEntries) {
22003
+ if (asset.kind === "template") {
22004
+ assertTemplateHasDefaultSlot({
22005
+ filename: options.assets.template,
22006
+ kind: "page-layout",
22007
+ template: asset.source
22008
+ });
22009
+ emitSfcTemplateIfMissing(options.pluginCtx, options.bundle, options.resolvedOptions.relativeBase, asset.source, options.resolvedOptions.templateExtension);
22010
+ continue;
22011
+ }
22012
+ emitSfcStyleIfMissing(options.pluginCtx, options.bundle, options.resolvedOptions.relativeBase, asset.source, options.resolvedOptions.styleExtension);
21639
22013
  }
21640
22014
  }
21641
- function invalidateVueFileCaches(file, compilationCache, styleBlocksCache, options) {
21642
- if (!options.existsSync(file)) compilationCache.delete(file);
21643
- else {
21644
- const cached = compilationCache.get(file);
21645
- if (cached) cached.source = void 0;
22015
+ async function emitNativeLayoutAssetsIfNeeded(options) {
22016
+ const { pluginCtx, bundle } = options;
22017
+ const nativeLayoutState = await resolveNativeLayoutAssetState(options);
22018
+ if (!nativeLayoutState) return;
22019
+ const { resolvedOptions, assets } = nativeLayoutState;
22020
+ if (assets.json) {
22021
+ const source = await fs.readFile(assets.json, "utf8");
22022
+ emitSfcJsonAsset(pluginCtx, bundle, resolvedOptions.relativeBase, { config: source }, {
22023
+ emitIfMissingOnly: true,
22024
+ extension: resolvedOptions.jsonExtension,
22025
+ kind: "component"
22026
+ });
21646
22027
  }
21647
- styleBlocksCache.delete(file);
22028
+ await emitResolvedNativeLayoutStaticAssets({
22029
+ pluginCtx,
22030
+ bundle,
22031
+ assets,
22032
+ resolvedOptions
22033
+ });
21648
22034
  }
21649
- function handleTransformLayoutInvalidation(file, options) {
21650
- const { configService, compilationCache, styleBlocksCache, isLayoutFile, invalidateResolvedPageLayoutsCache } = options;
21651
- if (!configService || !isLayoutFile(file, configService)) return false;
21652
- invalidateResolvedPageLayoutsCache(configService.absoluteSrcRoot);
21653
- invalidatePageLayoutCaches(configService, compilationCache, styleBlocksCache);
21654
- return true;
22035
+ function emitScriptlessComponentJsFallbackIfMissing(options) {
22036
+ const { pluginCtx, bundle, relativeBase, scriptExtension } = options;
22037
+ ensureScriptlessComponentAsset(pluginCtx, bundle, relativeBase, scriptExtension);
21655
22038
  }
21656
- function handleTransformVueFileInvalidation(file, options) {
21657
- if (!isVueLikeId(file)) return false;
21658
- invalidateVueFileCaches(file, options.compilationCache, options.styleBlocksCache, { existsSync: options.existsSync });
21659
- return true;
22039
+ function resolveVueLayoutScriptFallbackState(options) {
22040
+ const resolvedOptions = resolveVueLayoutAssetOptions({
22041
+ configService: options.configService,
22042
+ layoutBasePath: getEntryBaseName(options.layoutFilePath),
22043
+ outputExtensions: options.outputExtensions
22044
+ });
22045
+ if (!resolvedOptions) return;
22046
+ const scriptFileName = resolveScriptlessComponentFileName(resolvedOptions.relativeBase, resolvedOptions.scriptExtension);
22047
+ if (options.bundle[scriptFileName]) return;
22048
+ return {
22049
+ resolvedOptions,
22050
+ scriptFileName
22051
+ };
22052
+ }
22053
+ async function emitVueLayoutScriptFallbackIfNeeded(options) {
22054
+ const { pluginCtx, bundle, layoutFilePath, ctx, configService, compileOptionsState, outputExtensions } = options;
22055
+ const fallbackState = resolveVueLayoutScriptFallbackState({
22056
+ bundle,
22057
+ layoutFilePath,
22058
+ configService,
22059
+ outputExtensions
22060
+ });
22061
+ if (!fallbackState) return;
22062
+ const { resolvedOptions } = fallbackState;
22063
+ const result = await compileVueLikeFile({
22064
+ source: await fs.readFile(layoutFilePath, "utf-8"),
22065
+ filename: layoutFilePath,
22066
+ ctx,
22067
+ pluginCtx,
22068
+ isPage: false,
22069
+ isApp: false,
22070
+ configService,
22071
+ compileOptionsState
22072
+ });
22073
+ assertTemplateHasDefaultSlot({
22074
+ filename: layoutFilePath,
22075
+ kind: "page-layout",
22076
+ template: result.template
22077
+ });
22078
+ if (result.script?.trim()) return;
22079
+ emitScriptlessComponentJsFallbackIfMissing({
22080
+ pluginCtx,
22081
+ bundle,
22082
+ relativeBase: resolvedOptions.relativeBase,
22083
+ scriptExtension: resolvedOptions.scriptExtension
22084
+ });
21660
22085
  }
21661
- async function ensureSfcStyleBlocks(filename, styleBlocksCache, options) {
21662
- const cached = styleBlocksCache.get(filename);
21663
- if (cached) return cached;
21664
- const styles = await options.load(filename);
21665
- styleBlocksCache.set(filename, styles);
21666
- return styles;
22086
+ function createBundleLayoutEmitters(options) {
22087
+ return {
22088
+ emitNativeLayout: async (layoutFilePath) => {
22089
+ await emitNativeLayoutAssetsIfNeeded({
22090
+ pluginCtx: options.pluginCtx,
22091
+ bundle: options.bundle,
22092
+ layoutBasePath: layoutFilePath,
22093
+ configService: options.configService,
22094
+ outputExtensions: options.outputExtensions
22095
+ });
22096
+ },
22097
+ emitVueLayout: async (layoutFilePath) => {
22098
+ await emitVueLayoutScriptFallbackIfNeeded({
22099
+ pluginCtx: options.pluginCtx,
22100
+ bundle: options.bundle,
22101
+ layoutFilePath,
22102
+ ctx: options.ctx,
22103
+ configService: options.configService,
22104
+ compileOptionsState: options.compileOptionsState,
22105
+ outputExtensions: options.outputExtensions
22106
+ });
22107
+ }
22108
+ };
21667
22109
  }
21668
- async function loadTransformSource(options) {
21669
- const { code, filename, isDev, readFileCached } = options;
21670
- if (typeof code === "string") return code;
21671
- return isDev ? await readFileCached(filename, {
21672
- checkMtime: true,
21673
- encoding: "utf8"
21674
- }) : await fs.readFile(filename, "utf-8");
22110
+ async function emitBundlePageLayoutsIfNeeded(options) {
22111
+ if (!options.layouts?.length) return;
22112
+ const layoutEmitters = createBundleLayoutEmitters(options);
22113
+ await emitResolvedBundleLayouts({
22114
+ layouts: options.layouts,
22115
+ emitNativeLayout: layoutEmitters.emitNativeLayout,
22116
+ emitVueLayout: layoutEmitters.emitVueLayout
22117
+ });
21675
22118
  }
21676
- async function preloadTransformSfcStyleBlocks(options) {
21677
- const { filename, source, styleBlocksCache, load } = options;
21678
- if (!filename.endsWith(".vue") || !source.includes("<style")) return;
22119
+ function resolveAppShellComponentConfig(config) {
22120
+ const shellConfig = { styleIsolation: "apply-shared" };
22121
+ if (!config) return JSON.stringify(shellConfig, null, 2);
21679
22122
  try {
21680
- return await ensureSfcStyleBlocks(filename, styleBlocksCache, { load: async (target) => await load(target, source) });
22123
+ const parsed = JSON.parse(config);
22124
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return JSON.stringify(shellConfig, null, 2);
22125
+ for (const key of ["usingComponents", "componentGenerics"]) {
22126
+ const value = parsed[key];
22127
+ if (value && typeof value === "object" && !Array.isArray(value)) shellConfig[key] = value;
22128
+ }
22129
+ return Object.keys(shellConfig).length ? JSON.stringify(shellConfig, null, 2) : void 0;
21681
22130
  } catch {
21682
22131
  return;
21683
22132
  }
21684
22133
  }
22134
+ function emitAppShellAssetsIfNeeded(options) {
22135
+ const { relativeBase, result } = options;
22136
+ if (!relativeBase || !result.template?.trim()) return;
22137
+ assertTemplateHasDefaultSlot({
22138
+ filename: options.filename,
22139
+ kind: "app-shell",
22140
+ template: result.template
22141
+ });
22142
+ emitBundleVueEntryAssets({
22143
+ bundle: options.bundle,
22144
+ pluginCtx: options.pluginCtx,
22145
+ ctx: options.ctx,
22146
+ filename: relativeBase,
22147
+ relativeBase,
22148
+ result,
22149
+ configService: options.configService,
22150
+ templateExtension: options.templateExtension,
22151
+ scriptModuleExtension: options.scriptModuleExtension,
22152
+ outputExtensions: options.outputExtensions,
22153
+ platformAssetOptions: options.platformAssetOptions
22154
+ });
22155
+ emitSharedVueEntryJsonAsset({
22156
+ bundle: options.bundle,
22157
+ pluginCtx: options.pluginCtx,
22158
+ relativeBase,
22159
+ config: resolveAppShellComponentConfig(result.config),
22160
+ outputExtensions: options.outputExtensions,
22161
+ platformAssetOptions: options.platformAssetOptions,
22162
+ jsonOptions: {
22163
+ defaultConfig: { component: true },
22164
+ kind: "component",
22165
+ extension: options.jsonExtension
22166
+ }
22167
+ });
22168
+ emitScriptlessComponentJsFallbackIfMissing({
22169
+ pluginCtx: options.pluginCtx,
22170
+ bundle: options.bundle,
22171
+ relativeBase,
22172
+ scriptExtension: options.scriptExtension
22173
+ });
22174
+ }
21685
22175
  //#endregion
21686
- //#region src/plugins/vue/transform/plugin/shared/layout.ts
21687
- async function handleTransformEntryPageLayoutFlow(options) {
21688
- const configService = options.ctx.configService;
22176
+ //#region src/plugins/vue/transform/bundle/emitCompiledEntry.ts
22177
+ async function emitResolvedCompiledVueEntryAssets(options) {
22178
+ const { bundle, state, filename, cached, result, relativeBase, compileOptionsState } = options;
22179
+ const { ctx, pluginCtx } = state;
22180
+ const { configService } = ctx;
21689
22181
  if (!configService) return;
21690
- const resolvedLayoutPlan = await resolvePageLayoutPlan(options.source, options.filename, configService);
21691
- if (!resolvedLayoutPlan) return;
21692
- if (options.result) applyPageLayoutPlan(options.result, options.filename, resolvedLayoutPlan, { platform: configService.platform });
21693
- await addResolvedPageLayoutWatchFiles(options.pluginCtx, resolvedLayoutPlan.layouts);
21694
- for (const layout of resolvedLayoutPlan.layouts) {
21695
- if (layout.kind !== "native") continue;
21696
- await emitNativeLayoutScriptChunkIfNeeded({
21697
- pluginCtx: options.pluginCtx,
21698
- layoutBasePath: layout.file,
22182
+ if (isAppVueFile(filename) && hasAppShellTemplate(result)) emitAppShellAssetsIfNeeded({
22183
+ bundle,
22184
+ pluginCtx,
22185
+ ctx,
22186
+ filename,
22187
+ relativeBase: resolveAppShellRelativeBase(configService),
22188
+ result,
22189
+ configService,
22190
+ templateExtension: options.templateExtension,
22191
+ jsonExtension: options.jsonExtension,
22192
+ scriptExtension: options.scriptExtension,
22193
+ scriptModuleExtension: options.scriptModuleExtension,
22194
+ outputExtensions: options.outputExtensions,
22195
+ platformAssetOptions: options.platformAssetOptions
22196
+ });
22197
+ if (cached.isPage && cached.source) {
22198
+ await handleCompiledEntryPageLayouts({
22199
+ source: cached.source,
22200
+ filename,
22201
+ result,
21699
22202
  configService,
21700
- outputExtensions: configService.outputExtensions
22203
+ emitLayouts: async (layouts) => {
22204
+ await emitBundlePageLayoutsIfNeeded({
22205
+ layouts,
22206
+ pluginCtx,
22207
+ bundle,
22208
+ ctx,
22209
+ configService,
22210
+ compileOptionsState,
22211
+ outputExtensions: options.outputExtensions
22212
+ });
22213
+ }
21701
22214
  });
22215
+ applyAppShell(result, filename, state.appShell);
21702
22216
  }
21703
- return resolvedLayoutPlan;
21704
- }
21705
- async function resolveTransformEntryFlags(options) {
21706
- const { pageMatcher, setPageMatcher, createPageMatcher, configService, scanService, scanDirty, scanDirtySynced, setScanDirtySynced, filename } = options;
21707
- if (configService.weappLibConfig?.enabled) return {
21708
- isPage: false,
21709
- isApp: false,
21710
- pageMatcher: pageMatcher ?? null
21711
- };
21712
- const currentPageMatcher = pageMatcher ?? createPageMatcher({
21713
- srcRoot: configService.absoluteSrcRoot,
21714
- loadEntries: async () => await loadTransformPageEntries(scanService),
21715
- warn: () => {}
22217
+ if (isLayoutFile(filename, configService)) assertTemplateHasDefaultSlot({
22218
+ filename,
22219
+ kind: "page-layout",
22220
+ template: result.template
21716
22221
  });
21717
- setPageMatcher(currentPageMatcher);
21718
- if (scanDirty && !scanDirtySynced) {
21719
- currentPageMatcher.markDirty();
21720
- setScanDirtySynced(true);
21721
- } else if (!scanDirty && scanDirtySynced) setScanDirtySynced(false);
21722
- return {
21723
- isPage: await currentPageMatcher.isPageFile(filename),
21724
- isApp: isAppEntry(filename),
21725
- pageMatcher: currentPageMatcher
21726
- };
21727
- }
21728
- async function registerNativeLayoutChunksForEntry(pluginCtx, ctx, filename, source) {
21729
- await handleTransformEntryPageLayoutFlow({
22222
+ const { shouldEmitComponentJson } = emitCompiledEntryBundleAssets({
22223
+ bundle,
21730
22224
  pluginCtx,
21731
22225
  ctx,
21732
22226
  filename,
21733
- source
22227
+ relativeBase,
22228
+ result,
22229
+ isPage: cached.isPage,
22230
+ configService,
22231
+ templateExtension: options.templateExtension,
22232
+ jsonExtension: options.jsonExtension,
22233
+ scriptModuleExtension: options.scriptModuleExtension,
22234
+ outputExtensions: options.outputExtensions,
22235
+ platformAssetOptions: options.platformAssetOptions
22236
+ });
22237
+ if (shouldEmitComponentJson && !result.script?.trim()) emitScriptlessComponentJsFallbackIfMissing({
22238
+ pluginCtx,
22239
+ bundle,
22240
+ relativeBase,
22241
+ scriptExtension: options.scriptExtension
21734
22242
  });
21735
22243
  }
21736
- async function preloadNativeLayoutEntries(options) {
21737
- const { pluginCtx, ctx, configService, scanService, collectFallbackPageEntryIds, findFirstResolvedVueLikeEntry, pathExists, readFile } = options;
21738
- if (!configService || !scanService) return;
21739
- const entryIds = await collectFallbackPageEntryIds(configService, scanService);
21740
- for (const entryId of entryIds) {
21741
- const entryFilePath = await findFirstResolvedVueLikeEntry(entryId, { resolve: async (candidate) => await pathExists(candidate) ? candidate : void 0 });
21742
- if (!entryFilePath) continue;
22244
+ async function emitCompiledVueEntryAssets(bundle, state, filename, cached) {
22245
+ const { ctx, pluginCtx, reExportResolutionCache, classStyleRuntimeWarned, compileOptionsCache } = state;
22246
+ const { configService } = ctx;
22247
+ if (!configService) return;
22248
+ addBundleWatchFile(pluginCtx, filename);
22249
+ const compileOptionsState = {
22250
+ reExportResolutionCache,
22251
+ classStyleRuntimeWarned,
22252
+ compileOptionsCache
22253
+ };
22254
+ const { outputExtensions, templateExtension, jsonExtension, scriptExtension, scriptModuleExtension, platformAssetOptions } = resolveVueBundleAssetContext(configService);
22255
+ const emitState = await resolveCompiledEntryEmitState({
22256
+ filename,
22257
+ cached,
22258
+ ctx,
22259
+ pluginCtx,
22260
+ configService,
22261
+ compileOptionsState
22262
+ });
22263
+ if (!emitState) return;
22264
+ await emitResolvedCompiledVueEntryAssets({
22265
+ bundle,
22266
+ state,
22267
+ filename,
22268
+ cached,
22269
+ result: emitState.result,
22270
+ relativeBase: emitState.relativeBase,
22271
+ compileOptionsState,
22272
+ outputExtensions,
22273
+ templateExtension,
22274
+ jsonExtension,
22275
+ scriptExtension,
22276
+ scriptModuleExtension,
22277
+ platformAssetOptions
22278
+ });
22279
+ }
22280
+ //#endregion
22281
+ //#region src/plugins/vue/transform/collectVuePages.ts
22282
+ async function collectVuePages(root) {
22283
+ const results = [];
22284
+ try {
22285
+ const entries = await fs.readdir(root);
22286
+ for (const entry of entries) {
22287
+ const full = path.join(root, entry);
22288
+ if ((await fs.stat(full)).isDirectory()) {
22289
+ const nested = await collectVuePages(full);
22290
+ results.push(...nested);
22291
+ } else if (isVueLikeFile(full)) results.push(stripVueLikeExtension(full));
22292
+ }
22293
+ } catch {}
22294
+ return results;
22295
+ }
22296
+ //#endregion
22297
+ //#region src/plugins/vue/transform/fallbackEntries.ts
22298
+ async function collectFallbackPageEntryIds(configService, scanService) {
22299
+ let pageList = [];
22300
+ if (scanService?.appEntry?.json?.pages?.length) pageList = scanService.appEntry.json.pages;
22301
+ else {
22302
+ const appJsonPath = path.join(configService.cwd, "dist", "app.json");
21743
22303
  try {
21744
- await registerNativeLayoutChunksForEntry(pluginCtx, ctx, entryFilePath, await readFile(entryFilePath, "utf8"));
22304
+ const appJsonContent = await fs.readFile(appJsonPath, "utf-8");
22305
+ pageList = JSON.parse(appJsonContent).pages || [];
21745
22306
  } catch {}
21746
22307
  }
22308
+ const collectedEntries = /* @__PURE__ */ new Set();
22309
+ pageList.forEach((p) => collectedEntries.add(path.join(configService.absoluteSrcRoot, p)));
22310
+ (await collectVuePages(path.join(configService.absoluteSrcRoot, "pages"))).forEach((f) => collectedEntries.add(f.slice(0, -4)));
22311
+ return collectedEntries;
21747
22312
  }
21748
- async function loadTransformStyleBlock(options) {
21749
- const { id, pluginCtx, configService, styleBlocksCache, loadScopedSlotModule, scopedSlotModules, parseWeappVueStyleRequest, readAndParseSfc, createReadAndParseSfcOptions } = options;
21750
- const scopedSlot = loadScopedSlotModule(id, scopedSlotModules);
21751
- if (scopedSlot) return scopedSlot;
21752
- const parsed = parseWeappVueStyleRequest(id);
21753
- if (!parsed) return null;
21754
- const { filename, index } = parsed;
21755
- let styles;
21756
- try {
21757
- styles = await ensureSfcStyleBlocks(filename, styleBlocksCache, { load: async (target) => (await readAndParseSfc(target, { ...createReadAndParseSfcOptions(pluginCtx, configService) })).descriptor.styles });
21758
- } catch {
21759
- return null;
22313
+ //#endregion
22314
+ //#region src/plugins/vue/transform/bundle/emitFallbackPage.ts
22315
+ function isFallbackEntryPending(entryId, emittedEntryIds, configService) {
22316
+ const normalizedEntryId = removeExtensionDeep(configService.relativeOutputPath(entryId));
22317
+ for (const emittedEntryId of emittedEntryIds) {
22318
+ const normalizedEmitted = normalizeFsResolvedId(emittedEntryId);
22319
+ if (!normalizedEmitted) continue;
22320
+ if (removeExtensionDeep(configService.relativeOutputPath(normalizedEmitted)) === normalizedEntryId) return true;
21760
22321
  }
21761
- const block = styles[index];
21762
- if (!block) return null;
21763
- return {
21764
- code: block.content,
21765
- map: null
21766
- };
22322
+ return false;
21767
22323
  }
21768
- //#endregion
21769
- //#region src/plugins/vue/transform/plugin/shared/compile.ts
21770
- function normalizeVueTransformResult(result) {
21771
- return {
21772
- ...result,
21773
- scriptMap: normalizeEncodedSourceMapLike(result.scriptMap)
21774
- };
22324
+ async function emitResolvedFallbackPageEntryAssets(options) {
22325
+ const { source, result } = await loadFallbackPageEntryCompilation({
22326
+ entryFilePath: options.entryFilePath,
22327
+ ctx: options.ctx,
22328
+ pluginCtx: options.pluginCtx,
22329
+ configService: options.configService,
22330
+ compileOptionsState: options.compileOptionsState
22331
+ });
22332
+ await handleFallbackPageLayouts({
22333
+ source,
22334
+ entryFilePath: options.entryFilePath,
22335
+ configService: options.configService,
22336
+ emitLayouts: async (layouts) => {
22337
+ await emitBundlePageLayoutsIfNeeded({
22338
+ layouts,
22339
+ pluginCtx: options.pluginCtx,
22340
+ bundle: options.bundle,
22341
+ ctx: options.ctx,
22342
+ configService: options.configService,
22343
+ compileOptionsState: options.compileOptionsState,
22344
+ outputExtensions: options.outputExtensions
22345
+ });
22346
+ }
22347
+ });
22348
+ applyAppShell(result, options.entryFilePath, options.appShell);
22349
+ emitFallbackPageBundleAssets({
22350
+ bundle: options.bundle,
22351
+ pluginCtx: options.pluginCtx,
22352
+ ctx: options.ctx,
22353
+ filename: options.entryFilePath,
22354
+ relativeBase: options.relativeBase,
22355
+ result,
22356
+ configService: options.configService,
22357
+ templateExtension: options.templateExtension,
22358
+ styleExtension: options.styleExtension,
22359
+ jsonExtension: options.jsonExtension,
22360
+ scriptModuleExtension: options.scriptModuleExtension,
22361
+ outputExtensions: options.outputExtensions,
22362
+ platformAssetOptions: options.platformAssetOptions
22363
+ });
21775
22364
  }
21776
- async function finalizeTransformEntryScript(options) {
21777
- const { result, filename, pluginCtx, configService, isPage, isApp, forcePageFeatureInjection = false } = options;
21778
- if (isPage && result.script) {
21779
- if (mayNeedTransformPageScrollDiagnostics(result.script)) for (const warning of collectOnPageScrollPerformanceWarnings(result.script, filename, { engine: resolveAstEngine(configService.weappViteConfig) })) logger_default.warn(warning);
21780
- if (forcePageFeatureInjection || mayNeedTransformPageFeatureInjection(result.script)) {
21781
- const injected = await injectWevuPageFeaturesInJsWithViteResolver(pluginCtx, result.script, filename, { checkMtime: configService.isDev });
21782
- if (injected.transformed) {
21783
- result.script = injected.code;
21784
- result.scriptMap = composeSourceMaps(injected.map, result.scriptMap);
22365
+ async function emitFallbackPageAssets(bundle, state, options) {
22366
+ const { ctx, pluginCtx, compilationCache, reExportResolutionCache, classStyleRuntimeWarned, compileOptionsCache } = state;
22367
+ const { configService, scanService } = ctx;
22368
+ if (!configService || !scanService) return;
22369
+ const compileOptionsState = {
22370
+ reExportResolutionCache,
22371
+ classStyleRuntimeWarned,
22372
+ compileOptionsCache
22373
+ };
22374
+ const { outputExtensions, templateExtension, styleExtension, jsonExtension, scriptModuleExtension, platformAssetOptions } = resolveVueBundleAssetContext(configService);
22375
+ const collectedEntries = await collectFallbackPageEntryIds(configService, scanService);
22376
+ for (const entryId of collectedEntries) {
22377
+ if (options?.emittedEntryIds && !isFallbackEntryPending(entryId, options.emittedEntryIds, configService)) continue;
22378
+ const emitState = await resolveFallbackPageEmitState({
22379
+ entryId,
22380
+ configService,
22381
+ compilationCache,
22382
+ pathExists: async (candidate) => {
22383
+ return await pathExists(candidate, { ttlMs: getPathExistsTtlMs(configService) }) ? candidate : void 0;
21785
22384
  }
22385
+ });
22386
+ if (!emitState) continue;
22387
+ const { relativeBase, entryFilePath } = emitState;
22388
+ addBundleWatchFile(pluginCtx, entryFilePath);
22389
+ try {
22390
+ await emitResolvedFallbackPageEntryAssets({
22391
+ bundle,
22392
+ pluginCtx,
22393
+ entryFilePath,
22394
+ ctx,
22395
+ relativeBase,
22396
+ configService,
22397
+ compileOptionsState,
22398
+ templateExtension,
22399
+ styleExtension,
22400
+ jsonExtension,
22401
+ scriptModuleExtension,
22402
+ outputExtensions,
22403
+ platformAssetOptions,
22404
+ appShell: state.appShell
22405
+ });
22406
+ } catch (error) {
22407
+ const message = error instanceof Error ? error.message : String(error);
22408
+ logger_default.error(`[Vue 编译] 编译 ${entryFilePath} 失败:${message}`);
21786
22409
  }
21787
22410
  }
21788
- if (!isApp && result.script && result.template && isAutoSetDataPickEnabled(configService.weappViteConfig) && mayNeedTransformSetDataPick(result.template, { platform: configService.platform }) && mayNeedInjectSetDataPickInJs(result.script)) {
21789
- const keys = collectSetDataPickKeysFromTemplate(result.template, { astEngine: resolveAstEngine(configService.weappViteConfig) });
21790
- const injectedPick = injectSetDataPickInJs(result.script, keys);
21791
- if (injectedPick.transformed) {
21792
- result.script = injectedPick.code;
21793
- result.scriptMap = composeSourceMaps(injectedPick.map, result.scriptMap);
21794
- }
21795
- }
21796
- if (!isPage && !isApp && result.script && result.template?.includes(WEVU_SLOT_OWNER_ID_PROP)) {
21797
- const injectedProps = injectScopedSlotHostPropertiesInJs(result.script);
21798
- if (injectedProps.transformed) {
21799
- result.script = injectedProps.code;
21800
- result.scriptMap = composeSourceMaps(injectedProps.map, result.scriptMap);
21801
- }
21802
- }
21803
- return result;
21804
22411
  }
21805
- function finalizeTransformEntryCode(options) {
21806
- const { result, filename, styleBlocks, isPage, isApp, isDev } = options;
21807
- const returned = new MagicString(result.script ?? "");
21808
- let hasMutation = false;
21809
- if (styleBlocks?.length) {
21810
- const styleImports = buildWeappVueStyleRequests(filename, styleBlocks).map((request) => `import ${JSON.stringify(request)};\n`).join("");
21811
- returned.prepend(styleImports);
21812
- hasMutation = true;
21813
- }
21814
- if (!isApp && !result.script?.trim()) {
21815
- returned.append(resolveScriptlessVueEntryStub(isPage));
21816
- hasMutation = true;
21817
- }
21818
- const macroHash = result.meta?.jsonMacroHash;
21819
- if (macroHash && isDev) {
21820
- returned.append(`\n;Object.defineProperty({}, '__weappViteJsonMacroHash', { value: ${JSON.stringify(macroHash)} })\n`);
21821
- hasMutation = true;
21822
- }
21823
- const defineOptionsHash = result.meta?.defineOptionsHash;
21824
- if (defineOptionsHash && isDev) {
21825
- returned.append(`\n;Object.defineProperty({}, '__weappViteDefineOptionsHash', { value: ${JSON.stringify(defineOptionsHash)} })\n`);
21826
- hasMutation = true;
21827
- }
21828
- const generatedMap = hasMutation ? returned.generateMap({
21829
- hires: true,
21830
- includeContent: true,
21831
- source: filename,
21832
- file: filename
21833
- }) : null;
22412
+ //#endregion
22413
+ //#region src/plugins/vue/transform/bundle/index.ts
22414
+ function resolveVueBundleEmitState(state) {
22415
+ const { ctx, compilationCache } = state;
22416
+ const { configService, scanService } = ctx;
22417
+ if (!configService || !scanService) return;
22418
+ state.appShell = Array.from(compilationCache.entries()).find(([filename, cached]) => {
22419
+ return isAppVueFile(filename) && hasAppShellTemplate(cached.result);
22420
+ }) ? resolveAppShellLayout(configService) : void 0;
22421
+ const hmrState = ctx.runtimeState?.build?.hmr;
22422
+ const isAppVueHmrUpdate = Boolean(configService.isDev && hmrState?.profile?.file && isAppVueFile(hmrState.profile.file));
22423
+ const emittedEntryIds = Boolean(configService.isDev && hmrState && !isAppVueHmrUpdate && !hmrState.didEmitAllEntries && (hmrState.lastHmrEntryIds?.size ?? hmrState.lastEmittedEntryIds?.size ?? 0) > 0) && hmrState ? hmrState.lastHmrEntryIds?.size ? hmrState.lastHmrEntryIds : hmrState.lastEmittedEntryIds : void 0;
21834
22424
  return {
21835
- code: returned.toString(),
21836
- map: composeSourceMaps(generatedMap, result.scriptMap)
22425
+ compilationEntries: Array.from(compilationCache.entries()).filter(([id]) => {
22426
+ return !emittedEntryIds || emittedEntryIds.has(normalizeFsResolvedId(id));
22427
+ }),
22428
+ emittedEntryIds
21837
22429
  };
21838
22430
  }
21839
- async function compileTransformEntryResult(options) {
21840
- const { transformedSource, filename, compileOptions, compileVueFile, compileJsxFile } = options;
21841
- return filename.endsWith(".vue") ? await compileVueFile(transformedSource, filename, compileOptions) : await compileJsxFile(transformedSource, filename, compileOptions);
21842
- }
21843
- async function finalizeTransformCompiledResult(options) {
21844
- const { ctx, pluginCtx, filename, source, result, compilationCache, setAppShell, configService, isPage, isApp, scopedSlotModules, emittedScopedSlotChunks, addWatchFile, emitScopedSlotChunks } = options;
21845
- const transformResult = result;
21846
- if (isPage && result.template) await handleTransformEntryPageLayoutFlow({
21847
- pluginCtx,
21848
- ctx,
21849
- filename,
21850
- source,
21851
- result
21852
- });
21853
- if (isApp) setAppShell?.(hasAppShellTemplate(result) ? resolveAppShellLayout(configService) : void 0);
21854
- if (!isApp) registerVueTemplateToken(ctx, filename, result.template);
21855
- if (Array.isArray(result.meta?.sfcSrcDeps) && typeof pluginCtx.addWatchFile === "function") for (const dep of result.meta.sfcSrcDeps) addWatchFile(pluginCtx, dep);
21856
- await finalizeTransformEntryScript({
21857
- result: transformResult,
21858
- filename,
21859
- pluginCtx,
21860
- configService,
21861
- isPage,
21862
- isApp,
21863
- forcePageFeatureInjection: isPage
21864
- });
21865
- compilationCache.set(filename, {
21866
- result,
21867
- source,
21868
- isPage
21869
- });
21870
- const relativeBase = resolveVueOutputBase(configService, filename);
21871
- if (relativeBase) emitScopedSlotChunks(pluginCtx, relativeBase, result, scopedSlotModules, emittedScopedSlotChunks, configService.outputExtensions);
21872
- return transformResult;
22431
+ async function emitCompiledBundleEntries(bundle, state, compilationEntries) {
22432
+ for (const [filename, cached] of compilationEntries) await emitCompiledVueEntryAssets(bundle, state, filename, cached);
21873
22433
  }
21874
- function logTransformFileError(filename, error) {
21875
- const message = error instanceof Error ? error.message : String(error);
21876
- logger_default.error(`[Vue 编译] 编译 ${filename} 失败:${message}`);
22434
+ async function emitVueBundleAssets(bundle, state) {
22435
+ const emitState = resolveVueBundleEmitState(state);
22436
+ if (!emitState) return;
22437
+ await emitCompiledBundleEntries(bundle, state, emitState.compilationEntries);
22438
+ await emitFallbackPageAssets(bundle, state, { emittedEntryIds: emitState.emittedEntryIds });
21877
22439
  }
21878
22440
  //#endregion
21879
22441
  //#region src/plugins/wevu.ts
@@ -21997,10 +22559,15 @@ async function transformVueLikeFile(options) {
21997
22559
  filename
21998
22560
  }));
21999
22561
  let transformedSource = source;
22000
- if (isApp) transformedSource = await measureStage("ensureAutoRoutes", async () => await inlineTransformAutoRoutes({
22001
- source: transformedSource,
22002
- autoRoutesService: ctx.autoRoutesService
22003
- }));
22562
+ let autoRoutesSignature;
22563
+ if (isApp) {
22564
+ const transformed = await measureStage("ensureAutoRoutes", async () => await resolveTransformAutoRoutesSource({
22565
+ source: transformedSource,
22566
+ autoRoutesService: ctx.autoRoutesService
22567
+ }));
22568
+ transformedSource = transformed.source;
22569
+ autoRoutesSignature = transformed.signature;
22570
+ }
22004
22571
  const compileOptions = createCompileVueFileOptions(ctx, pluginCtx, filename, isPage, isApp, configService, {
22005
22572
  reExportResolutionCache,
22006
22573
  classStyleRuntimeWarned,
@@ -22014,7 +22581,8 @@ async function transformVueLikeFile(options) {
22014
22581
  compileJsxFile
22015
22582
  })));
22016
22583
  if (Array.isArray(result.meta?.styleBlocks)) styleBlocksCache.set(filename, result.meta.styleBlocks);
22017
- syncVueSfcStyleDependencies(ctx, filename, result.meta?.styleBlocks ?? styleBlocksCache.get(filename));
22584
+ const sfcStyleDependencies = syncVueSfcStyleDependencies(ctx, filename, result.meta?.styleBlocks ?? styleBlocksCache.get(filename));
22585
+ for (const dependency of sfcStyleDependencies) addNormalizedWatchFile(pluginCtx, dependency);
22018
22586
  registerScopedSlotHostGenerics(ctx, result.scopedSlotComponents, parseUsingComponents(result.config));
22019
22587
  await measureStage("finalizeCompiledResult", async () => {
22020
22588
  await finalizeTransformCompiledResult({
@@ -22022,6 +22590,7 @@ async function transformVueLikeFile(options) {
22022
22590
  pluginCtx,
22023
22591
  filename,
22024
22592
  source: transformedSource,
22593
+ autoRoutesSignature,
22025
22594
  result,
22026
22595
  compilationCache,
22027
22596
  setAppShell,
@@ -22040,7 +22609,8 @@ async function transformVueLikeFile(options) {
22040
22609
  styleBlocks: result.meta?.styleBlocks ?? styleBlocksCache.get(filename),
22041
22610
  isPage,
22042
22611
  isApp,
22043
- isDev: configService.isDev
22612
+ isDev: configService.isDev,
22613
+ hmrStyleToken: configService.isDev && ctx.runtimeState?.build?.hmr?.dirtyVueEntryIds?.has(filename) ? ctx.runtimeState.build.hmr.profile.eventId : void 0
22044
22614
  }));
22045
22615
  reportTiming(filename, isPage);
22046
22616
  return {
@@ -22091,6 +22661,7 @@ function createVueTransformPlugin(ctx) {
22091
22661
  return await loadTransformStyleBlock({
22092
22662
  id,
22093
22663
  pluginCtx: this,
22664
+ ctx,
22094
22665
  configService: ctx.configService,
22095
22666
  styleBlocksCache,
22096
22667
  loadScopedSlotModule: (id) => {
@@ -22477,7 +23048,8 @@ function normalizeInlineConfigAfterDefu(inline, options) {
22477
23048
  arrangePlugins(inline, ctx, subPackageMeta);
22478
23049
  }
22479
23050
  function resolveMiniprogramWatchInclude(options) {
22480
- const watchInclude = [path.join(options.cwd, options.srcRoot, "**")];
23051
+ const srcRoot = path.join(options.cwd, options.srcRoot);
23052
+ const watchInclude = options.buildScope?.enabled ? [...options.buildScope.includeMainPackage ? [path.join(srcRoot, "pages", "**")] : [], ...options.buildScope.subPackageRoots.map((root) => path.join(srcRoot, root, "**"))] : [path.join(srcRoot, "**")];
22481
23053
  if (!options.pluginRoot) return watchInclude;
22482
23054
  const absolutePluginRoot = path.resolve(options.cwd, options.pluginRoot);
22483
23055
  const relativeToSrc = path.relative(path.resolve(options.cwd, options.srcRoot), absolutePluginRoot);
@@ -22495,7 +23067,10 @@ function mergeMiniprogram(options, ...configs) {
22495
23067
  const external = [];
22496
23068
  const npmBuildCandidates = packageJson ? resolveNpmBuildCandidateDependenciesSync(ctx, packageJson) : [];
22497
23069
  if (npmBuildCandidates.length > 0) {
22498
- const builtinAliases = resolveBuiltinPackageAliases();
23070
+ const builtinAliases = resolveBuiltinPackageAliases({
23071
+ isDev,
23072
+ wevuRuntime: config.weapp?.wevu?.runtime
23073
+ });
22499
23074
  external.push(...npmBuildCandidates.map((pkg) => {
22500
23075
  return new RegExp(`^${escapeRegex(pkg)}(\\/|$)`);
22501
23076
  }), ...builtinAliases.filter(({ find }) => {
@@ -22517,7 +23092,8 @@ function mergeMiniprogram(options, ...configs) {
22517
23092
  const watchInclude = resolveMiniprogramWatchInclude({
22518
23093
  cwd,
22519
23094
  srcRoot,
22520
- pluginRoot: config.weapp?.pluginRoot
23095
+ pluginRoot: config.weapp?.pluginRoot,
23096
+ buildScope: resolveBuildScope(config.weapp?.buildScope)
22521
23097
  });
22522
23098
  const inline = defu(config, ...configs, {
22523
23099
  root: cwd,
@@ -22730,9 +23306,15 @@ function createConfigService(ctx) {
22730
23306
  const defineEnv = configState.defineEnv;
22731
23307
  let packageManager = configState.packageManager;
22732
23308
  let options = configState.options;
22733
- const builtinAliases = resolveBuiltinPackageAliases();
23309
+ let loadingOptions;
22734
23310
  const oxcRuntimeSupport = createOxcRuntimeSupport();
22735
- const aliasManager = createAliasManager(oxcRuntimeSupport.alias, builtinAliases);
23311
+ const aliasManager = createAliasManager(oxcRuntimeSupport.alias, resolveBuiltinPackageAliases());
23312
+ function injectBuiltinAliases(config) {
23313
+ aliasManager.injectBuiltinAliases(config, resolveBuiltinPackageAliases({
23314
+ isDev: loadingOptions?.isDev ?? options.isDev,
23315
+ wevuRuntime: config.weapp?.wevu?.runtime
23316
+ }));
23317
+ }
22736
23318
  const normalizeComparablePath = (input) => {
22737
23319
  const resolved = path.resolve(input);
22738
23320
  try {
@@ -22841,7 +23423,7 @@ function createConfigService(ctx) {
22841
23423
  }
22842
23424
  applyRuntimePlatform("miniprogram");
22843
23425
  const loadConfigImpl = createLoadConfig({
22844
- injectBuiltinAliases: aliasManager.injectBuiltinAliases,
23426
+ injectBuiltinAliases,
22845
23427
  oxcRolldownPlugin: oxcRuntimeSupport.rolldownPlugin,
22846
23428
  oxcVitePlugin: oxcRuntimeSupport.vitePlugin
22847
23429
  });
@@ -22858,7 +23440,14 @@ function createConfigService(ctx) {
22858
23440
  mode: "development",
22859
23441
  emitDefaultAutoImportOutputs: true
22860
23442
  });
22861
- const resolvedConfig = defu(await loadConfigImpl(input), {
23443
+ loadingOptions = input;
23444
+ let rawConfig;
23445
+ try {
23446
+ rawConfig = await loadConfigImpl(input);
23447
+ } finally {
23448
+ loadingOptions = void 0;
23449
+ }
23450
+ const resolvedConfig = defu(rawConfig, {
22862
23451
  cwd: input.cwd ?? defaultCwd,
22863
23452
  isDev: false,
22864
23453
  emitDefaultAutoImportOutputs: true,
@@ -22889,7 +23478,7 @@ function createConfigService(ctx) {
22889
23478
  ctx,
22890
23479
  getOptions,
22891
23480
  setOptions,
22892
- injectBuiltinAliases: aliasManager.injectBuiltinAliases,
23481
+ injectBuiltinAliases,
22893
23482
  getDefineImportMetaEnv,
22894
23483
  applyRuntimePlatform,
22895
23484
  oxcRolldownPlugin: oxcRuntimeSupport.rolldownPlugin
@@ -23321,8 +23910,12 @@ function createRuntimeState() {
23321
23910
  entriesMap: /* @__PURE__ */ new Map(),
23322
23911
  layoutEntryDependents: /* @__PURE__ */ new Map(),
23323
23912
  entryLayoutDependencies: /* @__PURE__ */ new Map(),
23913
+ vueEntryHasTemplate: /* @__PURE__ */ new Map(),
23324
23914
  vueEntryNonJsonSignatures: /* @__PURE__ */ new Map(),
23915
+ vueEntryScriptSignatures: /* @__PURE__ */ new Map(),
23916
+ dirtyVueEntryIds: /* @__PURE__ */ new Set(),
23325
23917
  didEmitAllEntries: false,
23918
+ lastHmrEntryIds: /* @__PURE__ */ new Set(),
23326
23919
  lastEmittedEntryIds: /* @__PURE__ */ new Set(),
23327
23920
  recentProfiles: [],
23328
23921
  profile: {}
@@ -23508,7 +24101,7 @@ async function loadAppEntry(ctx, scanState) {
23508
24101
  const vueAppPath = await findVueEntry(appBasename);
23509
24102
  let configFromVue;
23510
24103
  if (!appConfigFile && vueAppPath) {
23511
- const { extractConfigFromVue } = await import("./file-CGqxLI8I.mjs");
24104
+ const { extractConfigFromVue } = await import("./file-IuX99F00.mjs");
23512
24105
  configFromVue = await extractConfigFromVue(vueAppPath);
23513
24106
  if (configFromVue) appConfigFile = vueAppPath;
23514
24107
  }
@@ -23529,6 +24122,7 @@ async function loadAppEntry(ctx, scanState) {
23529
24122
  if (configFromVue) config = configFromVue;
23530
24123
  else config = await ctx.jsonService.read(appConfigFile);
23531
24124
  await applyAutoRoutesToAppConfigIfNeeded(ctx, config);
24125
+ applyBuildScopeToAppConfig(config, resolveBuildScope(ctx.configService.weappViteConfig.buildScope));
23532
24126
  if (isObject(config)) {
23533
24127
  normalizeAppConfigSubPackages(config);
23534
24128
  const resolvedAppEntry = {
@@ -24804,4 +25398,4 @@ async function createCompilerContext(options) {
24804
25398
  return ctx;
24805
25399
  }
24806
25400
  //#endregion
24807
- export { getDefaultIdeProjectRoot as C, createCjsConfigLoadError as S, isPathInside as T, resolveWeappConfigFile as _, resetCompilerContext as a, loadViteConfigFile as b, WEB_PLATFORM_ALIASES as c, isWebPlatform as d, resolveWeappViteTarget as f, getRouteRuntimeGlobalKeys as g, resolveHmrProfileJsonPath as h, getCompilerContext as i, getSupportedWeappVitePlatforms as l, SHARED_CHUNK_VIRTUAL_PREFIX as m, syncProjectSupportFiles as n, setActiveCompilerContextKey as o, createSharedBuildConfig as p, syncManagedTsconfigBootstrapFiles as r, formatBytes as s, createCompilerContext as t, getSupportedWeappViteTargetDescriptors as u, checkRuntime as v, shouldPassPlatformArgToIdeOpen as w, parseCommentJson as x, getProjectConfigFileName as y };
25401
+ export { createCjsConfigLoadError as C, isPathInside as E, parseCommentJson as S, shouldPassPlatformArgToIdeOpen as T, createBuildScopeConfigFromCli as _, resetCompilerContext as a, getProjectConfigFileName as b, WEB_PLATFORM_ALIASES as c, isWebPlatform as d, resolveWeappViteTarget as f, getRouteRuntimeGlobalKeys as g, resolveHmrProfileJsonPath as h, getCompilerContext as i, getSupportedWeappVitePlatforms as l, SHARED_CHUNK_VIRTUAL_PREFIX as m, syncProjectSupportFiles as n, setActiveCompilerContextKey as o, createSharedBuildConfig as p, syncManagedTsconfigBootstrapFiles as r, formatBytes as s, createCompilerContext as t, getSupportedWeappViteTargetDescriptors as u, resolveWeappConfigFile as v, getDefaultIdeProjectRoot as w, loadViteConfigFile as x, checkRuntime as y };