weapp-vite 7.1.3 → 7.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auto-import-presets/wevu-router.mjs +1 -1
- package/dist/auto-import-presets/wevu.mjs +1 -1
- package/dist/auto-import-presets.mjs +2 -2
- package/dist/auto-routes.mjs +1 -1
- package/dist/cli.mjs +607 -297
- package/dist/{config-D9e7hCm1.d.mts → config-JdEU9lCP.d.mts} +33 -2
- package/dist/config.d.mts +1 -1
- package/dist/{createContext-2OomMtxv.mjs → createContext-403iJEyy.mjs} +1219 -376
- package/dist/docs/getting-started.md +1 -1
- package/dist/docs/vue-sfc.md +20 -6
- package/dist/docs/wevu-authoring.md +1 -1
- package/dist/file-BRwj-D25.mjs +2 -0
- package/dist/{file-CD9gXASh.mjs → file-CfgcKGLR.mjs} +1 -1
- package/dist/getInstance-BhkSNqVQ.mjs +2 -0
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +1 -1
- package/dist/json.d.mts +1 -1
- package/dist/mcp.d.mts +1 -1
- package/dist/test.mjs +1 -1
- package/dist/types.d.mts +1 -1
- package/dist/wevu-BQWUU7br.mjs +142 -0
- package/dist/{wevu-router-Bl-FE8zi.mjs → wevu-router-Dg1LnBlg.mjs} +3 -1
- package/package.json +25 -23
- package/dist/file-BNDoQN7z.mjs +0 -2
- package/dist/getInstance-ChNOSsDp.mjs +0 -2
- package/dist/wevu-CrDVekb9.mjs +0 -130
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { n as applyWeappViteHostMeta } from "./pluginHost--CaeyWpA.mjs";
|
|
2
|
-
import { E as MINI_PROGRAM_PLATFORM_ADAPTERS, _ as templateExtensions, a as findJsonEntry, b as isNativeTemplateSource, c as isJsOrTs, d as touch, g as supportedCssLangs, h as scriptExtensions, i as findJsEntry, l as isTemplate, m as jsExtensions, n as changeFileExtension, o as findTemplateEntry, p as configExtensions, r as findCssEntry, s as findVueEntry, t as extractConfigFromVue, v as vueExtensions, w as inlineAutoRoutesImports, x as isSourceStyleExtension, y as ALL_NATIVE_STYLE_RESOLVER_EXTENSIONS } from "./file-
|
|
2
|
+
import { E as MINI_PROGRAM_PLATFORM_ADAPTERS, _ as templateExtensions, a as findJsonEntry, b as isNativeTemplateSource, c as isJsOrTs, d as touch, g as supportedCssLangs, h as scriptExtensions, i as findJsEntry, l as isTemplate, m as jsExtensions, n as changeFileExtension, o as findTemplateEntry, p as configExtensions, r as findCssEntry, s as findVueEntry, t as extractConfigFromVue, v as vueExtensions, w as inlineAutoRoutesImports, x as isSourceStyleExtension, y as ALL_NATIVE_STYLE_RESOLVER_EXTENSIONS } from "./file-CfgcKGLR.mjs";
|
|
3
3
|
import { n as configureLogger, r as logger_default } from "./logger-mt4mSTqV.mjs";
|
|
4
4
|
import { createRequire, isBuiltin } from "node:module";
|
|
5
5
|
import { createDebug } from "obug";
|
|
6
6
|
import fs, { existsSync, readFileSync, realpathSync, statSync } from "node:fs";
|
|
7
|
-
import { APP_PRELUDE_CHUNK_MARKER, APP_PRELUDE_GUARD_KEY, APP_PRELUDE_REQUIRE_MARKER, REQUEST_GLOBAL_ACTUALS_KEY, REQUEST_GLOBAL_BUNDLE_HOST_REF, REQUEST_GLOBAL_BUNDLE_MARKER, REQUEST_GLOBAL_BUNDLE_MARKER as REQUEST_GLOBAL_BUNDLE_MARKER$1, REQUEST_GLOBAL_CHUNK_HOST_REF, REQUEST_GLOBAL_CHUNK_MODULE_REF, REQUEST_GLOBAL_EXPOSE_HELPER, REQUEST_GLOBAL_INSTALLER_HOST_REF, REQUEST_GLOBAL_LAZY_CONSTRUCTOR_HELPER, REQUEST_GLOBAL_LAZY_FUNCTION_HELPER, REQUEST_GLOBAL_LOCAL_BINDINGS_MARKER, REQUEST_GLOBAL_LOCAL_BINDINGS_MARKER as REQUEST_GLOBAL_LOCAL_BINDINGS_MARKER$1, REQUEST_GLOBAL_MARK_PLACEHOLDER_HELPER, REQUEST_GLOBAL_PASSIVE_BINDINGS_MARKER, REQUEST_GLOBAL_PASSIVE_BINDINGS_MARKER as REQUEST_GLOBAL_PASSIVE_BINDINGS_MARKER$1, REQUEST_GLOBAL_PLACEHOLDER_KEY, REQUEST_GLOBAL_PRELUDE_GUARD_KEY, REQUEST_GLOBAL_PRELUDE_MARKER, REQUEST_GLOBAL_SYNTHETIC_EXPORT_NAME, REQUEST_GLOBAL_USABLE_CONSTRUCTOR_HELPER, WEAPP_I18N_JS_FILE, WEAPP_I18N_LOCALE_DATA_KEY, WEAPP_I18N_PUBLIC_MODULE_ID, WEAPP_I18N_RUNTIME_MARKER, WEAPP_I18N_VIRTUAL_MODULE_ID, WEAPP_I18N_WXS_FILE, WEAPP_REACT_EVENT_METHOD_NAME, WEAPP_VITE_EXTERNAL_OUTPUT_DIRECTORY, WEAPP_VITE_IMPORT_META_ENV_KEY, WEAPP_VITE_INJECTED_API_IDENTIFIER, WEAPP_VITE_LOGICAL_ENTRY_RESOLVED_PREFIX, WEAPP_VITE_LOGICAL_ENTRY_VIRTUAL_PREFIX, WEAPP_VITE_RUNTIME_CONTRACT_VERSION, WEAPP_VITE_RUNTIME_REACTIVITY_VIRTUAL_ID, WEAPP_VITE_RUNTIME_TEMPLATE_VIRTUAL_ID, WEAPP_VITE_RUNTIME_VIRTUAL_ID, WEAPP_VITE_RUNTIME_VIRTUAL_IDS, WEAPP_VITE_SIDECAR_OWNER_QUERY_MARKER, WEAPP_VITE_SIDECAR_QUERY_MARKER, WEAPP_VITE_SIDECAR_RESOLVED_PREFIX, WEAPP_VITE_SIDECAR_VIRTUAL_PREFIX, WEAPP_VITE_STATEFUL_HMR_BRIDGE_KEY, WEAPP_VITE_STATEFUL_HMR_CLIENT_KEY, WEAPP_VITE_STATEFUL_HMR_CONTROL_FILE, WEAPP_VITE_STATEFUL_HMR_CONTROL_KEY, WEAPP_VITE_STATEFUL_HMR_GLOBAL_STYLE_BASENAME, WEAPP_VITE_STATEFUL_HMR_PRELOAD_FILE, WEAPP_VITE_STATEFUL_HMR_UPDATE_FILE, WEVU_APP_SHELL_COMPONENT_BASE, WEVU_APP_SHELL_TAG_NAME, WEVU_INTERNAL_KEY_IDENTIFIER, WEVU_LAYOUT_BIND_PREFIX, WEVU_PAGE_LAYOUT_CURRENT_NAME_IDENTIFIER, WEVU_PAGE_LAYOUT_CURRENT_PROPS_IDENTIFIER, WEVU_PAGE_LAYOUT_NAME_KEY, WEVU_PAGE_LAYOUT_NEXT_NAME_IDENTIFIER, WEVU_PAGE_LAYOUT_NEXT_PROPS_IDENTIFIER, WEVU_PAGE_LAYOUT_NONE, WEVU_PAGE_LAYOUT_PROPS_KEY, WEVU_PAGE_LAYOUT_SETTER_KEY, WEVU_SLOT_FALLBACK_VIRTUAL_HOST_BASE, WEVU_SLOT_FALLBACK_VIRTUAL_HOST_GLOBAL_PATH, WEVU_SLOT_FALLBACK_VIRTUAL_HOST_TAG_NAME, WEVU_SLOT_NAMES_PROP, WEVU_SLOT_OWNER_ID_ATTR, WEVU_SLOT_OWNER_ID_KEY, WEVU_SLOT_OWNER_ID_PROP, WEVU_SLOT_PROPS_ATTR, WEVU_SLOT_SCOPE_ATTR, WEVU_SLOT_SCOPE_KEY } from "@weapp-core/constants";
|
|
7
|
+
import { APP_PRELUDE_CHUNK_MARKER, APP_PRELUDE_GUARD_KEY, APP_PRELUDE_REQUIRE_MARKER, REQUEST_GLOBAL_ACTUALS_KEY, REQUEST_GLOBAL_BUNDLE_HOST_REF, REQUEST_GLOBAL_BUNDLE_MARKER, REQUEST_GLOBAL_BUNDLE_MARKER as REQUEST_GLOBAL_BUNDLE_MARKER$1, REQUEST_GLOBAL_CHUNK_HOST_REF, REQUEST_GLOBAL_CHUNK_MODULE_REF, REQUEST_GLOBAL_EXPOSE_HELPER, REQUEST_GLOBAL_INSTALLER_HOST_REF, REQUEST_GLOBAL_LAZY_CONSTRUCTOR_HELPER, REQUEST_GLOBAL_LAZY_FUNCTION_HELPER, REQUEST_GLOBAL_LOCAL_BINDINGS_MARKER, REQUEST_GLOBAL_LOCAL_BINDINGS_MARKER as REQUEST_GLOBAL_LOCAL_BINDINGS_MARKER$1, REQUEST_GLOBAL_MARK_PLACEHOLDER_HELPER, REQUEST_GLOBAL_PASSIVE_BINDINGS_MARKER, REQUEST_GLOBAL_PASSIVE_BINDINGS_MARKER as REQUEST_GLOBAL_PASSIVE_BINDINGS_MARKER$1, REQUEST_GLOBAL_PLACEHOLDER_KEY, REQUEST_GLOBAL_PRELUDE_GUARD_KEY, REQUEST_GLOBAL_PRELUDE_MARKER, REQUEST_GLOBAL_SYNTHETIC_EXPORT_NAME, REQUEST_GLOBAL_USABLE_CONSTRUCTOR_HELPER, WEAPP_I18N_JS_FILE, WEAPP_I18N_LOCALE_DATA_KEY, WEAPP_I18N_PUBLIC_MODULE_ID, WEAPP_I18N_RUNTIME_MARKER, WEAPP_I18N_VIRTUAL_MODULE_ID, WEAPP_I18N_WXS_FILE, WEAPP_REACT_EVENT_METHOD_NAME, WEAPP_VITE_EXTERNAL_OUTPUT_DIRECTORY, WEAPP_VITE_IMPORT_META_ENV_KEY, WEAPP_VITE_INJECTED_API_IDENTIFIER, WEAPP_VITE_LOGICAL_ENTRY_RESOLVED_PREFIX, WEAPP_VITE_LOGICAL_ENTRY_VIRTUAL_PREFIX, WEAPP_VITE_RUNTIME_CONTRACT_VERSION, WEAPP_VITE_RUNTIME_REACTIVITY_VIRTUAL_ID, WEAPP_VITE_RUNTIME_TEMPLATE_VIRTUAL_ID, WEAPP_VITE_RUNTIME_VIRTUAL_ID, WEAPP_VITE_RUNTIME_VIRTUAL_IDS, WEAPP_VITE_SIDECAR_OWNER_QUERY_MARKER, WEAPP_VITE_SIDECAR_QUERY_MARKER, WEAPP_VITE_SIDECAR_RESOLVED_PREFIX, WEAPP_VITE_SIDECAR_VIRTUAL_PREFIX, WEAPP_VITE_STATEFUL_HMR_BRIDGE_KEY, WEAPP_VITE_STATEFUL_HMR_CLIENT_KEY, WEAPP_VITE_STATEFUL_HMR_CONTROL_FILE, WEAPP_VITE_STATEFUL_HMR_CONTROL_KEY, WEAPP_VITE_STATEFUL_HMR_GLOBAL_STYLE_BASENAME, WEAPP_VITE_STATEFUL_HMR_PRELOAD_FILE, WEAPP_VITE_STATEFUL_HMR_UPDATE_FILE, WEVU_APP_SHELL_COMPONENT_BASE, WEVU_APP_SHELL_TAG_NAME, WEVU_AUTO_ROUTES_MODULE_ID, WEVU_AUTO_ROUTES_MODULE_ID as WEVU_AUTO_ROUTES_MODULE_ID$1, WEVU_AUTO_ROUTES_RESOLVED_MODULE_ID, WEVU_AUTO_ROUTES_RESOLVED_MODULE_ID as WEVU_AUTO_ROUTES_RESOLVED_MODULE_ID$1, WEVU_AUTO_ROUTES_VIRTUAL_MODULE_ID, WEVU_AUTO_ROUTES_VIRTUAL_MODULE_ID as WEVU_AUTO_ROUTES_VIRTUAL_MODULE_ID$1, WEVU_DEFINE_PAGE_META_MACRO, WEVU_INTERNAL_KEY_IDENTIFIER, WEVU_LAYOUT_BIND_PREFIX, WEVU_PAGE_LAYOUT_CURRENT_NAME_IDENTIFIER, WEVU_PAGE_LAYOUT_CURRENT_PROPS_IDENTIFIER, WEVU_PAGE_LAYOUT_NAME_KEY, WEVU_PAGE_LAYOUT_NEXT_NAME_IDENTIFIER, WEVU_PAGE_LAYOUT_NEXT_PROPS_IDENTIFIER, WEVU_PAGE_LAYOUT_NONE, WEVU_PAGE_LAYOUT_PROPS_KEY, WEVU_PAGE_LAYOUT_SETTER_KEY, WEVU_ROUTER_MODULE_ID, WEVU_SLOT_FALLBACK_VIRTUAL_HOST_BASE, WEVU_SLOT_FALLBACK_VIRTUAL_HOST_GLOBAL_PATH, WEVU_SLOT_FALLBACK_VIRTUAL_HOST_TAG_NAME, WEVU_SLOT_NAMES_PROP, WEVU_SLOT_OWNER_ID_ATTR, WEVU_SLOT_OWNER_ID_KEY, WEVU_SLOT_OWNER_ID_PROP, WEVU_SLOT_PROPS_ATTR, WEVU_SLOT_SCOPE_ATTR, WEVU_SLOT_SCOPE_KEY } from "@weapp-core/constants";
|
|
8
8
|
import path, { posix } from "pathe";
|
|
9
9
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
10
10
|
import path$1, { normalize, posix as posix$1, relative, win32 } from "node:path";
|
|
@@ -18,15 +18,16 @@ import { collectOnPageScrollPerformanceWarnings } from "@weapp-vite/ast/operatio
|
|
|
18
18
|
import { BABEL_TS_MODULE_PARSER_OPTIONS as BABEL_TS_MODULE_PARSER_OPTIONS$1, generate as generate$1, parse as parse$3, parseJsLike, traverse } from "@weapp-vite/ast/babel";
|
|
19
19
|
import * as t from "@weapp-vite/ast/babelTypes";
|
|
20
20
|
import picomatch from "picomatch";
|
|
21
|
-
import { VUE_COMPONENT_TAG_RE, classifyVueSfcBlockChanges, collectVueTemplateTags, compileJsxFile, compileVueFile, compileVueStyleToWxss, createJsonMerger, createPageEntryMatcher, createPageEntryMatcher as createPageEntryMatcher$1, generateScopedId, getClassStyleWxsSource, getMiniProgramTemplatePlatform, getSfcCheckMtime, injectWevuPageFeaturesInJsWithResolver, invalidateFileCache, isAutoImportCandidateTag, isBuiltinComponent, isUniAppCompatibilityFile, pathExists, readAndParseSfc, readFile as readFile$1, refreshVueFileJsonConfig, resolveClassStyleWxsLocation, resolveVueSfcHmrSignatures, resolveVueSfcStyleIndependentSignature, transformNestedWxssVars, transformUniAppSource, transformVueDeepSelectors } from "wevu/compiler";
|
|
21
|
+
import { VUE_COMPONENT_TAG_RE, classifyVueSfcBlockChanges, collectPageMetaCallsFromPrograms, collectVueTemplateTags, compileJsxFile, compileVueFile, compileVueStyleToWxss, createJsonMerger, createPageEntryMatcher, createPageEntryMatcher as createPageEntryMatcher$1, extractPageDeclarationWithDependencies, generateScopedId, getClassStyleWxsSource, getMiniProgramTemplatePlatform, getSfcCheckMtime, injectWevuPageFeaturesInJsWithResolver, invalidateFileCache, isAutoImportCandidateTag, isBuiltinComponent, isUniAppCompatibilityFile, mayContainPageDeclaration, mayContainPageMeta, pathExists, readAndParseSfc, readAndParseSfc as readAndParseSfc$1, readFile as readFile$1, refreshVueFileJsonConfig, resolveClassStyleWxsLocation, resolveVueSfcHmrSignatures, resolveVueSfcStyleIndependentSignature, stripPageDeclaration, transformNestedWxssVars, transformUniAppSource, transformVueDeepSelectors } from "wevu/compiler";
|
|
22
22
|
import fs$2, { appendFile, copyFile, mkdir, readFile, readdir, rm } from "node:fs/promises";
|
|
23
|
-
import { build, createLogger, createServer, loadConfigFromFile, preprocessCSS, transformWithOxc } from "vite";
|
|
23
|
+
import { BuildEnvironment, build, createIdResolver, createLogger, createServer, loadConfigFromFile, preprocessCSS, resolveConfig, transformWithOxc } from "vite";
|
|
24
24
|
import { createHash, randomBytes, randomUUID } from "node:crypto";
|
|
25
25
|
import semverGte from "semver/functions/gte.js";
|
|
26
26
|
import semverSatisfies from "semver/functions/satisfies.js";
|
|
27
27
|
import semverValid from "semver/functions/valid.js";
|
|
28
28
|
import { LRUCache } from "lru-cache";
|
|
29
29
|
import { fdir } from "fdir";
|
|
30
|
+
import { isDeepStrictEqual } from "node:util";
|
|
30
31
|
import chokidar from "chokidar";
|
|
31
32
|
import { getPackageInfo, getPackageInfoSync, resolveModule } from "local-pkg";
|
|
32
33
|
import { build as build$1 } from "rolldown";
|
|
@@ -50,6 +51,7 @@ import tsconfigPaths from "vite-tsconfig-paths";
|
|
|
50
51
|
import { wrapPlugin } from "vite-plugin-performance";
|
|
51
52
|
import { performance as performance$1 } from "node:perf_hooks";
|
|
52
53
|
import { compileI18nCatalog, generateI18nCatalogModuleSource, generateI18nRuntimeSource, generateI18nWxsSource } from "@weapp-vite/i18n/compiler";
|
|
54
|
+
import selectorParser from "postcss-selector-parser";
|
|
53
55
|
import { weappWebPlugin } from "@weapp-vite/web";
|
|
54
56
|
import { bundleRequire } from "rolldown-require";
|
|
55
57
|
//#region src/debugger.ts
|
|
@@ -355,8 +357,9 @@ function createModuleGraphService() {
|
|
|
355
357
|
const queue = [id];
|
|
356
358
|
const visited = /* @__PURE__ */ new Set();
|
|
357
359
|
for (let index = 0; index < queue.length; index += 1) {
|
|
358
|
-
const
|
|
359
|
-
|
|
360
|
+
const target = queue[index];
|
|
361
|
+
const request = typeof target === "string" ? target : target.url ?? target.id;
|
|
362
|
+
if (!request || visited.has(request)) continue;
|
|
360
363
|
visited.add(request);
|
|
361
364
|
try {
|
|
362
365
|
await devServer.transformRequest(request);
|
|
@@ -364,10 +367,10 @@ function createModuleGraphService() {
|
|
|
364
367
|
debug$3?.(`dev graph 预热跳过无法展开的 external 终点 ${request}: ${String(error)}`);
|
|
365
368
|
continue;
|
|
366
369
|
}
|
|
367
|
-
const module = devServer.moduleGraph.getModuleById(request);
|
|
370
|
+
const module = typeof target === "string" ? devServer.moduleGraph.getModuleById(request) : target;
|
|
368
371
|
for (const dependency of module?.importedModules ?? []) {
|
|
369
372
|
const dependencyRequest = dependency.url ?? dependency.id;
|
|
370
|
-
if (dependencyRequest && !visited.has(dependencyRequest)) queue.push(
|
|
373
|
+
if (dependencyRequest && !visited.has(dependencyRequest)) queue.push(dependency);
|
|
371
374
|
}
|
|
372
375
|
}
|
|
373
376
|
};
|
|
@@ -8990,17 +8993,46 @@ function formatSubPackagesTuple(subPackages, baseIndent = "") {
|
|
|
8990
8993
|
lines.push(`${baseIndent}]`);
|
|
8991
8994
|
return lines.join("\n");
|
|
8992
8995
|
}
|
|
8993
|
-
function
|
|
8996
|
+
function formatStaticRouteType(value, baseIndent) {
|
|
8997
|
+
if (value === null) return "null";
|
|
8998
|
+
if (typeof value === "string") return "string";
|
|
8999
|
+
if (typeof value === "number") return "number";
|
|
9000
|
+
if (typeof value === "boolean") return "boolean";
|
|
9001
|
+
if (Array.isArray(value)) {
|
|
9002
|
+
if (value.length === 0) return "unknown[]";
|
|
9003
|
+
return `Array<${[...new Set(value.map((item) => formatStaticRouteType(item, baseIndent)))].join(" | ")}>`;
|
|
9004
|
+
}
|
|
9005
|
+
const entries = Object.entries(value);
|
|
9006
|
+
if (entries.length === 0) return "{}";
|
|
9007
|
+
const propertyIndent = `${baseIndent}${INDENT}`;
|
|
9008
|
+
return `{\n${entries.map(([key, propertyValue]) => {
|
|
9009
|
+
return `${propertyIndent}${JSON.stringify(key)}: ${formatStaticRouteType(propertyValue, propertyIndent)};`;
|
|
9010
|
+
}).join("\n")}\n${baseIndent}}`;
|
|
9011
|
+
}
|
|
9012
|
+
function formatNamedRouteMapEntries(routes) {
|
|
9013
|
+
const routeIndent = `${INDENT}${INDENT}`;
|
|
9014
|
+
const fieldIndent = `${routeIndent}${INDENT}`;
|
|
9015
|
+
return routes.map((route) => {
|
|
9016
|
+
return [
|
|
9017
|
+
`${routeIndent}${JSON.stringify(route.name)}: {`,
|
|
9018
|
+
`${fieldIndent}path: ${JSON.stringify(route.path)};`,
|
|
9019
|
+
`${fieldIndent}meta: ${formatStaticRouteType(route.meta, fieldIndent)};`,
|
|
9020
|
+
`${routeIndent}};`
|
|
9021
|
+
].join("\n");
|
|
9022
|
+
});
|
|
9023
|
+
}
|
|
9024
|
+
function createTypedRouterDefinition(routes, namedRoutes = []) {
|
|
8994
9025
|
const pagesType = formatTuple(routes.pages, INDENT);
|
|
8995
9026
|
const entriesType = formatTuple(routes.entries, INDENT);
|
|
8996
9027
|
const subPackagesType = formatSubPackagesTuple(routes.subPackages, INDENT);
|
|
9028
|
+
const namedRouteMapEntries = formatNamedRouteMapEntries(namedRoutes);
|
|
8997
9029
|
return [
|
|
8998
9030
|
"/* eslint-disable */",
|
|
8999
9031
|
"// biome-ignore lint: disable",
|
|
9000
9032
|
"// oxlint-disable",
|
|
9001
9033
|
"// ------",
|
|
9002
9034
|
"// 由 weapp-vite 自动生成,请勿编辑。",
|
|
9003
|
-
|
|
9035
|
+
`import '${WEVU_ROUTER_MODULE_ID}';`,
|
|
9004
9036
|
"",
|
|
9005
9037
|
"declare module 'weapp-vite/auto-routes' {",
|
|
9006
9038
|
` export type AutoRoutesPages = ${pagesType};`,
|
|
@@ -9036,10 +9068,13 @@ function createTypedRouterDefinition(routes) {
|
|
|
9036
9068
|
" export default routes;",
|
|
9037
9069
|
"}",
|
|
9038
9070
|
"",
|
|
9039
|
-
|
|
9071
|
+
`declare module '${WEVU_ROUTER_MODULE_ID}' {`,
|
|
9040
9072
|
" interface WevuTypedRouterRouteMap {",
|
|
9041
9073
|
" entries: import('weapp-vite/auto-routes').AutoRoutesEntries[number];",
|
|
9042
9074
|
" }",
|
|
9075
|
+
" interface WevuNamedRouteMap {",
|
|
9076
|
+
...namedRouteMapEntries,
|
|
9077
|
+
" }",
|
|
9043
9078
|
"}",
|
|
9044
9079
|
""
|
|
9045
9080
|
].join("\n");
|
|
@@ -9225,6 +9260,34 @@ function applyBuildScopeToAutoRoutes(routes, scope) {
|
|
|
9225
9260
|
};
|
|
9226
9261
|
}
|
|
9227
9262
|
//#endregion
|
|
9263
|
+
//#region src/runtime/config/internal/alias.ts
|
|
9264
|
+
function normalizeAliasOptions(alias) {
|
|
9265
|
+
if (!alias) return [];
|
|
9266
|
+
if (Array.isArray(alias)) return alias.filter((entry) => {
|
|
9267
|
+
return Boolean(entry && typeof entry === "object" && "find" in entry && "replacement" in entry);
|
|
9268
|
+
});
|
|
9269
|
+
return Object.entries(alias).map(([find, replacement]) => {
|
|
9270
|
+
return {
|
|
9271
|
+
find,
|
|
9272
|
+
replacement
|
|
9273
|
+
};
|
|
9274
|
+
});
|
|
9275
|
+
}
|
|
9276
|
+
function createAliasManager(oxcAlias, defaultBuiltinAliases) {
|
|
9277
|
+
function injectBuiltinAliases(config, builtinAliases = defaultBuiltinAliases) {
|
|
9278
|
+
const resolve = config.resolve ?? (config.resolve = {});
|
|
9279
|
+
const aliasArray = normalizeAliasOptions(resolve.alias);
|
|
9280
|
+
if (!aliasArray.some((entry) => {
|
|
9281
|
+
return entry.find instanceof RegExp && entry.find.source === oxcAlias.find.source;
|
|
9282
|
+
})) aliasArray.unshift(oxcAlias);
|
|
9283
|
+
for (const builtin of builtinAliases) if (!aliasArray.some((entry) => {
|
|
9284
|
+
return typeof entry.find === "string" && entry.find === builtin.find;
|
|
9285
|
+
})) aliasArray.unshift(builtin);
|
|
9286
|
+
resolve.alias = aliasArray;
|
|
9287
|
+
}
|
|
9288
|
+
return { injectBuiltinAliases };
|
|
9289
|
+
}
|
|
9290
|
+
//#endregion
|
|
9228
9291
|
//#region src/utils/miniProgramGlobals.ts
|
|
9229
9292
|
function getMiniProgramGlobalKeys() {
|
|
9230
9293
|
return [...getMiniProgramRuntimeGlobalKeysByResolvePriority()];
|
|
@@ -9261,6 +9324,13 @@ function updateWatchTargets(target, next) {
|
|
|
9261
9324
|
target.clear();
|
|
9262
9325
|
for (const item of next) target.add(item);
|
|
9263
9326
|
}
|
|
9327
|
+
function updatePageDeclarationDependencies(target, next) {
|
|
9328
|
+
target.clear();
|
|
9329
|
+
for (const [dependency, owners] of next) target.set(dependency, new Set(owners));
|
|
9330
|
+
}
|
|
9331
|
+
function createAutoRoutesSourceFingerprint(source) {
|
|
9332
|
+
return createHash("sha256").update(source).digest("hex");
|
|
9333
|
+
}
|
|
9264
9334
|
function createEmptyAutoRoutesSnapshot() {
|
|
9265
9335
|
return {
|
|
9266
9336
|
pages: [],
|
|
@@ -9305,21 +9375,39 @@ function createAutoRoutesModuleCode(serialized) {
|
|
|
9305
9375
|
...createAutoRoutesRuntimeLines()
|
|
9306
9376
|
].join("\n");
|
|
9307
9377
|
}
|
|
9308
|
-
function
|
|
9378
|
+
function createNamedAutoRoutesModuleCode(serialized) {
|
|
9379
|
+
return `export const routes = JSON.parse(${JSON.stringify(serialized)});\n`;
|
|
9380
|
+
}
|
|
9381
|
+
function createAutoRoutesArtifacts(snapshot, namedRoutes = []) {
|
|
9309
9382
|
const serialized = JSON.stringify(snapshot, null, 2);
|
|
9383
|
+
const namedRoutesSerialized = JSON.stringify(namedRoutes, null, 2);
|
|
9310
9384
|
return {
|
|
9311
9385
|
serialized,
|
|
9312
9386
|
moduleCode: createAutoRoutesModuleCode(serialized),
|
|
9313
|
-
|
|
9387
|
+
namedModuleCode: createNamedAutoRoutesModuleCode(namedRoutesSerialized),
|
|
9388
|
+
signature: JSON.stringify({
|
|
9389
|
+
routes: snapshot,
|
|
9390
|
+
namedRoutes
|
|
9391
|
+
}),
|
|
9392
|
+
typedDefinition: createTypedRouterDefinition(snapshot, namedRoutes)
|
|
9314
9393
|
};
|
|
9315
9394
|
}
|
|
9316
9395
|
function resetAutoRoutesState(state) {
|
|
9317
9396
|
const emptySnapshot = createEmptyAutoRoutesSnapshot();
|
|
9318
9397
|
const artifacts = createAutoRoutesArtifacts(emptySnapshot);
|
|
9319
9398
|
updateRoutesReference(state.routes, emptySnapshot);
|
|
9399
|
+
state.namedRoutes = [];
|
|
9320
9400
|
state.serialized = artifacts.serialized;
|
|
9321
9401
|
state.typedDefinition = artifacts.typedDefinition;
|
|
9322
9402
|
state.moduleCode = artifacts.moduleCode;
|
|
9403
|
+
state.namedModuleCode = artifacts.namedModuleCode;
|
|
9404
|
+
state.signature = artifacts.signature;
|
|
9405
|
+
state.topologyKey = "";
|
|
9406
|
+
state.pageDeclarationDependencies.clear();
|
|
9407
|
+
state.pageDeclarationFingerprints.clear();
|
|
9408
|
+
state.usesOpaquePageDeclarationResolver = false;
|
|
9409
|
+
updateWatchTargets(state.pageSourceFiles, /* @__PURE__ */ new Set());
|
|
9410
|
+
updateWatchTargets(state.namedRouteSourceFiles, /* @__PURE__ */ new Set());
|
|
9323
9411
|
updateWatchTargets(state.watchFiles, /* @__PURE__ */ new Set());
|
|
9324
9412
|
updateWatchTargets(state.watchDirs, /* @__PURE__ */ new Set());
|
|
9325
9413
|
state.dirty = false;
|
|
@@ -9335,24 +9423,38 @@ function resolvePersistentCacheBaseDir(configService) {
|
|
|
9335
9423
|
return (typeof configService.configFilePath === "string" ? path.dirname(configService.configFilePath) : configService.cwd) || void 0;
|
|
9336
9424
|
}
|
|
9337
9425
|
function applyPersistentCache(state, cache) {
|
|
9338
|
-
const
|
|
9426
|
+
const artifacts = createAutoRoutesArtifacts(cache.snapshot, cache.namedRoutes);
|
|
9339
9427
|
updateRoutesReference(state.routes, cache.snapshot);
|
|
9340
|
-
state.
|
|
9341
|
-
state.
|
|
9342
|
-
state.
|
|
9343
|
-
|
|
9344
|
-
|
|
9428
|
+
state.namedRoutes = cache.namedRoutes;
|
|
9429
|
+
state.serialized = artifacts.serialized;
|
|
9430
|
+
state.moduleCode = artifacts.moduleCode;
|
|
9431
|
+
state.namedModuleCode = artifacts.namedModuleCode;
|
|
9432
|
+
state.signature = `${artifacts.signature}\n${cache.topologyKey}`;
|
|
9433
|
+
state.typedDefinition = artifacts.typedDefinition;
|
|
9434
|
+
state.topologyKey = cache.topologyKey;
|
|
9435
|
+
updatePageDeclarationDependencies(state.pageDeclarationDependencies, new Map(Object.entries(cache.pageDeclarationDependencies).map(([dependency, owners]) => [dependency, new Set(owners)])));
|
|
9436
|
+
state.pageDeclarationFingerprints.clear();
|
|
9437
|
+
for (const [sourceFile, fingerprint] of Object.entries(cache.pageDeclarationFingerprints)) state.pageDeclarationFingerprints.set(sourceFile, fingerprint);
|
|
9438
|
+
state.usesOpaquePageDeclarationResolver = cache.usesOpaquePageDeclarationResolver;
|
|
9439
|
+
updateWatchTargets(state.pageSourceFiles, new Set(cache.pageSourceFiles));
|
|
9440
|
+
updateWatchTargets(state.namedRouteSourceFiles, new Set(cache.namedRouteSourceFiles));
|
|
9441
|
+
updateWatchTargets(state.watchFiles, new Set(cache.watchFiles));
|
|
9442
|
+
updateWatchTargets(state.watchDirs, new Set(cache.watchDirs));
|
|
9345
9443
|
state.dirty = false;
|
|
9346
9444
|
state.initialized = true;
|
|
9347
|
-
state.needsFullRescan =
|
|
9445
|
+
state.needsFullRescan = false;
|
|
9348
9446
|
}
|
|
9349
9447
|
function createPersistentCachePayload(state, fileMtims) {
|
|
9350
9448
|
return {
|
|
9351
|
-
version:
|
|
9449
|
+
version: 6,
|
|
9352
9450
|
snapshot: cloneRoutes(state.routes),
|
|
9353
|
-
|
|
9354
|
-
|
|
9355
|
-
|
|
9451
|
+
namedRoutes: state.namedRoutes,
|
|
9452
|
+
topologyKey: state.topologyKey,
|
|
9453
|
+
pageDeclarationDependencies: Object.fromEntries([...state.pageDeclarationDependencies].map(([dependency, owners]) => [dependency, [...owners]])),
|
|
9454
|
+
pageDeclarationFingerprints: Object.fromEntries(state.pageDeclarationFingerprints),
|
|
9455
|
+
usesOpaquePageDeclarationResolver: state.usesOpaquePageDeclarationResolver,
|
|
9456
|
+
pageSourceFiles: [...state.pageSourceFiles],
|
|
9457
|
+
namedRouteSourceFiles: [...state.namedRouteSourceFiles],
|
|
9356
9458
|
watchFiles: [...state.watchFiles],
|
|
9357
9459
|
watchDirs: [...state.watchDirs],
|
|
9358
9460
|
fileMtims
|
|
@@ -9460,6 +9562,7 @@ function isAutoRoutesCandidateUnchanged(previous, candidate) {
|
|
|
9460
9562
|
}
|
|
9461
9563
|
//#endregion
|
|
9462
9564
|
//#region src/runtime/autoRoutesPlugin/routes/scan.ts
|
|
9565
|
+
const PAGE_SOURCE_EXTENSIONS = [...scriptExtensions, ...vueExtensions];
|
|
9463
9566
|
function sortAutoRoutesEntries(values) {
|
|
9464
9567
|
values.sort((a, b) => {
|
|
9465
9568
|
if (a === "pages/index/index") return -1;
|
|
@@ -9488,7 +9591,136 @@ function shouldIncludeScanCandidate(candidate, json, route) {
|
|
|
9488
9591
|
}
|
|
9489
9592
|
return candidate.hasScript || candidate.hasTemplate || Boolean(candidate.jsonPath);
|
|
9490
9593
|
}
|
|
9491
|
-
|
|
9594
|
+
function resolvePageDeclarationAliases(ctx) {
|
|
9595
|
+
const configService = ctx.configService;
|
|
9596
|
+
if (!configService) return [];
|
|
9597
|
+
return [...normalizeAliasOptions(configService.inlineConfig?.resolve?.alias), ...configService.aliasEntries ?? []];
|
|
9598
|
+
}
|
|
9599
|
+
function resolveCandidatePageSources(ctx, candidate) {
|
|
9600
|
+
const sourceFiles = PAGE_SOURCE_EXTENSIONS.map((extension) => `${candidate.base}.${extension}`).filter((sourceFile) => candidate.files.has(sourceFile));
|
|
9601
|
+
const nativeSource = sourceFiles[0];
|
|
9602
|
+
if (!nativeSource) return [];
|
|
9603
|
+
if (ctx.configService?.weappWebConfig?.enabled !== true) return [nativeSource];
|
|
9604
|
+
return [nativeSource, ...sourceFiles.filter((sourceFile) => sourceFile !== nativeSource)];
|
|
9605
|
+
}
|
|
9606
|
+
async function collectNamedRoutes(ctx, candidates, scopedEntries, options) {
|
|
9607
|
+
const pageDeclarationAliases = resolvePageDeclarationAliases(ctx);
|
|
9608
|
+
const configService = ctx.configService;
|
|
9609
|
+
const scopedCandidates = candidates.filter((candidate) => scopedEntries.has(candidate.entry)).sort((a, b) => a.entry.localeCompare(b.entry));
|
|
9610
|
+
const sourceCache = /* @__PURE__ */ new Map();
|
|
9611
|
+
const readSource = (sourceFile) => {
|
|
9612
|
+
let pending = sourceCache.get(sourceFile);
|
|
9613
|
+
if (!pending) {
|
|
9614
|
+
pending = fs$1.readFile(sourceFile, "utf8");
|
|
9615
|
+
sourceCache.set(sourceFile, pending);
|
|
9616
|
+
}
|
|
9617
|
+
return pending;
|
|
9618
|
+
};
|
|
9619
|
+
const resolveSource = async (source, importer) => {
|
|
9620
|
+
const resolved = await options.resolvePageDeclarationSource?.(source, importer);
|
|
9621
|
+
if (resolved) return resolved;
|
|
9622
|
+
if (!importer) return;
|
|
9623
|
+
const aliased = resolveImportee$1(source, importer, pageDeclarationAliases);
|
|
9624
|
+
return aliased === source ? void 0 : aliased;
|
|
9625
|
+
};
|
|
9626
|
+
const declarations = await Promise.all(scopedCandidates.map(async ({ candidate, entry }) => {
|
|
9627
|
+
const sourceFiles = resolveCandidatePageSources(ctx, candidate);
|
|
9628
|
+
const sources = await Promise.all(sourceFiles.map(async (sourceFile) => {
|
|
9629
|
+
const source = await readSource(sourceFile);
|
|
9630
|
+
return {
|
|
9631
|
+
...await extractPageDeclarationWithDependencies(source, sourceFile, {
|
|
9632
|
+
readFile: readSource,
|
|
9633
|
+
resolveId: resolveSource
|
|
9634
|
+
}),
|
|
9635
|
+
sourceFile
|
|
9636
|
+
};
|
|
9637
|
+
}));
|
|
9638
|
+
const primary = sources[0];
|
|
9639
|
+
for (const alternate of sources.slice(1)) if (!isDeepStrictEqual(primary?.declaration, alternate.declaration)) {
|
|
9640
|
+
const first = toPosixPath(path.relative(configService.cwd, primary.sourceFile));
|
|
9641
|
+
const second = toPosixPath(path.relative(configService.cwd, alternate.sourceFile));
|
|
9642
|
+
throw new Error(`[auto-routes] 页面 ${entry} 的候选源文件页面声明不一致:${first} 与 ${second}`);
|
|
9643
|
+
}
|
|
9644
|
+
return {
|
|
9645
|
+
entry,
|
|
9646
|
+
primary,
|
|
9647
|
+
sources
|
|
9648
|
+
};
|
|
9649
|
+
}));
|
|
9650
|
+
const namedRoutes = [];
|
|
9651
|
+
const pageSourceFiles = /* @__PURE__ */ new Set();
|
|
9652
|
+
const namedRouteSourceFiles = /* @__PURE__ */ new Set();
|
|
9653
|
+
const pageDeclarationDependencies = /* @__PURE__ */ new Map();
|
|
9654
|
+
const sourceByName = /* @__PURE__ */ new Map();
|
|
9655
|
+
for (const { entry, primary, sources } of declarations) {
|
|
9656
|
+
for (const source of sources) {
|
|
9657
|
+
pageSourceFiles.add(source.sourceFile);
|
|
9658
|
+
for (const dependency of source.dependencies) {
|
|
9659
|
+
let owners = pageDeclarationDependencies.get(dependency);
|
|
9660
|
+
if (!owners) {
|
|
9661
|
+
owners = /* @__PURE__ */ new Set();
|
|
9662
|
+
pageDeclarationDependencies.set(dependency, owners);
|
|
9663
|
+
}
|
|
9664
|
+
owners.add(source.sourceFile);
|
|
9665
|
+
}
|
|
9666
|
+
}
|
|
9667
|
+
const declaration = primary?.declaration;
|
|
9668
|
+
if (!declaration || !primary) continue;
|
|
9669
|
+
const routeSourceFile = primary.declarationSourceFile ?? primary.sourceFile;
|
|
9670
|
+
const duplicateSource = sourceByName.get(declaration.name);
|
|
9671
|
+
if (duplicateSource) {
|
|
9672
|
+
const first = toPosixPath(path.relative(configService.cwd, duplicateSource));
|
|
9673
|
+
const second = toPosixPath(path.relative(configService.cwd, routeSourceFile));
|
|
9674
|
+
throw new Error(`[auto-routes] 页面路由名称 ${JSON.stringify(declaration.name)} 重复:${first} 与 ${second}`);
|
|
9675
|
+
}
|
|
9676
|
+
sourceByName.set(declaration.name, routeSourceFile);
|
|
9677
|
+
for (const source of sources) namedRouteSourceFiles.add(source.sourceFile);
|
|
9678
|
+
namedRoutes.push({
|
|
9679
|
+
name: declaration.name,
|
|
9680
|
+
path: `/${entry}`,
|
|
9681
|
+
meta: declaration.meta ?? {}
|
|
9682
|
+
});
|
|
9683
|
+
}
|
|
9684
|
+
const pageDeclarationFingerprints = /* @__PURE__ */ new Map();
|
|
9685
|
+
await Promise.all([...sourceCache].map(async ([sourceFile, pendingSource]) => {
|
|
9686
|
+
pageDeclarationFingerprints.set(sourceFile, createAutoRoutesSourceFingerprint(await pendingSource));
|
|
9687
|
+
}));
|
|
9688
|
+
return {
|
|
9689
|
+
namedRoutes,
|
|
9690
|
+
namedRouteSourceFiles,
|
|
9691
|
+
pageDeclarationDependencies,
|
|
9692
|
+
pageDeclarationFingerprints,
|
|
9693
|
+
pageSourceFiles
|
|
9694
|
+
};
|
|
9695
|
+
}
|
|
9696
|
+
function createAutoRoutesTopologyKey(ctx, candidatesMap) {
|
|
9697
|
+
const configService = ctx.configService;
|
|
9698
|
+
if (!configService) return "";
|
|
9699
|
+
const candidates = [...candidatesMap.values()].map((candidate) => ({
|
|
9700
|
+
base: toPosixPath(path.relative(configService.absoluteSrcRoot, candidate.base)),
|
|
9701
|
+
files: [...candidate.files].map((filePath) => toPosixPath(path.relative(configService.absoluteSrcRoot, filePath))).sort((a, b) => a.localeCompare(b))
|
|
9702
|
+
})).sort((a, b) => a.base.localeCompare(b.base));
|
|
9703
|
+
const { subPackageRoots } = resolveAutoRoutesMatcherContext(ctx);
|
|
9704
|
+
const pageDeclarationAliases = resolvePageDeclarationAliases(ctx).map((alias) => ({
|
|
9705
|
+
find: typeof alias.find === "string" ? {
|
|
9706
|
+
kind: "string",
|
|
9707
|
+
value: alias.find
|
|
9708
|
+
} : {
|
|
9709
|
+
flags: alias.find.flags,
|
|
9710
|
+
kind: "regexp",
|
|
9711
|
+
value: alias.find.source
|
|
9712
|
+
},
|
|
9713
|
+
replacement: alias.replacement
|
|
9714
|
+
}));
|
|
9715
|
+
return JSON.stringify({
|
|
9716
|
+
buildScope: resolveBuildScope(configService.weappViteConfig.buildScope),
|
|
9717
|
+
webSiblingValidation: configService.weappWebConfig?.enabled === true,
|
|
9718
|
+
pageDeclarationAliases,
|
|
9719
|
+
candidates,
|
|
9720
|
+
subPackageRoots: [...subPackageRoots].sort((a, b) => a.localeCompare(b))
|
|
9721
|
+
});
|
|
9722
|
+
}
|
|
9723
|
+
async function scanRoutes(ctx, candidatesMap, options = {}) {
|
|
9492
9724
|
const configService = ctx.configService;
|
|
9493
9725
|
const jsonService = ctx.jsonService;
|
|
9494
9726
|
if (!configService || !jsonService) throw new Error("扫描路由前必须初始化 configService/jsonService。");
|
|
@@ -9499,7 +9731,12 @@ async function scanRoutes(ctx, candidatesMap) {
|
|
|
9499
9731
|
const subPackages = /* @__PURE__ */ new Map();
|
|
9500
9732
|
const watchFiles = /* @__PURE__ */ new Set();
|
|
9501
9733
|
const watchDirs = /* @__PURE__ */ new Set();
|
|
9502
|
-
const
|
|
9734
|
+
const includedCandidates = [];
|
|
9735
|
+
const candidatesSnapshot = new Map([...candidatesMap].map(([base, candidate]) => [base, {
|
|
9736
|
+
...candidate,
|
|
9737
|
+
files: new Set(candidate.files)
|
|
9738
|
+
}]));
|
|
9739
|
+
const candidateList = [...candidatesSnapshot.values()];
|
|
9503
9740
|
const jsonEntries = await Promise.all(candidateList.map(async (candidate) => {
|
|
9504
9741
|
if (!candidate.jsonPath) return {
|
|
9505
9742
|
candidate,
|
|
@@ -9523,6 +9760,10 @@ async function scanRoutes(ctx, candidatesMap) {
|
|
|
9523
9760
|
entriesSet.add(route.entry);
|
|
9524
9761
|
if (route.root) ensureSubPackage(subPackages, route.root).add(route.pagePath);
|
|
9525
9762
|
else pagesSet.add(route.pagePath);
|
|
9763
|
+
includedCandidates.push({
|
|
9764
|
+
candidate,
|
|
9765
|
+
entry: route.entry
|
|
9766
|
+
});
|
|
9526
9767
|
}
|
|
9527
9768
|
for (const dir of matcher.getWatchRoots(absoluteSrcRoot)) watchDirs.add(dir);
|
|
9528
9769
|
const pages = [...pagesSet];
|
|
@@ -9543,12 +9784,27 @@ async function scanRoutes(ctx, candidatesMap) {
|
|
|
9543
9784
|
entries,
|
|
9544
9785
|
subPackages: subPackageList
|
|
9545
9786
|
}, resolveBuildScope(configService.weappViteConfig.buildScope));
|
|
9546
|
-
const {
|
|
9787
|
+
const { namedRoutes, namedRouteSourceFiles, pageDeclarationDependencies, pageDeclarationFingerprints, pageSourceFiles } = await collectNamedRoutes(ctx, includedCandidates, new Set(snapshot.entries), options);
|
|
9788
|
+
for (const dependency of pageDeclarationDependencies.keys()) {
|
|
9789
|
+
watchFiles.add(dependency);
|
|
9790
|
+
watchDirs.add(path.dirname(dependency));
|
|
9791
|
+
}
|
|
9792
|
+
const { serialized, moduleCode, namedModuleCode, signature: routeSignature, typedDefinition } = createAutoRoutesArtifacts(snapshot, namedRoutes);
|
|
9793
|
+
const topologyKey = createAutoRoutesTopologyKey(ctx, candidatesSnapshot);
|
|
9547
9794
|
return {
|
|
9548
9795
|
snapshot,
|
|
9796
|
+
namedRoutes,
|
|
9549
9797
|
serialized,
|
|
9550
9798
|
moduleCode,
|
|
9799
|
+
namedModuleCode,
|
|
9800
|
+
signature: `${routeSignature}\n${topologyKey}`,
|
|
9551
9801
|
typedDefinition,
|
|
9802
|
+
topologyKey,
|
|
9803
|
+
namedRouteSourceFiles,
|
|
9804
|
+
pageDeclarationDependencies,
|
|
9805
|
+
pageDeclarationFingerprints,
|
|
9806
|
+
usesOpaquePageDeclarationResolver: Boolean(options.resolvePageDeclarationSource && pageDeclarationDependencies.size > 0),
|
|
9807
|
+
pageSourceFiles,
|
|
9552
9808
|
watchFiles,
|
|
9553
9809
|
watchDirs
|
|
9554
9810
|
};
|
|
@@ -9591,6 +9847,24 @@ function cloneRoutes(routes) {
|
|
|
9591
9847
|
function getResolvedConfig(ctx) {
|
|
9592
9848
|
return resolveWeappAutoRoutesConfig(ctx.configService?.weappViteConfig?.autoRoutes);
|
|
9593
9849
|
}
|
|
9850
|
+
function isStringArray(value) {
|
|
9851
|
+
return Array.isArray(value) && value.every((item) => typeof item === "string");
|
|
9852
|
+
}
|
|
9853
|
+
function isStringArrayRecord(value) {
|
|
9854
|
+
return isObject(value) && !Array.isArray(value) && Object.values(value).every(isStringArray);
|
|
9855
|
+
}
|
|
9856
|
+
function isStringRecord(value) {
|
|
9857
|
+
return isObject(value) && !Array.isArray(value) && Object.values(value).every((item) => typeof item === "string");
|
|
9858
|
+
}
|
|
9859
|
+
function isPersistentCache(value, topologyKey) {
|
|
9860
|
+
if (!isObject(value) || Array.isArray(value) || !isObject(value.snapshot) || Array.isArray(value.snapshot) || !isObject(value.fileMtims) || Array.isArray(value.fileMtims) || !isStringArrayRecord(value.pageDeclarationDependencies) || !isStringRecord(value.pageDeclarationFingerprints)) return false;
|
|
9861
|
+
const subPackages = value.snapshot.subPackages;
|
|
9862
|
+
const namedRoutes = value.namedRoutes;
|
|
9863
|
+
const pageSourceFiles = value.pageSourceFiles;
|
|
9864
|
+
const dependencyEntries = Object.entries(value.pageDeclarationDependencies);
|
|
9865
|
+
const fingerprints = value.pageDeclarationFingerprints;
|
|
9866
|
+
return value.version === 6 && value.topologyKey === topologyKey && typeof value.usesOpaquePageDeclarationResolver === "boolean" && isStringArray(value.snapshot.pages) && isStringArray(value.snapshot.entries) && Array.isArray(subPackages) && subPackages.every((pkg) => isObject(pkg) && !Array.isArray(pkg) && typeof pkg.root === "string" && isStringArray(pkg.pages)) && Array.isArray(namedRoutes) && namedRoutes.every((route) => isObject(route) && !Array.isArray(route) && typeof route.name === "string" && typeof route.path === "string" && isObject(route.meta) && !Array.isArray(route.meta)) && isStringArray(pageSourceFiles) && isStringArray(value.namedRouteSourceFiles) && isStringArray(value.watchFiles) && isStringArray(value.watchDirs) && dependencyEntries.every(([, owners]) => isStringArray(owners)) && Object.values(fingerprints).every((fingerprint) => typeof fingerprint === "string") && pageSourceFiles.every((sourceFile) => Object.hasOwn(fingerprints, sourceFile)) && dependencyEntries.every(([dependency, owners]) => Object.hasOwn(fingerprints, dependency) && owners.every((owner) => pageSourceFiles.includes(owner))) && Object.values(value.fileMtims).every((mtime) => typeof mtime === "number" && Number.isFinite(mtime));
|
|
9867
|
+
}
|
|
9594
9868
|
function resolvePersistentCachePath(ctx) {
|
|
9595
9869
|
const autoRoutesConfig = getResolvedConfig(ctx);
|
|
9596
9870
|
if (!autoRoutesConfig.persistentCache) return;
|
|
@@ -9629,22 +9903,26 @@ async function collectWatchFileMtims(watchFiles) {
|
|
|
9629
9903
|
}));
|
|
9630
9904
|
return Object.fromEntries(entries);
|
|
9631
9905
|
}
|
|
9632
|
-
async function restorePersistentCache(ctx, state) {
|
|
9906
|
+
async function restorePersistentCache(ctx, state, topologyKey, isCurrent = () => true, hasOpaquePageDeclarationSourceResolver = false) {
|
|
9633
9907
|
if (!getResolvedConfig(ctx).persistentCache) return false;
|
|
9634
9908
|
const cachePath = resolvePersistentCachePath(ctx);
|
|
9635
9909
|
if (!cachePath || !await fs$1.pathExists(cachePath)) return false;
|
|
9636
9910
|
try {
|
|
9637
|
-
const
|
|
9638
|
-
if (
|
|
9639
|
-
const
|
|
9911
|
+
const cached = await fs$1.readJson(cachePath);
|
|
9912
|
+
if (!isPersistentCache(cached, topologyKey)) return false;
|
|
9913
|
+
const cache = cached;
|
|
9914
|
+
if (Object.keys(cache.pageDeclarationDependencies).length > 0 && (cache.usesOpaquePageDeclarationResolver || hasOpaquePageDeclarationSourceResolver)) return false;
|
|
9915
|
+
const watchFiles = cache.watchFiles;
|
|
9640
9916
|
if (watchFiles.length === 0) return false;
|
|
9641
9917
|
const cachedMtims = cache.fileMtims;
|
|
9642
|
-
if (!cachedMtims) return false;
|
|
9643
9918
|
const fileMtims = await collectWatchFileMtims(watchFiles);
|
|
9644
9919
|
for (const filePath of watchFiles) {
|
|
9645
9920
|
const expectedMtime = cachedMtims[filePath];
|
|
9646
9921
|
if (typeof expectedMtime !== "number" || !Number.isFinite(expectedMtime) || fileMtims[filePath] !== expectedMtime) return false;
|
|
9647
9922
|
}
|
|
9923
|
+
if ((await Promise.all(Object.entries(cache.pageDeclarationFingerprints).map(async ([sourceFile, expectedFingerprint]) => {
|
|
9924
|
+
return [expectedFingerprint, createAutoRoutesSourceFingerprint(await fs$1.readFile(sourceFile, "utf8"))];
|
|
9925
|
+
}))).some(([expected, current]) => expected !== current) || !isCurrent()) return false;
|
|
9648
9926
|
applyPersistentCache(state, cache);
|
|
9649
9927
|
return true;
|
|
9650
9928
|
} catch {
|
|
@@ -9654,14 +9932,13 @@ async function restorePersistentCache(ctx, state) {
|
|
|
9654
9932
|
async function writePersistentCache(ctx, state) {
|
|
9655
9933
|
const cachePath = resolvePersistentCachePath(ctx);
|
|
9656
9934
|
if (!cachePath || !state.initialized || !getResolvedConfig(ctx).persistentCache) return;
|
|
9657
|
-
|
|
9935
|
+
const payload = createPersistentCachePayload(state, {});
|
|
9658
9936
|
try {
|
|
9659
|
-
fileMtims = await collectWatchFileMtims(
|
|
9937
|
+
payload.fileMtims = await collectWatchFileMtims(payload.watchFiles);
|
|
9660
9938
|
} catch {
|
|
9661
9939
|
return;
|
|
9662
9940
|
}
|
|
9663
9941
|
try {
|
|
9664
|
-
const payload = createPersistentCachePayload(state, fileMtims);
|
|
9665
9942
|
if (await hasSamePersistentCachePayload(cachePath, payload)) return;
|
|
9666
9943
|
await fs$1.outputJson(cachePath, payload, { spaces: 2 });
|
|
9667
9944
|
} catch (error) {
|
|
@@ -9813,7 +10090,9 @@ async function updateCandidateFromFile(ctx, stateCandidates, filePath, event, ma
|
|
|
9813
10090
|
function createAutoRoutesService(ctx) {
|
|
9814
10091
|
const state = ctx.runtimeState.autoRoutes;
|
|
9815
10092
|
let pendingScan;
|
|
10093
|
+
let pendingRefresh;
|
|
9816
10094
|
let lastWrittenTypedDefinition;
|
|
10095
|
+
let resolvePageDeclarationSource;
|
|
9817
10096
|
let mutationVersion = 0;
|
|
9818
10097
|
function flagDirty() {
|
|
9819
10098
|
mutationVersion += 1;
|
|
@@ -9836,6 +10115,22 @@ function createAutoRoutesService(ctx) {
|
|
|
9836
10115
|
function markNeedsFullRescan() {
|
|
9837
10116
|
state.needsFullRescan = true;
|
|
9838
10117
|
}
|
|
10118
|
+
async function mayChangePageDeclaration(sourcePath) {
|
|
10119
|
+
if (!state.pageSourceFiles.has(sourcePath)) return false;
|
|
10120
|
+
if (state.namedRouteSourceFiles.has(sourcePath)) return true;
|
|
10121
|
+
try {
|
|
10122
|
+
const source = await fs$1.readFile(sourcePath, "utf8");
|
|
10123
|
+
return mayContainPageDeclaration(source);
|
|
10124
|
+
} catch {
|
|
10125
|
+
return true;
|
|
10126
|
+
}
|
|
10127
|
+
}
|
|
10128
|
+
function getPageDeclarationOwners(filePath) {
|
|
10129
|
+
const sourcePath = normalizeFsResolvedId(filePath);
|
|
10130
|
+
const dependencyOwners = state.pageDeclarationDependencies.get(sourcePath);
|
|
10131
|
+
if (dependencyOwners) return [...dependencyOwners];
|
|
10132
|
+
return state.pageSourceFiles.has(sourcePath) ? [sourcePath] : [];
|
|
10133
|
+
}
|
|
9839
10134
|
async function ensureCandidateRegistry() {
|
|
9840
10135
|
const configService = requireConfigService(ctx, "扫描路由前必须初始化 configService。");
|
|
9841
10136
|
if (!isEnabled()) {
|
|
@@ -9857,46 +10152,76 @@ function createAutoRoutesService(ctx) {
|
|
|
9857
10152
|
state.needsFullRescan = false;
|
|
9858
10153
|
return true;
|
|
9859
10154
|
}
|
|
9860
|
-
async function
|
|
10155
|
+
async function refresh() {
|
|
9861
10156
|
if (!isEnabled()) {
|
|
9862
|
-
if (state.dirty || !state.initialized || state.routes.pages.length > 0 || state.routes.entries.length > 0 || state.routes.subPackages.length > 0) resetState();
|
|
10157
|
+
if (state.dirty || !state.initialized || state.routes.pages.length > 0 || state.routes.entries.length > 0 || state.routes.subPackages.length > 0 || state.namedRoutes.length > 0) resetState();
|
|
9863
10158
|
if (await removeTypedRouterDefinition(ctx)) lastWrittenTypedDefinition = void 0;
|
|
9864
10159
|
await removePersistentCache(ctx);
|
|
9865
10160
|
return;
|
|
9866
10161
|
}
|
|
9867
10162
|
if (!getResolvedConfig().persistentCache) await removePersistentCache(ctx);
|
|
10163
|
+
let registryUpdated = false;
|
|
9868
10164
|
if (!state.initialized && state.needsFullRescan) {
|
|
9869
|
-
|
|
10165
|
+
registryUpdated = await ensureCandidateRegistry();
|
|
10166
|
+
const topologyKey = createAutoRoutesTopologyKey(ctx, state.candidates);
|
|
10167
|
+
const restoreVersion = mutationVersion;
|
|
10168
|
+
const isRestoreCurrent = () => {
|
|
10169
|
+
return mutationVersion === restoreVersion && topologyKey === createAutoRoutesTopologyKey(ctx, state.candidates);
|
|
10170
|
+
};
|
|
10171
|
+
if (await restorePersistentCache(ctx, state, topologyKey, isRestoreCurrent, Boolean(resolvePageDeclarationSource)) && isRestoreCurrent()) {
|
|
9870
10172
|
lastWrittenTypedDefinition = await writeTypedRouterDefinition(ctx, state.typedDefinition, lastWrittenTypedDefinition);
|
|
9871
|
-
return;
|
|
10173
|
+
if (isRestoreCurrent()) return;
|
|
9872
10174
|
}
|
|
9873
10175
|
}
|
|
9874
|
-
if (await ensureCandidateRegistry()
|
|
10176
|
+
if (!registryUpdated) registryUpdated = await ensureCandidateRegistry();
|
|
10177
|
+
if (registryUpdated) flagDirty();
|
|
9875
10178
|
if (!state.dirty) {
|
|
9876
10179
|
await (pendingScan ?? Promise.resolve());
|
|
9877
|
-
lastWrittenTypedDefinition = await writeTypedRouterDefinition(ctx, state.typedDefinition, lastWrittenTypedDefinition);
|
|
10180
|
+
if (!state.dirty) lastWrittenTypedDefinition = await writeTypedRouterDefinition(ctx, state.typedDefinition, lastWrittenTypedDefinition);
|
|
9878
10181
|
return;
|
|
9879
10182
|
}
|
|
9880
10183
|
while (state.dirty) {
|
|
9881
10184
|
if (!pendingScan) {
|
|
9882
10185
|
const versionSnapshot = mutationVersion;
|
|
9883
|
-
pendingScan = scanRoutes(ctx, state.candidates).then((result) => {
|
|
10186
|
+
pendingScan = scanRoutes(ctx, state.candidates, { resolvePageDeclarationSource }).then((result) => {
|
|
10187
|
+
if (mutationVersion !== versionSnapshot) return;
|
|
9884
10188
|
updateRoutesReference(state.routes, result.snapshot);
|
|
10189
|
+
state.namedRoutes = result.namedRoutes;
|
|
9885
10190
|
state.serialized = result.serialized;
|
|
9886
10191
|
state.moduleCode = result.moduleCode;
|
|
10192
|
+
state.namedModuleCode = result.namedModuleCode;
|
|
10193
|
+
state.signature = result.signature;
|
|
9887
10194
|
state.typedDefinition = result.typedDefinition;
|
|
10195
|
+
state.topologyKey = result.topologyKey;
|
|
10196
|
+
updatePageDeclarationDependencies(state.pageDeclarationDependencies, result.pageDeclarationDependencies);
|
|
10197
|
+
state.pageDeclarationFingerprints.clear();
|
|
10198
|
+
for (const [sourceFile, fingerprint] of result.pageDeclarationFingerprints) state.pageDeclarationFingerprints.set(sourceFile, fingerprint);
|
|
10199
|
+
state.usesOpaquePageDeclarationResolver = result.usesOpaquePageDeclarationResolver;
|
|
10200
|
+
updateWatchTargets(state.pageSourceFiles, result.pageSourceFiles);
|
|
10201
|
+
updateWatchTargets(state.namedRouteSourceFiles, result.namedRouteSourceFiles);
|
|
9888
10202
|
updateWatchTargets(state.watchFiles, result.watchFiles);
|
|
9889
10203
|
updateWatchTargets(state.watchDirs, result.watchDirs);
|
|
9890
|
-
|
|
10204
|
+
state.dirty = false;
|
|
9891
10205
|
state.initialized = true;
|
|
10206
|
+
}).catch((error) => {
|
|
10207
|
+
if (mutationVersion === versionSnapshot) throw error;
|
|
9892
10208
|
}).finally(() => {
|
|
9893
10209
|
pendingScan = void 0;
|
|
9894
10210
|
});
|
|
9895
10211
|
}
|
|
9896
10212
|
await pendingScan;
|
|
9897
|
-
lastWrittenTypedDefinition = await writeTypedRouterDefinition(ctx, state.typedDefinition, lastWrittenTypedDefinition);
|
|
9898
|
-
await writePersistentCache(ctx, state);
|
|
9899
10213
|
}
|
|
10214
|
+
const publicationVersion = mutationVersion;
|
|
10215
|
+
if (!state.dirty) lastWrittenTypedDefinition = await writeTypedRouterDefinition(ctx, state.typedDefinition, lastWrittenTypedDefinition);
|
|
10216
|
+
if (!state.dirty && mutationVersion === publicationVersion) await writePersistentCache(ctx, state);
|
|
10217
|
+
}
|
|
10218
|
+
async function ensureFresh() {
|
|
10219
|
+
do {
|
|
10220
|
+
pendingRefresh ??= refresh().finally(() => {
|
|
10221
|
+
pendingRefresh = void 0;
|
|
10222
|
+
});
|
|
10223
|
+
await pendingRefresh;
|
|
10224
|
+
} while (state.dirty);
|
|
9900
10225
|
}
|
|
9901
10226
|
return {
|
|
9902
10227
|
async ensureFresh() {
|
|
@@ -9913,24 +10238,46 @@ function createAutoRoutesService(ctx) {
|
|
|
9913
10238
|
return state.routes;
|
|
9914
10239
|
},
|
|
9915
10240
|
getSignature() {
|
|
9916
|
-
return state.
|
|
10241
|
+
return state.signature;
|
|
9917
10242
|
},
|
|
9918
10243
|
getModuleCode() {
|
|
9919
10244
|
return state.moduleCode;
|
|
9920
10245
|
},
|
|
10246
|
+
getNamedModuleCode() {
|
|
10247
|
+
return state.namedModuleCode;
|
|
10248
|
+
},
|
|
9921
10249
|
getWatchFiles() {
|
|
9922
10250
|
return state.watchFiles.values();
|
|
9923
10251
|
},
|
|
9924
10252
|
getWatchDirectories() {
|
|
9925
10253
|
return state.watchDirs.values();
|
|
9926
10254
|
},
|
|
10255
|
+
getPageDeclarationOwners(filePath) {
|
|
10256
|
+
return isEnabled() ? getPageDeclarationOwners(filePath) : [];
|
|
10257
|
+
},
|
|
9927
10258
|
isRouteFile(filePath) {
|
|
9928
|
-
return isEnabled() && matchesRouteFile(ctx, filePath);
|
|
10259
|
+
return isEnabled() && (getPageDeclarationOwners(filePath).length > 0 || matchesRouteFile(ctx, filePath));
|
|
10260
|
+
},
|
|
10261
|
+
isPageSource(filePath) {
|
|
10262
|
+
const sourcePath = normalizeFsResolvedId(filePath);
|
|
10263
|
+
return isEnabled() && state.pageSourceFiles.has(sourcePath);
|
|
10264
|
+
},
|
|
10265
|
+
isPageDeclarationSource(filePath) {
|
|
10266
|
+
return isEnabled() && getPageDeclarationOwners(filePath).length > 0;
|
|
10267
|
+
},
|
|
10268
|
+
setPageDeclarationSourceResolver(resolve) {
|
|
10269
|
+
resolvePageDeclarationSource = resolve;
|
|
9929
10270
|
},
|
|
9930
10271
|
async handleFileChange(filePath, event) {
|
|
9931
10272
|
if (!isEnabled()) return false;
|
|
10273
|
+
const sourcePath = normalizeFsResolvedId(filePath);
|
|
10274
|
+
if (state.pageDeclarationDependencies.has(sourcePath)) {
|
|
10275
|
+
flagDirty();
|
|
10276
|
+
await ensureFresh();
|
|
10277
|
+
return true;
|
|
10278
|
+
}
|
|
9932
10279
|
if (!matchesRouteFile(ctx, filePath)) return false;
|
|
9933
|
-
if (!await updateCandidateFromFile(ctx, state.candidates, filePath, event, markNeedsFullRescan) && !state.needsFullRescan) return false;
|
|
10280
|
+
if (!await updateCandidateFromFile(ctx, state.candidates, filePath, event, markNeedsFullRescan) && !state.needsFullRescan && !state.dirty && !await mayChangePageDeclaration(sourcePath)) return false;
|
|
9934
10281
|
flagDirty();
|
|
9935
10282
|
await ensureFresh();
|
|
9936
10283
|
return true;
|
|
@@ -9944,12 +10291,162 @@ function createAutoRoutesService(ctx) {
|
|
|
9944
10291
|
};
|
|
9945
10292
|
}
|
|
9946
10293
|
//#endregion
|
|
10294
|
+
//#region src/runtime/autoRoutesPlugin/service/resolver.ts
|
|
10295
|
+
function createDefaultPageDeclarationSourceResolver(ctx) {
|
|
10296
|
+
let currentConfig;
|
|
10297
|
+
let pendingResolver;
|
|
10298
|
+
return async (source, importer) => {
|
|
10299
|
+
const configService = ctx.configService;
|
|
10300
|
+
if (!configService) return;
|
|
10301
|
+
if (!pendingResolver || currentConfig !== configService.inlineConfig) {
|
|
10302
|
+
currentConfig = configService.inlineConfig;
|
|
10303
|
+
pendingResolver = resolveConfig({
|
|
10304
|
+
root: configService.cwd,
|
|
10305
|
+
configFile: false,
|
|
10306
|
+
mode: configService.mode,
|
|
10307
|
+
resolve: currentConfig?.resolve,
|
|
10308
|
+
environments: currentConfig?.environments
|
|
10309
|
+
}, configService.isDev ? "serve" : "build", configService.mode, configService.isDev ? "development" : "production").then((config) => {
|
|
10310
|
+
const environment = new BuildEnvironment("client", config);
|
|
10311
|
+
const resolveId = createIdResolver(config);
|
|
10312
|
+
return (id, importer) => resolveId(environment, id, importer);
|
|
10313
|
+
});
|
|
10314
|
+
}
|
|
10315
|
+
return await (await pendingResolver)(source, importer);
|
|
10316
|
+
};
|
|
10317
|
+
}
|
|
10318
|
+
//#endregion
|
|
9947
10319
|
//#region src/runtime/autoRoutesPlugin/index.ts
|
|
9948
10320
|
function createAutoRoutesServicePlugin(ctx) {
|
|
9949
|
-
|
|
10321
|
+
const service = createAutoRoutesService(ctx);
|
|
10322
|
+
service.setPageDeclarationSourceResolver(createDefaultPageDeclarationSourceResolver(ctx));
|
|
10323
|
+
ctx.autoRoutesService = service;
|
|
9950
10324
|
return { name: "weapp-runtime:auto-routes-service" };
|
|
9951
10325
|
}
|
|
9952
10326
|
//#endregion
|
|
10327
|
+
//#region src/plugins/autoRoutes.shared.ts
|
|
10328
|
+
const AUTO_ROUTES_ID$1 = "weapp-vite/auto-routes";
|
|
10329
|
+
const VIRTUAL_MODULE_ID = "virtual:weapp-vite-auto-routes";
|
|
10330
|
+
const RESOLVED_VIRTUAL_ID = "\0weapp-vite:auto-routes";
|
|
10331
|
+
/**
|
|
10332
|
+
* 判断当前是否应按 watch 模式为 auto-routes 注册依赖文件。
|
|
10333
|
+
*/
|
|
10334
|
+
function isAutoRoutesWatchMode(configService) {
|
|
10335
|
+
return Boolean(configService?.isDev || configService?.inlineConfig?.build?.watch);
|
|
10336
|
+
}
|
|
10337
|
+
/**
|
|
10338
|
+
* 合并 service 与 matcher 提供的监听目录,并去重保留顺序。
|
|
10339
|
+
*/
|
|
10340
|
+
function collectAutoRoutesWatchDirs(watchDirectories, matcherWatchRoots) {
|
|
10341
|
+
const watchDirs = /* @__PURE__ */ new Set();
|
|
10342
|
+
for (const dir of watchDirectories) watchDirs.add(dir);
|
|
10343
|
+
for (const dir of matcherWatchRoots) watchDirs.add(dir);
|
|
10344
|
+
return [...watchDirs];
|
|
10345
|
+
}
|
|
10346
|
+
/**
|
|
10347
|
+
* 过滤出真正需要交给 auto-routes watcher 处理的路由源文件。
|
|
10348
|
+
* 已知声明依赖不受普通页面发现扩展名限制,其他文件仍沿用发现规则。
|
|
10349
|
+
*/
|
|
10350
|
+
function isAutoRoutesWatchFile(filePath, allowedExtensions, isPagesRelatedPath, isPageDeclarationSource) {
|
|
10351
|
+
if (isAutoRoutesGeneratedFileName(path.basename(filePath))) return false;
|
|
10352
|
+
if (isPageDeclarationSource(filePath)) return true;
|
|
10353
|
+
return allowedExtensions.has(path.extname(filePath)) && isPagesRelatedPath(filePath);
|
|
10354
|
+
}
|
|
10355
|
+
/**
|
|
10356
|
+
* 判断是否满足 auto-routes sidecar watcher 的启动前置条件。
|
|
10357
|
+
*/
|
|
10358
|
+
function shouldStartAutoRoutesWatcher(options) {
|
|
10359
|
+
if (options.routeWatcherStarted) return false;
|
|
10360
|
+
if (!options.isDev) return false;
|
|
10361
|
+
if (!options.autoRoutesEnabled || !options.autoRoutesWatch || !options.serviceEnabled) return false;
|
|
10362
|
+
return options.watchDirsLength > 0;
|
|
10363
|
+
}
|
|
10364
|
+
/**
|
|
10365
|
+
* 生成 sidecar watcher map 使用的关闭句柄。
|
|
10366
|
+
*/
|
|
10367
|
+
function createAutoRoutesSidecarWatcher(watcher) {
|
|
10368
|
+
return { close: async () => {
|
|
10369
|
+
await watcher.close();
|
|
10370
|
+
} };
|
|
10371
|
+
}
|
|
10372
|
+
/**
|
|
10373
|
+
* 向插件上下文注册 auto-routes 相关 watch 目标,忽略单个 addWatchFile 失败。
|
|
10374
|
+
*/
|
|
10375
|
+
function addAutoRoutesWatchTargets(pluginCtx, targets) {
|
|
10376
|
+
for (const file of targets.files) try {
|
|
10377
|
+
pluginCtx.addWatchFile?.(normalizeWatchPath(file));
|
|
10378
|
+
} catch {}
|
|
10379
|
+
for (const dir of targets.directories) try {
|
|
10380
|
+
pluginCtx.addWatchFile?.(normalizeWatchPath(dir));
|
|
10381
|
+
} catch {}
|
|
10382
|
+
}
|
|
10383
|
+
function invalidateAutoRoutesVirtualModules(server, resolvedIds) {
|
|
10384
|
+
if (!server) return;
|
|
10385
|
+
const seen = /* @__PURE__ */ new Set();
|
|
10386
|
+
const invalidateModuleWithImporters = (module) => {
|
|
10387
|
+
if (seen.has(module)) return;
|
|
10388
|
+
seen.add(module);
|
|
10389
|
+
server.moduleGraph.invalidateModule(module);
|
|
10390
|
+
for (const importer of module.importers) invalidateModuleWithImporters(importer);
|
|
10391
|
+
};
|
|
10392
|
+
for (const id of resolvedIds) {
|
|
10393
|
+
const virtualModule = server.moduleGraph.getModuleById(id);
|
|
10394
|
+
if (virtualModule) invalidateModuleWithImporters(virtualModule);
|
|
10395
|
+
}
|
|
10396
|
+
}
|
|
10397
|
+
/**
|
|
10398
|
+
* 统一解析 auto-routes 虚拟模块与 alias 入口的命中关系。
|
|
10399
|
+
*/
|
|
10400
|
+
function resolveAutoRoutesVirtualId(id, aliasTargets) {
|
|
10401
|
+
if (id === WEVU_AUTO_ROUTES_MODULE_ID$1 || id === WEVU_AUTO_ROUTES_VIRTUAL_MODULE_ID$1 || id === WEVU_AUTO_ROUTES_RESOLVED_MODULE_ID$1) return WEVU_AUTO_ROUTES_RESOLVED_MODULE_ID$1;
|
|
10402
|
+
if (id === "weapp-vite/auto-routes" || id === "virtual:weapp-vite-auto-routes" || id === "\0weapp-vite:auto-routes") return RESOLVED_VIRTUAL_ID;
|
|
10403
|
+
return aliasTargets?.has(id) ? RESOLVED_VIRTUAL_ID : null;
|
|
10404
|
+
}
|
|
10405
|
+
/**
|
|
10406
|
+
* 将 create/delete 这类结构性变化映射为 auto-routes 的全量重扫语义。
|
|
10407
|
+
*/
|
|
10408
|
+
function resolveAutoRoutesWatchChangeEvent(event) {
|
|
10409
|
+
if (event === "create" || event === "delete") return "rename";
|
|
10410
|
+
}
|
|
10411
|
+
/**
|
|
10412
|
+
* 判断某次热更新是否需要触发 auto-routes 虚拟模块失效。
|
|
10413
|
+
*/
|
|
10414
|
+
function resolveAutoRoutesHotUpdateAction(command, options) {
|
|
10415
|
+
if (command === "serve") return options.isRouteFile ? {
|
|
10416
|
+
shouldHandle: true,
|
|
10417
|
+
shouldUpdateRouteFile: true
|
|
10418
|
+
} : {
|
|
10419
|
+
shouldHandle: false,
|
|
10420
|
+
shouldUpdateRouteFile: false
|
|
10421
|
+
};
|
|
10422
|
+
if (options.isRouteFile || options.isPagesRelatedPath) return {
|
|
10423
|
+
shouldHandle: true,
|
|
10424
|
+
shouldUpdateRouteFile: false
|
|
10425
|
+
};
|
|
10426
|
+
return {
|
|
10427
|
+
shouldHandle: false,
|
|
10428
|
+
shouldUpdateRouteFile: false
|
|
10429
|
+
};
|
|
10430
|
+
}
|
|
10431
|
+
/**
|
|
10432
|
+
* Web 路由表在创建 router 时完成快照,必须越过 SFC 自接受边界重新加载入口。
|
|
10433
|
+
* 入口排在前面,避免依赖失效先将生成的入口降为仅更新时间戳的软失效。
|
|
10434
|
+
*/
|
|
10435
|
+
function collectAutoRoutesReloadModules(modules) {
|
|
10436
|
+
const pending = [...modules];
|
|
10437
|
+
const visited = new Set(pending);
|
|
10438
|
+
const reloadModules = /* @__PURE__ */ new Set();
|
|
10439
|
+
for (const module of pending) {
|
|
10440
|
+
if (module.importers.size === 0) reloadModules.add(module);
|
|
10441
|
+
for (const importer of module.importers) if (!visited.has(importer)) {
|
|
10442
|
+
visited.add(importer);
|
|
10443
|
+
pending.push(importer);
|
|
10444
|
+
}
|
|
10445
|
+
}
|
|
10446
|
+
for (const module of modules) reloadModules.add(module);
|
|
10447
|
+
return [...reloadModules];
|
|
10448
|
+
}
|
|
10449
|
+
//#endregion
|
|
9953
10450
|
//#region src/runtime/npmPlugin/service/dependencies.ts
|
|
9954
10451
|
const DEFAULT_NPM_STRATEGY = "explicit";
|
|
9955
10452
|
function dedupeDependencies(dependencies) {
|
|
@@ -10124,10 +10621,10 @@ function collectResolverPlugins(config) {
|
|
|
10124
10621
|
return (Array.isArray(config.plugins) ? config.plugins : config.plugins ? [config.plugins] : []).filter((plugin) => !isInternalPlugin(plugin));
|
|
10125
10622
|
}
|
|
10126
10623
|
async function transformVueSource(code, id, config) {
|
|
10127
|
-
const { descriptor, errors } =
|
|
10624
|
+
const { descriptor, errors } = await readAndParseSfc(id, { source: code });
|
|
10128
10625
|
if (errors.length) throw errors[0];
|
|
10129
|
-
const blocks = [descriptor.script, descriptor.scriptSetup].filter((block) => block?.content);
|
|
10130
|
-
const source = blocks.map((block) => block.content).join("\n") || "export default {}";
|
|
10626
|
+
const blocks = [descriptor.script, descriptor.scriptSetup].filter((block) => block?.content || block?.src);
|
|
10627
|
+
const source = blocks.map((block) => block.src ? `import ${JSON.stringify(block.src)};` : block.content).join("\n") || "export default {}";
|
|
10131
10628
|
const lang = blocks.some((block) => block?.lang === "tsx") ? "tsx" : blocks.some((block) => block?.lang === "ts") ? "ts" : "js";
|
|
10132
10629
|
return await transformWithOxc(source, id, {
|
|
10133
10630
|
lang,
|
|
@@ -10151,7 +10648,18 @@ function createProviderPlugin(ctx, config, onChange) {
|
|
|
10151
10648
|
return {
|
|
10152
10649
|
name: "weapp-vite:module-graph-provider",
|
|
10153
10650
|
enforce: "pre",
|
|
10651
|
+
config() {
|
|
10652
|
+
return { resolve: { alias: [{
|
|
10653
|
+
find: WEVU_AUTO_ROUTES_MODULE_ID$1,
|
|
10654
|
+
replacement: WEVU_AUTO_ROUTES_VIRTUAL_MODULE_ID$1
|
|
10655
|
+
}, {
|
|
10656
|
+
find: AUTO_ROUTES_ID$1,
|
|
10657
|
+
replacement: VIRTUAL_MODULE_ID
|
|
10658
|
+
}] } };
|
|
10659
|
+
},
|
|
10154
10660
|
async resolveId(id, importer) {
|
|
10661
|
+
const autoRoutesId = resolveAutoRoutesVirtualId(id);
|
|
10662
|
+
if (autoRoutesId) return autoRoutesId;
|
|
10155
10663
|
const virtualId = resolveVirtualModuleId(id);
|
|
10156
10664
|
if (virtualId) return virtualId;
|
|
10157
10665
|
if (parseSidecarSourceRequest(id)) return id;
|
|
@@ -10165,6 +10673,9 @@ function createProviderPlugin(ctx, config, onChange) {
|
|
|
10165
10673
|
return null;
|
|
10166
10674
|
},
|
|
10167
10675
|
load(id) {
|
|
10676
|
+
const autoRoutesId = resolveAutoRoutesVirtualId(id);
|
|
10677
|
+
const service = ctx.autoRoutesService;
|
|
10678
|
+
if (autoRoutesId && service) return service.ensureFresh().then(() => autoRoutesId === WEVU_AUTO_ROUTES_RESOLVED_MODULE_ID$1 ? service.getNamedModuleCode() : service.getModuleCode());
|
|
10168
10679
|
if (id.startsWith(DEV_EXTERNAL_PREFIX)) return "export default {}";
|
|
10169
10680
|
const logicalEntry = parseLogicalEntryId(id);
|
|
10170
10681
|
if (logicalEntry) return createLogicalEntryModuleCode(logicalEntry, ctx.moduleGraphService.getEntryDependencies(logicalEntry.sourceId));
|
|
@@ -10199,6 +10710,7 @@ function createProviderPlugin(ctx, config, onChange) {
|
|
|
10199
10710
|
async function createDevModuleGraphProvider(ctx, buildConfig, onChange) {
|
|
10200
10711
|
const configService = ctx.configService;
|
|
10201
10712
|
const userWatch = buildConfig.server?.watch;
|
|
10713
|
+
const pollingWatchOptions = resolvePollingWatchOptions({ inlineConfig: configService?.inlineConfig ?? {} });
|
|
10202
10714
|
const ignored = configService?.outDir ? createViteWatchIgnored(buildConfig.root ?? configService.cwd, configService.outDir, userWatch?.ignored) : userWatch?.ignored;
|
|
10203
10715
|
const server = await createServer({
|
|
10204
10716
|
...buildConfig,
|
|
@@ -10213,6 +10725,7 @@ async function createDevModuleGraphProvider(ctx, buildConfig, onChange) {
|
|
|
10213
10725
|
middlewareMode: true,
|
|
10214
10726
|
watch: {
|
|
10215
10727
|
...userWatch ?? {},
|
|
10728
|
+
...Object.fromEntries(Object.entries(pollingWatchOptions).filter(([, value]) => value !== void 0)),
|
|
10216
10729
|
...ignored !== void 0 ? { ignored } : {}
|
|
10217
10730
|
}
|
|
10218
10731
|
},
|
|
@@ -10290,7 +10803,7 @@ async function collectVueStyleScriptChanges(ctx, filename, configService) {
|
|
|
10290
10803
|
const changedEntries = /* @__PURE__ */ new Set();
|
|
10291
10804
|
for (const [entryId, bindings] of ctx.runtimeState.build.hmr.vueEntryStyleBindings) {
|
|
10292
10805
|
if (!bindings.sources.some((source) => normalizeFsResolvedId(source) === filename)) continue;
|
|
10293
|
-
const { descriptor } = await readAndParseSfc(entryId, createReadAndParseSfcOptions(ctx.moduleGraphService, configService));
|
|
10806
|
+
const { descriptor } = await readAndParseSfc$1(entryId, createReadAndParseSfcOptions(ctx.moduleGraphService, configService));
|
|
10294
10807
|
if (!hasSameCssVars(bindings.expressions, descriptor.cssVars)) changedEntries.add(entryId);
|
|
10295
10808
|
}
|
|
10296
10809
|
return changedEntries;
|
|
@@ -10478,6 +10991,9 @@ function resolveHmrRuntimeDecision(options) {
|
|
|
10478
10991
|
runtime: "classic"
|
|
10479
10992
|
};
|
|
10480
10993
|
}
|
|
10994
|
+
function resolveHmrRuntime(options) {
|
|
10995
|
+
return resolveHmrRuntimeDecision(options).runtime;
|
|
10996
|
+
}
|
|
10481
10997
|
function findSkylineRendererFiles(output) {
|
|
10482
10998
|
const jsonConfigs = /* @__PURE__ */ new Map();
|
|
10483
10999
|
for (const item of output) {
|
|
@@ -11471,9 +11987,18 @@ function createRuntimeState() {
|
|
|
11471
11987
|
},
|
|
11472
11988
|
autoRoutes: {
|
|
11473
11989
|
routes: emptyAutoRoutesSnapshot,
|
|
11990
|
+
namedRoutes: [],
|
|
11474
11991
|
serialized: emptyAutoRoutesArtifacts.serialized,
|
|
11475
11992
|
moduleCode: emptyAutoRoutesArtifacts.moduleCode,
|
|
11993
|
+
namedModuleCode: emptyAutoRoutesArtifacts.namedModuleCode,
|
|
11994
|
+
signature: emptyAutoRoutesArtifacts.signature,
|
|
11995
|
+
topologyKey: "",
|
|
11476
11996
|
typedDefinition: "",
|
|
11997
|
+
pageDeclarationDependencies: /* @__PURE__ */ new Map(),
|
|
11998
|
+
pageDeclarationFingerprints: /* @__PURE__ */ new Map(),
|
|
11999
|
+
usesOpaquePageDeclarationResolver: false,
|
|
12000
|
+
pageSourceFiles: /* @__PURE__ */ new Set(),
|
|
12001
|
+
namedRouteSourceFiles: /* @__PURE__ */ new Set(),
|
|
11477
12002
|
watchFiles: /* @__PURE__ */ new Set(),
|
|
11478
12003
|
watchDirs: /* @__PURE__ */ new Set(),
|
|
11479
12004
|
dirty: true,
|
|
@@ -11523,6 +12048,7 @@ function createRuntimeState() {
|
|
|
11523
12048
|
lastHmrEntryIds: /* @__PURE__ */ new Set(),
|
|
11524
12049
|
lastEmittedEntryIds: /* @__PURE__ */ new Set(),
|
|
11525
12050
|
lastEmittedChunkFileNames: /* @__PURE__ */ new Set(),
|
|
12051
|
+
forceEmitUnchangedChunks: true,
|
|
11526
12052
|
sharedChunkSourceModuleIds: /* @__PURE__ */ new Set(),
|
|
11527
12053
|
recentProfiles: [],
|
|
11528
12054
|
profile: {}
|
|
@@ -11589,18 +12115,7 @@ function resetRuntimeStateForFreshBuild(runtimeState) {
|
|
|
11589
12115
|
runtimeState.glassEasel.diagnostics.clear();
|
|
11590
12116
|
runtimeState.glassEasel.warnedDiagnostics.clear();
|
|
11591
12117
|
runtimeState.glassEasel.silent = false;
|
|
11592
|
-
|
|
11593
|
-
autoRoutes.routes = fresh.autoRoutes.routes;
|
|
11594
|
-
autoRoutes.serialized = fresh.autoRoutes.serialized;
|
|
11595
|
-
autoRoutes.moduleCode = fresh.autoRoutes.moduleCode;
|
|
11596
|
-
autoRoutes.typedDefinition = fresh.autoRoutes.typedDefinition;
|
|
11597
|
-
autoRoutes.watchFiles.clear();
|
|
11598
|
-
autoRoutes.watchDirs.clear();
|
|
11599
|
-
autoRoutes.dirty = fresh.autoRoutes.dirty;
|
|
11600
|
-
autoRoutes.initialized = fresh.autoRoutes.initialized;
|
|
11601
|
-
autoRoutes.candidates.clear();
|
|
11602
|
-
autoRoutes.needsFullRescan = fresh.autoRoutes.needsFullRescan;
|
|
11603
|
-
autoRoutes.loadingAppConfig = fresh.autoRoutes.loadingAppConfig;
|
|
12118
|
+
Object.assign(runtimeState.autoRoutes, fresh.autoRoutes);
|
|
11604
12119
|
const autoImport = runtimeState.autoImport;
|
|
11605
12120
|
autoImport.registry.clear();
|
|
11606
12121
|
autoImport.normalizedLocalComponents.clear();
|
|
@@ -13184,6 +13699,29 @@ function createPreserveModulesGroup(configService, getSubPackageRoots) {
|
|
|
13184
13699
|
};
|
|
13185
13700
|
}
|
|
13186
13701
|
//#endregion
|
|
13702
|
+
//#region src/runtime/sharedBuildConfig/virtualChunk.ts
|
|
13703
|
+
/** 虚拟模块的完整路径只作为标识参与散列,避免泄漏到文件名并超过文件系统长度限制。 */
|
|
13704
|
+
function resolveVirtualChunkFileName(chunk, root) {
|
|
13705
|
+
const ids = chunk.facadeModuleId ? [chunk.facadeModuleId] : chunk.moduleIds ?? [];
|
|
13706
|
+
if (ids.length !== 1) return;
|
|
13707
|
+
const id = ids[0];
|
|
13708
|
+
const entry = parseLogicalEntryId(id);
|
|
13709
|
+
const sidecar = parseSidecarModuleId(id);
|
|
13710
|
+
const identity = entry ? [
|
|
13711
|
+
"entry",
|
|
13712
|
+
entry.type,
|
|
13713
|
+
path.relative(root, entry.sourceId)
|
|
13714
|
+
] : sidecar ? [
|
|
13715
|
+
"sidecar",
|
|
13716
|
+
sidecar.kind,
|
|
13717
|
+
path.relative(root, sidecar.ownerId),
|
|
13718
|
+
path.relative(root, sidecar.sourceId)
|
|
13719
|
+
] : void 0;
|
|
13720
|
+
if (!identity) return;
|
|
13721
|
+
const hash = createHash("sha256").update(JSON.stringify(identity)).digest("hex").slice(0, 16);
|
|
13722
|
+
return `weapp-${identity[0]}-${identity[1]}-${hash}.js`;
|
|
13723
|
+
}
|
|
13724
|
+
//#endregion
|
|
13187
13725
|
//#region src/runtime/wevuModules.ts
|
|
13188
13726
|
const WEVU_RUNTIME_MODULE_IDS = [
|
|
13189
13727
|
"wevu",
|
|
@@ -13230,6 +13768,15 @@ function normalizeModuleId(id) {
|
|
|
13230
13768
|
stripLeadingNullByte: true
|
|
13231
13769
|
}).replaceAll("\\", "/");
|
|
13232
13770
|
}
|
|
13771
|
+
function isWevuOwnedModuleId(id) {
|
|
13772
|
+
if (WEVU_RUNTIME_MODULE_IDS.includes(id)) return true;
|
|
13773
|
+
const normalized = normalizeModuleId(id);
|
|
13774
|
+
const workspaceIndex = normalized.lastIndexOf("/packages-runtime/wevu/");
|
|
13775
|
+
if (workspaceIndex >= 0) return !normalized.slice(workspaceIndex + 23).split("/").includes("node_modules");
|
|
13776
|
+
const nodeModulesIndex = normalized.lastIndexOf("/node_modules/");
|
|
13777
|
+
if (nodeModulesIndex < 0) return false;
|
|
13778
|
+
return normalized.slice(nodeModulesIndex + 14).split("/", 1)[0] === "wevu";
|
|
13779
|
+
}
|
|
13233
13780
|
function resolveWevuPreservedModulePath(id) {
|
|
13234
13781
|
const normalized = normalizeModuleId(id);
|
|
13235
13782
|
const sourceMarker = "/packages-runtime/wevu/src/";
|
|
@@ -13288,6 +13835,7 @@ const REG_COMMONJS_HELPERS = /commonjsHelpers\.js$/;
|
|
|
13288
13835
|
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)))(?:$|[?#])/;
|
|
13289
13836
|
const REG_WEAPP_VITE_RUNTIME_VENDOR_ID = /(?:^|[/\\])weapp-vite[/\\](?:dist[/\\]runtime\.mjs|src[/\\]plugins[/\\]vue[/\\]runtime\.ts)(?:$|[?#])/;
|
|
13290
13837
|
const REG_HASHED_DIST_CHUNK_ID = /(?:^|[/\\])dist[/\\](?:dev[/\\])?([^/\\-]+)-([\w-]{6,})\.(?:m?js|cjs)(?:$|[?#])/;
|
|
13838
|
+
const REG_WEVU_RUNTIME_SUPPORT_ID = /(?:^|\/)@weapp-core\/(?:constants|shared)\/dist\//;
|
|
13291
13839
|
const STABLE_HASHED_DIST_CHUNK_PRIORITY = ["src"];
|
|
13292
13840
|
const STABLE_HASHED_DIST_CHUNK_PRIORITY_BY_PACKAGE = { wevu: [
|
|
13293
13841
|
"index",
|
|
@@ -13415,14 +13963,24 @@ function isWeappViteRuntimeModuleId(id) {
|
|
|
13415
13963
|
REG_WEAPP_VITE_RUNTIME_VENDOR_ID.lastIndex = 0;
|
|
13416
13964
|
return REG_WEAPP_VITE_RUNTIME_VENDOR_ID.test(cleanedAbsoluteId);
|
|
13417
13965
|
}
|
|
13966
|
+
function isPackagedRuntimeModuleId(id) {
|
|
13967
|
+
const cleanedAbsoluteId = normalizeSharedPathCandidate(id);
|
|
13968
|
+
REG_NODE_MODULES_DIR.lastIndex = 0;
|
|
13969
|
+
return REG_NODE_MODULES_DIR.test(cleanedAbsoluteId) || Boolean(resolveDistChunkPackageToken(cleanedAbsoluteId));
|
|
13970
|
+
}
|
|
13971
|
+
function isWevuRuntimeSupportModuleId(id) {
|
|
13972
|
+
return REG_WEVU_RUNTIME_SUPPORT_ID.test(normalizeSharedPathCandidate(id));
|
|
13973
|
+
}
|
|
13418
13974
|
function resolveStableHashedDistChunkFileName(chunk) {
|
|
13419
13975
|
const candidateIds = [chunk.facadeModuleId, ...chunk.moduleIds ?? []].filter((id) => typeof id === "string");
|
|
13420
13976
|
const matchedChunks = [];
|
|
13421
13977
|
let facadeMatchedChunk;
|
|
13422
|
-
|
|
13423
|
-
|
|
13424
|
-
|
|
13425
|
-
|
|
13978
|
+
const wevuOwnedCandidates = candidateIds.map((id) => isWevuOwnedModuleId(id));
|
|
13979
|
+
const hasWevuOwnedCandidate = wevuOwnedCandidates.some(Boolean);
|
|
13980
|
+
const hasOtherPackagedCandidate = candidateIds.some((id, index) => !wevuOwnedCandidates[index] && !isWevuRuntimeSupportModuleId(id) && isPackagedRuntimeModuleId(id));
|
|
13981
|
+
if (hasWevuOwnedCandidate && hasOtherPackagedCandidate) return "weapp-vendors/common.js";
|
|
13982
|
+
const firstWevuVendorFileName = candidateIds.map((id) => resolveWevuStableVendorFileName(id)).find((fileName) => Boolean(fileName));
|
|
13983
|
+
if (firstWevuVendorFileName) return firstWevuVendorFileName;
|
|
13426
13984
|
for (const id of candidateIds) {
|
|
13427
13985
|
if (isWeappViteRuntimeModuleId(id)) return "weapp-vendors/weapp-vite-runtime.js";
|
|
13428
13986
|
const cleanedAbsoluteId = normalizeSharedPathCandidate(id);
|
|
@@ -13519,7 +14077,7 @@ function createSharedBuildOutput(configService, getSubPackageRoots, options = {}
|
|
|
13519
14077
|
const stableHashedDistChunkFileName = resolveStableHashedDistChunkFileName(chunk);
|
|
13520
14078
|
if (stableHashedDistChunkFileName) return stableHashedDistChunkFileName;
|
|
13521
14079
|
}
|
|
13522
|
-
return "[name].js";
|
|
14080
|
+
return resolveVirtualChunkFileName(chunk, configService.absoluteSrcRoot) ?? "[name].js";
|
|
13523
14081
|
}
|
|
13524
14082
|
};
|
|
13525
14083
|
}
|
|
@@ -14275,37 +14833,6 @@ function isStatefulHmrRuntimeCompatibilityError(error) {
|
|
|
14275
14833
|
return error instanceof StatefulHmrRuntimeCompatibilityError || typeof error === "object" && error !== null && Reflect.get(error, "code") === "WEAPP_VITE_STATEFUL_HMR_RUNTIME_INCOMPATIBLE";
|
|
14276
14834
|
}
|
|
14277
14835
|
//#endregion
|
|
14278
|
-
//#region src/runtime/statefulHmr/componentPageStyles.ts
|
|
14279
|
-
/** 以完整产物中的最终 JSON 覆盖注册选项,只接纳已确认的 Component 页面。 */
|
|
14280
|
-
function resolveComponentPageGlobalStyleRoutes(output, pageOptions) {
|
|
14281
|
-
const assets = new Map(output.flatMap((item) => item.type === "asset" ? [[item.fileName, item]] : []));
|
|
14282
|
-
const appAsset = assets.get("app.json");
|
|
14283
|
-
const appConfig = appAsset ? JSON.parse(Buffer.from(appAsset.source).toString("utf8")) : void 0;
|
|
14284
|
-
const independentRoots = [];
|
|
14285
|
-
if (appConfig && typeof appConfig === "object" && !Array.isArray(appConfig)) {
|
|
14286
|
-
const config = appConfig;
|
|
14287
|
-
for (const key of ["subPackages", "subpackages"]) {
|
|
14288
|
-
const packages = config[key];
|
|
14289
|
-
if (!Array.isArray(packages)) continue;
|
|
14290
|
-
for (const entry of packages) if (entry && typeof entry === "object" && "independent" in entry && entry.independent === true && "root" in entry && typeof entry.root === "string") independentRoots.push(path.normalize(entry.root).replace(/^\/+|\/+$/g, ""));
|
|
14291
|
-
}
|
|
14292
|
-
}
|
|
14293
|
-
const routes = [];
|
|
14294
|
-
for (const [sourceRoute, options] of pageOptions) {
|
|
14295
|
-
const route = path.normalize(sourceRoute);
|
|
14296
|
-
if (independentRoots.some((root) => route === root || route.startsWith(`${root}/`))) continue;
|
|
14297
|
-
const jsonAsset = assets.get(`${route}.json`);
|
|
14298
|
-
let isolation = options.styleIsolation.kind === "known" ? options.styleIsolation.value : void 0;
|
|
14299
|
-
if (jsonAsset) {
|
|
14300
|
-
const config = JSON.parse(Buffer.from(jsonAsset.source).toString("utf8"));
|
|
14301
|
-
if (config === null || typeof config !== "object" || Array.isArray(config)) throw new Error(`Invalid Component page JSON: ${route}.json`);
|
|
14302
|
-
if ("styleIsolation" in config && config.styleIsolation !== void 0) isolation = config.styleIsolation;
|
|
14303
|
-
}
|
|
14304
|
-
if (isolation === "apply-shared") routes.push(route);
|
|
14305
|
-
}
|
|
14306
|
-
return routes.sort();
|
|
14307
|
-
}
|
|
14308
|
-
//#endregion
|
|
14309
14836
|
//#region src/plugins/hooks/useLoadEntry/entryChunkLifecycle.ts
|
|
14310
14837
|
const ENTRY_GRAPH_CHANGE_REASON = "entry-graph-changed";
|
|
14311
14838
|
/** 入口注册属于完整扫描;局部扫描只能复用已注册入口或请求重建入口图。 */
|
|
@@ -15079,7 +15606,7 @@ function createStatefulHmrGlobalStyleAssets(output, styleExtension, options = {}
|
|
|
15079
15606
|
const globalStyle = result.find((item) => item.type === "asset" && item.fileName === styleFile);
|
|
15080
15607
|
const marker = pageStyleRefreshMarker(styleRefreshToken(globalStyle?.type === "asset" ? globalStyle.source : ""));
|
|
15081
15608
|
for (const [index, item] of result.entries()) {
|
|
15082
|
-
if (item.type !== "asset" || path.extname(item.fileName) !== path.extname(styleFile) || item.fileName
|
|
15609
|
+
if (item.type !== "asset" || path.extname(item.fileName) !== path.extname(styleFile) || !routes.has(item.fileName.slice(0, -path.extname(styleFile).length))) continue;
|
|
15083
15610
|
const original = Buffer.from(item.source).toString("utf8");
|
|
15084
15611
|
const source = stripPageStyleRefreshMarker(original);
|
|
15085
15612
|
if (!source) continue;
|
|
@@ -17808,6 +18335,7 @@ async function runStatefulHmrDev(ctx, buildOptions, restart, snapshots) {
|
|
|
17808
18335
|
port: 0,
|
|
17809
18336
|
watch: {
|
|
17810
18337
|
...buildOptions.server?.watch ?? {},
|
|
18338
|
+
...Object.fromEntries(Object.entries(pollingWatchOptions).filter(([, value]) => value !== void 0)),
|
|
17811
18339
|
ignored: createViteWatchIgnored(buildOptions.root ?? configService.cwd, configService.outDir, buildOptions.server?.watch?.ignored)
|
|
17812
18340
|
}
|
|
17813
18341
|
},
|
|
@@ -18278,6 +18806,65 @@ function formatStatefulHmrError(error) {
|
|
|
18278
18806
|
return String(error);
|
|
18279
18807
|
}
|
|
18280
18808
|
//#endregion
|
|
18809
|
+
//#region src/runtime/statefulHmr/componentPageStyles.ts
|
|
18810
|
+
function hasNativePageRegistration(code) {
|
|
18811
|
+
if (!code.includes("Page")) return false;
|
|
18812
|
+
let found = false;
|
|
18813
|
+
traverse(parseJsLike(code), { CallExpression(callPath) {
|
|
18814
|
+
const callee = callPath.node.callee;
|
|
18815
|
+
if (callee.type === "Identifier" && callee.name === "Page" && !callPath.scope.hasBinding("Page")) {
|
|
18816
|
+
found = true;
|
|
18817
|
+
callPath.stop();
|
|
18818
|
+
}
|
|
18819
|
+
} });
|
|
18820
|
+
return found;
|
|
18821
|
+
}
|
|
18822
|
+
/** 以最终 JSON 和注册方式确认继承全局样式的页面,保留独立分包与隔离边界。 */
|
|
18823
|
+
function resolveComponentPageGlobalStyleRoutes(output, pageOptions) {
|
|
18824
|
+
const assets = new Map(output.flatMap((item) => item.type === "asset" ? [[item.fileName, item]] : []));
|
|
18825
|
+
const appAsset = assets.get("app.json");
|
|
18826
|
+
const appConfig = appAsset ? JSON.parse(Buffer.from(appAsset.source).toString("utf8")) : void 0;
|
|
18827
|
+
const independentRoots = [];
|
|
18828
|
+
const nativeCandidates = [];
|
|
18829
|
+
if (appConfig && typeof appConfig === "object" && !Array.isArray(appConfig)) {
|
|
18830
|
+
const config = appConfig;
|
|
18831
|
+
if (Array.isArray(config.pages)) nativeCandidates.push(...config.pages.filter((route) => typeof route === "string"));
|
|
18832
|
+
for (const key of ["subPackages", "subpackages"]) {
|
|
18833
|
+
const packages = config[key];
|
|
18834
|
+
if (!Array.isArray(packages)) continue;
|
|
18835
|
+
for (const entry of packages) if (entry && typeof entry === "object" && "independent" in entry && entry.independent === true && "root" in entry && typeof entry.root === "string") independentRoots.push(path.normalize(entry.root).replace(/^\/+|\/+$/g, ""));
|
|
18836
|
+
else if (entry && typeof entry === "object" && "root" in entry && typeof entry.root === "string" && "pages" in entry && Array.isArray(entry.pages)) nativeCandidates.push(...entry.pages.filter((route) => typeof route === "string").map((route) => path.join(entry.root, route)));
|
|
18837
|
+
}
|
|
18838
|
+
}
|
|
18839
|
+
const routes = [];
|
|
18840
|
+
const componentRoutes = new Set(Array.from(pageOptions.keys(), (route) => path.normalize(route)));
|
|
18841
|
+
for (const [sourceRoute, options] of pageOptions) {
|
|
18842
|
+
const route = path.normalize(sourceRoute);
|
|
18843
|
+
if (independentRoots.some((root) => route === root || route.startsWith(`${root}/`))) continue;
|
|
18844
|
+
const jsonAsset = assets.get(`${route}.json`);
|
|
18845
|
+
let isolation = options.styleIsolation.kind === "known" ? options.styleIsolation.value : void 0;
|
|
18846
|
+
if (jsonAsset) {
|
|
18847
|
+
const config = JSON.parse(Buffer.from(jsonAsset.source).toString("utf8"));
|
|
18848
|
+
if (config === null || typeof config !== "object" || Array.isArray(config)) throw new Error(`Invalid Component page JSON: ${route}.json`);
|
|
18849
|
+
if ("styleIsolation" in config && config.styleIsolation !== void 0) isolation = config.styleIsolation;
|
|
18850
|
+
}
|
|
18851
|
+
if (isolation === "apply-shared") routes.push(route);
|
|
18852
|
+
}
|
|
18853
|
+
const chunks = new Map(output.flatMap((item) => item.type === "chunk" ? [[item.fileName, item]] : []));
|
|
18854
|
+
for (const sourceRoute of nativeCandidates) {
|
|
18855
|
+
const route = path.normalize(sourceRoute);
|
|
18856
|
+
if (componentRoutes.has(route) || independentRoots.some((root) => route === root || route.startsWith(`${root}/`))) continue;
|
|
18857
|
+
const chunk = chunks.get(`${route}.js`);
|
|
18858
|
+
if (!chunk || !hasNativePageRegistration(chunk.code)) continue;
|
|
18859
|
+
const json = assets.get(`${route}.json`);
|
|
18860
|
+
const config = json ? JSON.parse(Buffer.from(json.source).toString("utf8")) : {};
|
|
18861
|
+
if (!config || typeof config !== "object" || Array.isArray(config)) throw new Error(`Invalid native page JSON: ${route}.json`);
|
|
18862
|
+
if ("component" in config && config.component === true) continue;
|
|
18863
|
+
routes.push(route);
|
|
18864
|
+
}
|
|
18865
|
+
return [...new Set(routes)].sort();
|
|
18866
|
+
}
|
|
18867
|
+
//#endregion
|
|
18281
18868
|
//#region src/runtime/statefulHmr/snapshotBuild.ts
|
|
18282
18869
|
/** 快照独立编译;初始化到构建收尾均不写支持文件,由活动 DevEngine 统一维护。 */
|
|
18283
18870
|
async function buildStatefulHmrSnapshot(loadOptions, configure = (options) => options) {
|
|
@@ -18287,7 +18874,16 @@ async function buildStatefulHmrSnapshot(loadOptions, configure = (options) => op
|
|
|
18287
18874
|
await ctx.configService.load(loadOptions);
|
|
18288
18875
|
await ctx.scanService.loadAppEntry();
|
|
18289
18876
|
ctx.scanService.loadSubPackages();
|
|
18290
|
-
|
|
18877
|
+
let globalStyleRoutes = [];
|
|
18878
|
+
const baseOptions = ctx.configService.merge(void 0, createSharedBuildConfig(ctx.configService, ctx.scanService));
|
|
18879
|
+
baseOptions.plugins = [...baseOptions.plugins ?? [], {
|
|
18880
|
+
name: "weapp-vite:stateful-hmr-page-style-metadata",
|
|
18881
|
+
enforce: "post",
|
|
18882
|
+
generateBundle(_options, bundle) {
|
|
18883
|
+
globalStyleRoutes = resolveComponentPageGlobalStyleRoutes(Object.values(bundle), ctx.runtimeState.build.hmr.componentPageStyleOptions);
|
|
18884
|
+
}
|
|
18885
|
+
}];
|
|
18886
|
+
const options = configure(baseOptions);
|
|
18291
18887
|
options.build = {
|
|
18292
18888
|
...options.build,
|
|
18293
18889
|
watch: void 0,
|
|
@@ -18297,7 +18893,7 @@ async function buildStatefulHmrSnapshot(loadOptions, configure = (options) => op
|
|
|
18297
18893
|
output: await build(options),
|
|
18298
18894
|
getEntryIds: () => ctx.runtimeState.build.hmr.resolvedEntryMap.keys(),
|
|
18299
18895
|
getDelegatedComponentEntryIds: () => Array.from(ctx.runtimeState.build.hmr.resolvedEntryMap.keys()).filter((id) => /\.(?:vue|jsx|tsx)$/.test(id) && ctx.runtimeState.build.hmr.entriesMap.get(ctx.configService.relativeAbsoluteSrcRoot(removeExtensionDeep(id)))?.type === "component"),
|
|
18300
|
-
|
|
18896
|
+
getGlobalStyleRoutes: () => globalStyleRoutes
|
|
18301
18897
|
};
|
|
18302
18898
|
});
|
|
18303
18899
|
}
|
|
@@ -18776,7 +19372,7 @@ async function applyScriptSetupUsingComponents(options) {
|
|
|
18776
19372
|
const { pluginCtx, vueEntryPath, source, templatePath, json, configService, wxmlService, reExportResolutionCache, externalComponentEntryMap } = options;
|
|
18777
19373
|
try {
|
|
18778
19374
|
if (source !== void 0 && !hasTemplateComponentTagHint(source)) return;
|
|
18779
|
-
const { descriptor, errors } = await readAndParseSfc(vueEntryPath, { ...createReadAndParseSfcOptions(pluginCtx, configService, source === void 0 ? void 0 : { source }) });
|
|
19375
|
+
const { descriptor, errors } = await readAndParseSfc$1(vueEntryPath, { ...createReadAndParseSfcOptions(pluginCtx, configService, source === void 0 ? void 0 : { source }) });
|
|
18780
19376
|
if (!errors?.length && descriptor?.template && !templatePath) {
|
|
18781
19377
|
const tags = collectVueTemplateAutoImportTags(descriptor.template.content, vueEntryPath);
|
|
18782
19378
|
if (tags.size) {
|
|
@@ -20128,7 +20724,7 @@ async function syncManagedTsconfigSupportFiles(ctx) {
|
|
|
20128
20724
|
};
|
|
20129
20725
|
}
|
|
20130
20726
|
async function syncAutoRoutesSupportFiles(ctx) {
|
|
20131
|
-
|
|
20727
|
+
await ctx.autoRoutesService?.ensureFresh();
|
|
20132
20728
|
}
|
|
20133
20729
|
async function syncAutoImportSupportFiles(ctx, syncAutoImport, configService) {
|
|
20134
20730
|
const autoImportConfig = syncAutoImport ? getAutoImportConfig(configService) : void 0;
|
|
@@ -20551,6 +21147,10 @@ function resetEmittedOutputCaches(runtimeState) {
|
|
|
20551
21147
|
runtimeState.css.transformedSidecarSource.clear();
|
|
20552
21148
|
runtimeState.wxml.emittedCode.clear();
|
|
20553
21149
|
}
|
|
21150
|
+
function shouldCleanOutputs(configService, phase) {
|
|
21151
|
+
if (configService.inlineConfig.build?.emptyOutDir === false) return false;
|
|
21152
|
+
return phase === "rebuild" || !configService.isDev || configService.weappViteConfig.cleanOutputsInDev !== false;
|
|
21153
|
+
}
|
|
20554
21154
|
async function cleanOutputs(configService) {
|
|
20555
21155
|
if (configService.mpDistRoot) {
|
|
20556
21156
|
const preservedNpmDirNames = resolvePreservedNpmDirNames(configService);
|
|
@@ -20570,10 +21170,24 @@ async function cleanOutputs(configService) {
|
|
|
20570
21170
|
//#endregion
|
|
20571
21171
|
//#region src/runtime/buildPlugin/snapshotSources.ts
|
|
20572
21172
|
/** 一次性 snapshot 不经过 watchChange,构建前必须刷新整个批次的真实源状态。 */
|
|
20573
|
-
async function refreshSnapshotSources(ctx, files) {
|
|
21173
|
+
async function refreshSnapshotSources(ctx, files, emittedRouteSignature) {
|
|
20574
21174
|
const changedFiles = new Set(Array.from(files, (file) => normalizeFsResolvedId(file)));
|
|
20575
21175
|
for (const file of changedFiles) invalidateFileCache(file);
|
|
20576
|
-
for (const file of changedFiles)
|
|
21176
|
+
for (const file of changedFiles) {
|
|
21177
|
+
await ctx.autoRoutesService?.handleFileChange(file);
|
|
21178
|
+
if (isTemplate(file)) await ctx.wxmlService?.scan(file);
|
|
21179
|
+
}
|
|
21180
|
+
const routeSignature = ctx.autoRoutesService?.getSignature();
|
|
21181
|
+
const routeDependentEntries = /* @__PURE__ */ new Set();
|
|
21182
|
+
if (emittedRouteSignature !== routeSignature) for (const id of [RESOLVED_VIRTUAL_ID, WEVU_AUTO_ROUTES_RESOLVED_MODULE_ID]) {
|
|
21183
|
+
invalidateFileCache(id);
|
|
21184
|
+
ctx.moduleGraphService.recordChangedFile(id, "update");
|
|
21185
|
+
for (const entry of ctx.moduleGraphService.invalidate(id)) routeDependentEntries.add(entry);
|
|
21186
|
+
}
|
|
21187
|
+
return {
|
|
21188
|
+
routeSignature,
|
|
21189
|
+
routeDependentEntries
|
|
21190
|
+
};
|
|
20577
21191
|
}
|
|
20578
21192
|
//#endregion
|
|
20579
21193
|
//#region src/runtime/buildPlugin/touchAppWxss.ts
|
|
@@ -21415,7 +22029,7 @@ function createBuildService(ctx) {
|
|
|
21415
22029
|
if (target === "app" && hmrDecision.runtime === "stateful-experimental") try {
|
|
21416
22030
|
const snapshot = await buildStatefulHmrSnapshot(configService.loadOptions, appendHmrMetricsPlugin);
|
|
21417
22031
|
const initialSnapshot = toStatefulHmrOutput(snapshot.output);
|
|
21418
|
-
const initialGlobalStyleRoutes =
|
|
22032
|
+
const initialGlobalStyleRoutes = snapshot.getGlobalStyleRoutes();
|
|
21419
22033
|
const initialEntryIds = collectStatefulHmrEntryIds(snapshot.getEntryIds());
|
|
21420
22034
|
const skylineFiles = findSkylineRendererFiles(initialSnapshot);
|
|
21421
22035
|
if (skylineFiles.length > 0) await applySkylineHmrFallback({
|
|
@@ -21475,12 +22089,11 @@ function createBuildService(ctx) {
|
|
|
21475
22089
|
}];
|
|
21476
22090
|
return snapshotOptions;
|
|
21477
22091
|
});
|
|
21478
|
-
const output = toStatefulHmrOutput(snapshot.output);
|
|
21479
22092
|
return {
|
|
21480
|
-
output,
|
|
22093
|
+
output: toStatefulHmrOutput(snapshot.output),
|
|
21481
22094
|
entryIds: [...collectStatefulHmrEntryIds(snapshot.getEntryIds())],
|
|
21482
22095
|
delegatedComponentEntryIds: snapshot.getDelegatedComponentEntryIds(),
|
|
21483
|
-
componentPageGlobalStyleRoutes:
|
|
22096
|
+
componentPageGlobalStyleRoutes: snapshot.getGlobalStyleRoutes()
|
|
21484
22097
|
};
|
|
21485
22098
|
}
|
|
21486
22099
|
}), workerPromise]);
|
|
@@ -21516,6 +22129,7 @@ function createBuildService(ctx) {
|
|
|
21516
22129
|
let pendingSnapshotBatch;
|
|
21517
22130
|
let failedSnapshotReasons = [];
|
|
21518
22131
|
let snapshotBatchTimer;
|
|
22132
|
+
let emittedAutoRoutesSignature;
|
|
21519
22133
|
const devBuildWatcher = target === "app" ? createDevBuildWatcher() : void 0;
|
|
21520
22134
|
function markSnapshotEntriesFullDirty() {
|
|
21521
22135
|
for (const entryId of ctx.runtimeState.build.hmr.resolvedEntryMap.keys()) {
|
|
@@ -21576,7 +22190,9 @@ function createBuildService(ctx) {
|
|
|
21576
22190
|
recordHmrProfileDuration(ctx.runtimeState.build.hmr.profile, "snapshotResolveMs", performance.now() - snapshotResolveStartedAt);
|
|
21577
22191
|
const snapshotBuildStartedAt = performance.now();
|
|
21578
22192
|
const requiresFullRescan = batchReasons.some((batchReason) => batchReason.forceFullRescan || batchReason.event === "create" || batchReason.event === "delete");
|
|
21579
|
-
await refreshSnapshotSources(ctx, batchReasons.flatMap((batchReason) => batchReason.file ? [batchReason.file] : []));
|
|
22193
|
+
const { routeSignature, routeDependentEntries } = await refreshSnapshotSources(ctx, batchReasons.flatMap((batchReason) => batchReason.file ? [batchReason.file] : []), emittedAutoRoutesSignature);
|
|
22194
|
+
for (const entryId of graphAffectedEntries) routeDependentEntries.delete(entryId);
|
|
22195
|
+
for (const entryId of routeDependentEntries) graphAffectedEntries.add(entryId);
|
|
21580
22196
|
const styleScriptChanges = /* @__PURE__ */ new Set();
|
|
21581
22197
|
for (const batchReason of batchReasons) {
|
|
21582
22198
|
if (!batchReason.file) continue;
|
|
@@ -21588,7 +22204,7 @@ function createBuildService(ctx) {
|
|
|
21588
22204
|
if (!requiresFullRescan && graphAffectedEntries.size) {
|
|
21589
22205
|
const dirtyReasons = batchReasons.map(resolveSnapshotDirtyReason);
|
|
21590
22206
|
const dirtyReason = dirtyReasons.includes("direct") ? "direct" : dirtyReasons.includes("dependency") ? "dependency" : "metadata";
|
|
21591
|
-
for (const entryId of graphAffectedEntries) if (ctx.runtimeState.build.hmr.resolvedEntryMap.has(entryId)) markSnapshotEntryDirty(entryId, reason, styleScriptChanges.has(entryId) ? "direct" : dirtyReason);
|
|
22207
|
+
for (const entryId of graphAffectedEntries) if (ctx.runtimeState.build.hmr.resolvedEntryMap.has(entryId)) markSnapshotEntryDirty(entryId, reason, styleScriptChanges.has(entryId) ? "direct" : routeDependentEntries.has(entryId) ? "dependency" : dirtyReason);
|
|
21592
22208
|
const summaryCounts = /* @__PURE__ */ new Map();
|
|
21593
22209
|
for (const batchReason of batchReasons) {
|
|
21594
22210
|
if (!batchReason.file) continue;
|
|
@@ -21600,6 +22216,7 @@ function createBuildService(ctx) {
|
|
|
21600
22216
|
try {
|
|
21601
22217
|
devBuildWatcher?.emitEvent({ code: "START" });
|
|
21602
22218
|
await build(snapshotBuildOptions);
|
|
22219
|
+
emittedAutoRoutesSignature = routeSignature;
|
|
21603
22220
|
devBuildWatcher?.emitEvent({ code: "END" });
|
|
21604
22221
|
} catch (error) {
|
|
21605
22222
|
devBuildWatcher?.emitEvent({
|
|
@@ -21623,9 +22240,10 @@ function createBuildService(ctx) {
|
|
|
21623
22240
|
...snapshotBuildOptions,
|
|
21624
22241
|
build: {
|
|
21625
22242
|
...snapshotBuildOptions.build ?? {},
|
|
21626
|
-
emptyOutDir:
|
|
22243
|
+
emptyOutDir: shouldCleanOutputs(configService, "rebuild")
|
|
21627
22244
|
}
|
|
21628
22245
|
});
|
|
22246
|
+
emittedAutoRoutesSignature = routeSignature;
|
|
21629
22247
|
devBuildWatcher?.emitEvent({ code: "END" });
|
|
21630
22248
|
return "snapshot";
|
|
21631
22249
|
} catch (error) {
|
|
@@ -21690,7 +22308,10 @@ function createBuildService(ctx) {
|
|
|
21690
22308
|
const watcherPromise = target === "app" ? (async () => {
|
|
21691
22309
|
devBuildWatcher.emitEvent({ code: "START" });
|
|
21692
22310
|
try {
|
|
22311
|
+
await ctx.autoRoutesService?.ensureFresh();
|
|
22312
|
+
const routeSignature = ctx.autoRoutesService?.getSignature();
|
|
21693
22313
|
await build(snapshotBuildOptions);
|
|
22314
|
+
emittedAutoRoutesSignature = routeSignature;
|
|
21694
22315
|
devBuildWatcher.emitEvent({ code: "END" });
|
|
21695
22316
|
return devBuildWatcher.watcher;
|
|
21696
22317
|
} catch (error) {
|
|
@@ -21875,6 +22496,8 @@ function createBuildService(ctx) {
|
|
|
21875
22496
|
const pluginOutputRoot = configService.absolutePluginOutputRoot;
|
|
21876
22497
|
if (!pluginOutputRoot) return;
|
|
21877
22498
|
const inlineConfig = { build: { outDir: pluginOutputRoot } };
|
|
22499
|
+
const emptyOutDir = configService.inlineConfig.build?.emptyOutDir;
|
|
22500
|
+
if (typeof emptyOutDir === "boolean") inlineConfig.build.emptyOutDir = emptyOutDir;
|
|
21878
22501
|
const isolatedCtx = await createCompilerContext({
|
|
21879
22502
|
key: `plugin-build:${configService.cwd}`,
|
|
21880
22503
|
cwd: configService.cwd,
|
|
@@ -21903,7 +22526,7 @@ function createBuildService(ctx) {
|
|
|
21903
22526
|
return await runProd(target);
|
|
21904
22527
|
}
|
|
21905
22528
|
async function buildEntry(options) {
|
|
21906
|
-
if (
|
|
22529
|
+
if (shouldCleanOutputs(configService, "startup")) {
|
|
21907
22530
|
await cleanOutputs(configService);
|
|
21908
22531
|
resetEmittedOutputCaches(ctx.runtimeState);
|
|
21909
22532
|
}
|
|
@@ -22089,34 +22712,6 @@ function resolveBuiltinPackageAliases(options = {}) {
|
|
|
22089
22712
|
return aliases;
|
|
22090
22713
|
}
|
|
22091
22714
|
//#endregion
|
|
22092
|
-
//#region src/runtime/config/internal/alias.ts
|
|
22093
|
-
function normalizeAliasOptions(alias) {
|
|
22094
|
-
if (!alias) return [];
|
|
22095
|
-
if (Array.isArray(alias)) return alias.filter((entry) => {
|
|
22096
|
-
return Boolean(entry && typeof entry === "object" && "find" in entry && "replacement" in entry);
|
|
22097
|
-
});
|
|
22098
|
-
return Object.entries(alias).map(([find, replacement]) => {
|
|
22099
|
-
return {
|
|
22100
|
-
find,
|
|
22101
|
-
replacement
|
|
22102
|
-
};
|
|
22103
|
-
});
|
|
22104
|
-
}
|
|
22105
|
-
function createAliasManager(oxcAlias, defaultBuiltinAliases) {
|
|
22106
|
-
function injectBuiltinAliases(config, builtinAliases = defaultBuiltinAliases) {
|
|
22107
|
-
const resolve = config.resolve ?? (config.resolve = {});
|
|
22108
|
-
const aliasArray = normalizeAliasOptions(resolve.alias);
|
|
22109
|
-
if (!aliasArray.some((entry) => {
|
|
22110
|
-
return entry.find instanceof RegExp && entry.find.source === oxcAlias.find.source;
|
|
22111
|
-
})) aliasArray.unshift(oxcAlias);
|
|
22112
|
-
for (const builtin of builtinAliases) if (!aliasArray.some((entry) => {
|
|
22113
|
-
return typeof entry.find === "string" && entry.find === builtin.find;
|
|
22114
|
-
})) aliasArray.unshift(builtin);
|
|
22115
|
-
resolve.alias = aliasArray;
|
|
22116
|
-
}
|
|
22117
|
-
return { injectBuiltinAliases };
|
|
22118
|
-
}
|
|
22119
|
-
//#endregion
|
|
22120
22715
|
//#region src/runtime/config/enhance.ts
|
|
22121
22716
|
const enhanceKeys = [
|
|
22122
22717
|
"wxml",
|
|
@@ -24276,89 +24871,6 @@ function asset(ctx) {
|
|
|
24276
24871
|
buildTarget: ctx.currentBuildTarget ?? "app"
|
|
24277
24872
|
})];
|
|
24278
24873
|
}
|
|
24279
|
-
const RESOLVED_VIRTUAL_ID = "\0weapp-vite:auto-routes";
|
|
24280
|
-
/**
|
|
24281
|
-
* 判断当前是否应按 watch 模式为 auto-routes 注册依赖文件。
|
|
24282
|
-
*/
|
|
24283
|
-
function isAutoRoutesWatchMode(configService) {
|
|
24284
|
-
return Boolean(configService?.isDev || configService?.inlineConfig?.build?.watch);
|
|
24285
|
-
}
|
|
24286
|
-
/**
|
|
24287
|
-
* 合并 service 与 matcher 提供的监听目录,并去重保留顺序。
|
|
24288
|
-
*/
|
|
24289
|
-
function collectAutoRoutesWatchDirs(watchDirectories, matcherWatchRoots) {
|
|
24290
|
-
const watchDirs = /* @__PURE__ */ new Set();
|
|
24291
|
-
for (const dir of watchDirectories) watchDirs.add(dir);
|
|
24292
|
-
for (const dir of matcherWatchRoots) watchDirs.add(dir);
|
|
24293
|
-
return [...watchDirs];
|
|
24294
|
-
}
|
|
24295
|
-
/**
|
|
24296
|
-
* 过滤出真正需要交给 auto-routes watcher 处理的路由 Vue 文件。
|
|
24297
|
-
*/
|
|
24298
|
-
function isAutoRoutesWatchFile(filePath, allowedExtensions, isPagesRelatedPath) {
|
|
24299
|
-
return !isAutoRoutesGeneratedFileName(path.basename(filePath)) && allowedExtensions.has(path.extname(filePath)) && isPagesRelatedPath(filePath);
|
|
24300
|
-
}
|
|
24301
|
-
/**
|
|
24302
|
-
* 判断是否满足 auto-routes sidecar watcher 的启动前置条件。
|
|
24303
|
-
*/
|
|
24304
|
-
function shouldStartAutoRoutesWatcher(options) {
|
|
24305
|
-
if (options.routeWatcherStarted) return false;
|
|
24306
|
-
if (!options.isDev) return false;
|
|
24307
|
-
if (!options.autoRoutesEnabled || !options.autoRoutesWatch || !options.serviceEnabled) return false;
|
|
24308
|
-
return options.watchDirsLength > 0;
|
|
24309
|
-
}
|
|
24310
|
-
/**
|
|
24311
|
-
* 生成 sidecar watcher map 使用的关闭句柄。
|
|
24312
|
-
*/
|
|
24313
|
-
function createAutoRoutesSidecarWatcher(watcher) {
|
|
24314
|
-
return { close: async () => {
|
|
24315
|
-
await watcher.close();
|
|
24316
|
-
} };
|
|
24317
|
-
}
|
|
24318
|
-
/**
|
|
24319
|
-
* 向插件上下文注册 auto-routes 相关 watch 目标,忽略单个 addWatchFile 失败。
|
|
24320
|
-
*/
|
|
24321
|
-
function addAutoRoutesWatchTargets(pluginCtx, targets) {
|
|
24322
|
-
for (const file of targets.files) try {
|
|
24323
|
-
pluginCtx.addWatchFile?.(normalizeWatchPath(file));
|
|
24324
|
-
} catch {}
|
|
24325
|
-
for (const dir of targets.directories) try {
|
|
24326
|
-
pluginCtx.addWatchFile?.(normalizeWatchPath(dir));
|
|
24327
|
-
} catch {}
|
|
24328
|
-
}
|
|
24329
|
-
/**
|
|
24330
|
-
* 统一解析 auto-routes 虚拟模块与 alias 入口的命中关系。
|
|
24331
|
-
*/
|
|
24332
|
-
function resolveAutoRoutesVirtualId(id, aliasTargets) {
|
|
24333
|
-
if (id === "weapp-vite/auto-routes" || id === "virtual:weapp-vite-auto-routes" || id === "\0weapp-vite:auto-routes") return RESOLVED_VIRTUAL_ID;
|
|
24334
|
-
return aliasTargets.has(id) ? RESOLVED_VIRTUAL_ID : null;
|
|
24335
|
-
}
|
|
24336
|
-
/**
|
|
24337
|
-
* 将 create/delete 这类结构性变化映射为 auto-routes 的全量重扫语义。
|
|
24338
|
-
*/
|
|
24339
|
-
function resolveAutoRoutesWatchChangeEvent(event) {
|
|
24340
|
-
if (event === "create" || event === "delete") return "rename";
|
|
24341
|
-
}
|
|
24342
|
-
/**
|
|
24343
|
-
* 判断某次热更新是否需要触发 auto-routes 虚拟模块失效。
|
|
24344
|
-
*/
|
|
24345
|
-
function resolveAutoRoutesHotUpdateAction(command, options) {
|
|
24346
|
-
if (command === "serve") return options.isRouteFile ? {
|
|
24347
|
-
shouldHandle: true,
|
|
24348
|
-
shouldUpdateRouteFile: true
|
|
24349
|
-
} : {
|
|
24350
|
-
shouldHandle: false,
|
|
24351
|
-
shouldUpdateRouteFile: false
|
|
24352
|
-
};
|
|
24353
|
-
if (options.isRouteFile || options.isPagesRelatedPath) return {
|
|
24354
|
-
shouldHandle: true,
|
|
24355
|
-
shouldUpdateRouteFile: false
|
|
24356
|
-
};
|
|
24357
|
-
return {
|
|
24358
|
-
shouldHandle: false,
|
|
24359
|
-
shouldUpdateRouteFile: false
|
|
24360
|
-
};
|
|
24361
|
-
}
|
|
24362
24874
|
//#endregion
|
|
24363
24875
|
//#region src/plugins/core/lifecycle/autoRoutesTopology.ts
|
|
24364
24876
|
/**
|
|
@@ -24370,31 +24882,95 @@ function markAppEntryForAutoRoutesTopology(ctx, options) {
|
|
|
24370
24882
|
invalidateFileCache("weapp-vite/auto-routes");
|
|
24371
24883
|
invalidateFileCache("virtual:weapp-vite-auto-routes");
|
|
24372
24884
|
invalidateFileCache("\0weapp-vite:auto-routes");
|
|
24885
|
+
invalidateFileCache(WEVU_AUTO_ROUTES_MODULE_ID);
|
|
24886
|
+
invalidateFileCache(WEVU_AUTO_ROUTES_VIRTUAL_MODULE_ID);
|
|
24887
|
+
invalidateFileCache(WEVU_AUTO_ROUTES_RESOLVED_MODULE_ID);
|
|
24373
24888
|
for (const target of resolveAutoRoutesAliasTargets(ctx.configService?.packageInfo?.rootPath)) invalidateFileCache(normalizeFsResolvedId(target));
|
|
24374
|
-
options.loadEntry
|
|
24889
|
+
const loadEntry = options.loadEntry;
|
|
24890
|
+
if (loadEntry && typeof loadEntry === "object" && "invalidateResolveCache" in loadEntry && typeof loadEntry.invalidateResolveCache === "function") loadEntry.invalidateResolveCache();
|
|
24375
24891
|
ctx.runtimeState.build.hmr.appEntryAutoRoutesSignature = void 0;
|
|
24376
24892
|
if (!appEntryId || !options.resolvedEntryMap.has(appEntryId)) return false;
|
|
24377
24893
|
options.markEntryDirty(appEntryId, "direct");
|
|
24378
24894
|
return true;
|
|
24379
24895
|
}
|
|
24380
24896
|
//#endregion
|
|
24897
|
+
//#region src/plugins/utils/parse.ts
|
|
24898
|
+
function hasOwn$2(source, key) {
|
|
24899
|
+
return Object.prototype.hasOwnProperty.call(source, key);
|
|
24900
|
+
}
|
|
24901
|
+
/**
|
|
24902
|
+
* 参考:https://github.com/tailwindlabs/tailwindcss/blob/main/packages/%40tailwindcss-vite/src/index.ts
|
|
24903
|
+
* 解析请求ID,返回包含文件名和查询参数的对象。
|
|
24904
|
+
* 如果查询参数中包含'wxss',则将其值设置为true。
|
|
24905
|
+
* @param id - 请求ID,格式为'filename?query'
|
|
24906
|
+
* @returns 解析后的请求响应对象
|
|
24907
|
+
*/
|
|
24908
|
+
function parseRequest(id) {
|
|
24909
|
+
const [filename, rawQuery] = id.split(`?`, 2);
|
|
24910
|
+
const query = {};
|
|
24911
|
+
if (rawQuery) {
|
|
24912
|
+
const params = new URLSearchParams(rawQuery);
|
|
24913
|
+
for (const [key, value] of params.entries()) query[key] = value;
|
|
24914
|
+
if (hasOwn$2(query, "wxss")) query.wxss = true;
|
|
24915
|
+
}
|
|
24916
|
+
return {
|
|
24917
|
+
filename,
|
|
24918
|
+
query
|
|
24919
|
+
};
|
|
24920
|
+
}
|
|
24921
|
+
/**
|
|
24922
|
+
* 根据请求响应获取 CSS 文件的真实路径。
|
|
24923
|
+
* 如果请求中包含 wxss 查询参数,则将文件扩展名更改为 'wxss'。
|
|
24924
|
+
* @param res - 解析请求的响应对象,包含文件名和查询参数。
|
|
24925
|
+
* @returns 返回文件的真实路径。
|
|
24926
|
+
*/
|
|
24927
|
+
function getCssRealPath(res) {
|
|
24928
|
+
if (typeof res.query.nativeStyle === "string" && res.query.nativeStyle) return changeFileExtension(res.filename, res.query.nativeStyle);
|
|
24929
|
+
if (res.query.wxss) return changeFileExtension(res.filename, "wxss");
|
|
24930
|
+
return res.filename;
|
|
24931
|
+
}
|
|
24932
|
+
//#endregion
|
|
24381
24933
|
//#region src/plugins/autoRoutes.ts
|
|
24382
24934
|
/**
|
|
24383
24935
|
* 路由文件监听器的唯一标识,用于在 sidecarWatcherMap 中注册。
|
|
24384
24936
|
*/
|
|
24385
|
-
const ROUTE_WATCHER_KEY = "__auto-routes-
|
|
24386
|
-
|
|
24387
|
-
|
|
24937
|
+
const ROUTE_WATCHER_KEY = "__auto-routes-source-watcher__";
|
|
24938
|
+
const AUTO_ROUTES_RESOLVED_IDS = [RESOLVED_VIRTUAL_ID, WEVU_AUTO_ROUTES_RESOLVED_MODULE_ID$1];
|
|
24939
|
+
const AUTO_ROUTES_VUE_SUFFIXES = vueExtensions.map((extension) => `.${extension}`);
|
|
24940
|
+
function isAutoRoutesWatcherController(watcher) {
|
|
24941
|
+
return Boolean(watcher && typeof watcher === "object" && "addWatchTargets" in watcher && typeof watcher.addWatchTargets === "function" && "close" in watcher && typeof watcher.close === "function" && "subscribers" in watcher && watcher.subscribers instanceof Map);
|
|
24942
|
+
}
|
|
24943
|
+
/**
|
|
24944
|
+
* 这里只排除非脚本 Vue 子资源;外部脚本是否属于页面声明由 service 的依赖所有权判定。
|
|
24945
|
+
*/
|
|
24946
|
+
function isPageScriptTransformRequest(id, normalizedId) {
|
|
24947
|
+
const query = id.includes("?") ? parseRequest(id).query : void 0;
|
|
24948
|
+
if (AUTO_ROUTES_VUE_SUFFIXES.some((suffix) => normalizedId.endsWith(suffix))) return query?.type === "script";
|
|
24949
|
+
return !query || !("vue" in query) || query.type === "script";
|
|
24950
|
+
}
|
|
24951
|
+
function createAutoRoutesPlugin(ctx, service) {
|
|
24388
24952
|
let resolvedConfig;
|
|
24389
24953
|
let devServer;
|
|
24954
|
+
let servedRouteSignature;
|
|
24390
24955
|
const autoRoutesAliasTargets = /* @__PURE__ */ new Set();
|
|
24391
24956
|
const autoRoutesTopologyDirtyEntries = /* @__PURE__ */ new Set();
|
|
24392
|
-
|
|
24957
|
+
const watcherSubscriber = {
|
|
24958
|
+
topologyDirtyEntries: autoRoutesTopologyDirtyEntries,
|
|
24959
|
+
get devServer() {
|
|
24960
|
+
return devServer;
|
|
24961
|
+
}
|
|
24962
|
+
};
|
|
24963
|
+
function registerPageDeclarationSourceResolver(pluginContext) {
|
|
24964
|
+
service.setPageDeclarationSourceResolver(typeof pluginContext.resolve === "function" ? async (source, importer) => {
|
|
24965
|
+
return (await pluginContext.resolve(source, importer, { skipSelf: true }))?.id;
|
|
24966
|
+
} : void 0);
|
|
24967
|
+
}
|
|
24393
24968
|
const refreshAutoRoutesAliasTargets = () => {
|
|
24394
24969
|
autoRoutesAliasTargets.clear();
|
|
24395
24970
|
for (const target of resolveAutoRoutesAliasTargets(ctx.configService?.packageInfo?.rootPath)) autoRoutesAliasTargets.add(target);
|
|
24396
24971
|
};
|
|
24397
24972
|
function isPagesRelatedPath(id) {
|
|
24973
|
+
if (service.isPageDeclarationSource(id)) return true;
|
|
24398
24974
|
const configService = ctx.configService;
|
|
24399
24975
|
if (!configService) return false;
|
|
24400
24976
|
const { autoRoutesConfig, subPackageRoots } = resolveAutoRoutesMatcherContext(ctx);
|
|
@@ -24406,37 +24982,14 @@ function createAutoRoutesPlugin(ctx) {
|
|
|
24406
24982
|
subPackageRoots
|
|
24407
24983
|
});
|
|
24408
24984
|
}
|
|
24409
|
-
|
|
24410
|
-
|
|
24411
|
-
|
|
24412
|
-
* 因此需要独立的文件监听来补偿。
|
|
24413
|
-
*
|
|
24414
|
-
* 注意:chokidar v5 在 macOS 上使用 glob 模式时无法检测新建文件,
|
|
24415
|
-
* 必须直接监听目录,然后在事件回调中按扩展名过滤。
|
|
24416
|
-
*
|
|
24417
|
-
* 生命周期:watcher 注册到 sidecarWatcherMap,由 watcherService.closeAll()
|
|
24418
|
-
* 统一回收,不在 closeBundle 中销毁(build watch 模式下 closeBundle 每次
|
|
24419
|
-
* 重编译都会触发,提前销毁会导致后续文件变更无法感知)。
|
|
24420
|
-
*/
|
|
24421
|
-
function invalidateAutoRoutesVirtualModule() {
|
|
24422
|
-
const server = devServer;
|
|
24423
|
-
const virtualModule = server?.moduleGraph.getModuleById(RESOLVED_VIRTUAL_ID);
|
|
24424
|
-
if (!virtualModule || !server) return;
|
|
24425
|
-
const seen = /* @__PURE__ */ new Set();
|
|
24426
|
-
const invalidateModuleWithImporters = (module) => {
|
|
24427
|
-
if (seen.has(module)) return;
|
|
24428
|
-
seen.add(module);
|
|
24429
|
-
server.moduleGraph.invalidateModule(module);
|
|
24430
|
-
for (const importer of module.importers) invalidateModuleWithImporters(importer);
|
|
24431
|
-
};
|
|
24432
|
-
invalidateModuleWithImporters(virtualModule);
|
|
24433
|
-
}
|
|
24434
|
-
function markAutoRoutesTopologyDirty() {
|
|
24985
|
+
function markAutoRoutesTopologyDirty(controller) {
|
|
24986
|
+
const appEntry = ctx.scanService?.appEntry?.path;
|
|
24987
|
+
if (appEntry) controller.subscribers.get("web")?.topologyDirtyEntries.add(normalizeFsResolvedId(appEntry));
|
|
24435
24988
|
return markAppEntryForAutoRoutesTopology(ctx, {
|
|
24436
24989
|
resolvedEntryMap: ctx.runtimeState.build.hmr.resolvedEntryMap,
|
|
24437
24990
|
markEntryDirty(entryId) {
|
|
24438
24991
|
const hmr = ctx.runtimeState.build.hmr;
|
|
24439
|
-
|
|
24992
|
+
for (const subscriber of controller.subscribers.values()) subscriber.topologyDirtyEntries.add(entryId);
|
|
24440
24993
|
hmr.dirtyEntrySet.add(entryId);
|
|
24441
24994
|
hmr.dirtyEntryReasons.set(entryId, "direct");
|
|
24442
24995
|
hmr.loadedEntrySet.delete(entryId);
|
|
@@ -24445,32 +24998,80 @@ function createAutoRoutesPlugin(ctx) {
|
|
|
24445
24998
|
}
|
|
24446
24999
|
});
|
|
24447
25000
|
}
|
|
24448
|
-
function
|
|
24449
|
-
const
|
|
24450
|
-
|
|
24451
|
-
|
|
24452
|
-
|
|
24453
|
-
|
|
24454
|
-
if (
|
|
24455
|
-
|
|
24456
|
-
|
|
24457
|
-
notifyAppEntryChange();
|
|
25001
|
+
function reportRouteStructureChangeError(filePath, event, error, controller) {
|
|
25002
|
+
const action = event === "create" ? "新增" : "删除";
|
|
25003
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
25004
|
+
const routeError = /* @__PURE__ */ new Error(`[auto-routes:watch] ${action}路由文件 ${ctx.configService?.relativeCwd(filePath) ?? filePath} 处理失败:${reason}`);
|
|
25005
|
+
const servers = /* @__PURE__ */ new Set();
|
|
25006
|
+
for (const subscriber of controller.subscribers.values()) if (subscriber.devServer) servers.add(subscriber.devServer);
|
|
25007
|
+
if (servers.size === 0) {
|
|
25008
|
+
logger_default.error(routeError);
|
|
25009
|
+
return;
|
|
24458
25010
|
}
|
|
25011
|
+
for (const server of servers) server.ws.send({
|
|
25012
|
+
type: "error",
|
|
25013
|
+
err: {
|
|
25014
|
+
message: routeError.message,
|
|
25015
|
+
stack: routeError.stack ?? routeError.message,
|
|
25016
|
+
id: filePath,
|
|
25017
|
+
plugin: "weapp-vite:auto-routes"
|
|
25018
|
+
}
|
|
25019
|
+
});
|
|
24459
25020
|
}
|
|
25021
|
+
async function handleRouteStructureChange(filePath, event, controller) {
|
|
25022
|
+
const changedSource = normalizeFsResolvedId(filePath);
|
|
25023
|
+
const declarationOwners = new Set(service.getPageDeclarationOwners(changedSource));
|
|
25024
|
+
const didChangeRoutes = await service.handleFileChange(filePath, resolveAutoRoutesWatchChangeEvent(event));
|
|
25025
|
+
controller.addWatchTargets([...service.getWatchDirectories()]);
|
|
25026
|
+
if (!didChangeRoutes) return;
|
|
25027
|
+
for (const owner of service.getPageDeclarationOwners(changedSource)) declarationOwners.add(owner);
|
|
25028
|
+
const servers = /* @__PURE__ */ new Set();
|
|
25029
|
+
for (const subscriber of controller.subscribers.values()) if (subscriber.devServer) servers.add(subscriber.devServer);
|
|
25030
|
+
for (const server of servers) invalidateAutoRoutesVirtualModules(server, AUTO_ROUTES_RESOLVED_IDS);
|
|
25031
|
+
const appEntryPath = ctx.scanService?.appEntry?.path;
|
|
25032
|
+
markAutoRoutesTopologyDirty(controller);
|
|
25033
|
+
ctx.scanService?.markDirty();
|
|
25034
|
+
const notificationFiles = /* @__PURE__ */ new Set();
|
|
25035
|
+
for (const owner of declarationOwners) if (owner !== changedSource) notificationFiles.add(owner);
|
|
25036
|
+
if (appEntryPath) notificationFiles.add(appEntryPath);
|
|
25037
|
+
for (const server of servers) for (const file of notificationFiles) server.watcher.emit("change", file);
|
|
25038
|
+
}
|
|
25039
|
+
/**
|
|
25040
|
+
* 启动 chokidar 监听页面路由源文件及其外部声明依赖所在目录的增删。
|
|
25041
|
+
* Rolldown 的 watcher 不会为新建文件触发 watchChange,
|
|
25042
|
+
* 因此需要独立的文件监听来补偿。
|
|
25043
|
+
*
|
|
25044
|
+
* 注意:chokidar v5 在 macOS 上使用 glob 模式时无法检测新建文件,
|
|
25045
|
+
* 必须直接监听目录,然后在事件回调中按扩展名过滤。
|
|
25046
|
+
*
|
|
25047
|
+
* 生命周期:watcher 注册到 sidecarWatcherMap,由 watcherService.closeAll()
|
|
25048
|
+
* 统一回收,不在 closeBundle 中销毁(build watch 模式下 closeBundle 每次
|
|
25049
|
+
* 重编译都会触发,提前销毁会导致后续文件变更无法感知)。
|
|
25050
|
+
*/
|
|
24460
25051
|
function startRouteFileWatcher() {
|
|
24461
25052
|
const configService = ctx.configService;
|
|
24462
25053
|
if (!configService) return;
|
|
24463
25054
|
const { autoRoutesConfig, matcher: resolvedMatcher } = resolveAutoRoutesMatcherContext(ctx);
|
|
24464
|
-
const allowedExtensions = new Set(vueExtensions.map((ext) => `.${ext}`));
|
|
25055
|
+
const allowedExtensions = new Set([...vueExtensions, ...scriptExtensions].map((ext) => `.${ext}`));
|
|
24465
25056
|
const watchDirs = collectAutoRoutesWatchDirs(service.getWatchDirectories(), resolvedMatcher.getWatchRoots(configService.absoluteSrcRoot));
|
|
24466
25057
|
if (!shouldStartAutoRoutesWatcher({
|
|
24467
|
-
routeWatcherStarted,
|
|
25058
|
+
routeWatcherStarted: false,
|
|
24468
25059
|
isDev: configService.isDev,
|
|
24469
25060
|
autoRoutesEnabled: autoRoutesConfig.enabled,
|
|
24470
25061
|
autoRoutesWatch: autoRoutesConfig.watch,
|
|
24471
25062
|
serviceEnabled: service.isEnabled(),
|
|
24472
25063
|
watchDirsLength: watchDirs.length
|
|
24473
25064
|
})) return;
|
|
25065
|
+
const subscriberId = resolvedConfig?.weappVite?.runtime ?? "miniprogram";
|
|
25066
|
+
const { sidecarWatcherMap } = ctx.runtimeState.watcher;
|
|
25067
|
+
const activeWatcher = sidecarWatcherMap.get(ROUTE_WATCHER_KEY);
|
|
25068
|
+
if (isAutoRoutesWatcherController(activeWatcher)) {
|
|
25069
|
+
activeWatcher.addWatchTargets(watchDirs);
|
|
25070
|
+
activeWatcher.subscribers.set(subscriberId, watcherSubscriber);
|
|
25071
|
+
return;
|
|
25072
|
+
}
|
|
25073
|
+
if (activeWatcher) return;
|
|
25074
|
+
const subscribers = /* @__PURE__ */ new Map([[subscriberId, watcherSubscriber]]);
|
|
24474
25075
|
const watcher = chokidar.watch(watchDirs, createSidecarWatchOptions(configService, {
|
|
24475
25076
|
ignoreInitial: true,
|
|
24476
25077
|
persistent: true,
|
|
@@ -24479,23 +25080,43 @@ function createAutoRoutesPlugin(ctx) {
|
|
|
24479
25080
|
pollInterval: 20
|
|
24480
25081
|
}
|
|
24481
25082
|
}));
|
|
25083
|
+
const sidecarWatcher = createAutoRoutesSidecarWatcher(watcher);
|
|
25084
|
+
const controller = {
|
|
25085
|
+
addWatchTargets(paths) {
|
|
25086
|
+
watcher.add(paths);
|
|
25087
|
+
},
|
|
25088
|
+
subscribers,
|
|
25089
|
+
async close() {
|
|
25090
|
+
if (sidecarWatcherMap.get(ROUTE_WATCHER_KEY) === controller) sidecarWatcherMap.delete(ROUTE_WATCHER_KEY);
|
|
25091
|
+
controller.subscribers.clear();
|
|
25092
|
+
await sidecarWatcher.close();
|
|
25093
|
+
}
|
|
25094
|
+
};
|
|
24482
25095
|
watcher.on("add", (filePath) => {
|
|
24483
|
-
if (!isAutoRoutesWatchFile(filePath, allowedExtensions, isPagesRelatedPath)) return;
|
|
25096
|
+
if (!isAutoRoutesWatchFile(filePath, allowedExtensions, isPagesRelatedPath, service.isPageDeclarationSource)) return;
|
|
24484
25097
|
logger_default.info(`[auto-routes:watch] 新增路由文件 ${configService.relativeCwd(filePath)}`);
|
|
24485
|
-
handleRouteStructureChange(filePath, "create")
|
|
25098
|
+
handleRouteStructureChange(filePath, "create", controller).catch((error) => {
|
|
25099
|
+
reportRouteStructureChangeError(filePath, "create", error, controller);
|
|
25100
|
+
});
|
|
24486
25101
|
});
|
|
24487
25102
|
watcher.on("unlink", (filePath) => {
|
|
24488
|
-
if (!isAutoRoutesWatchFile(filePath, allowedExtensions, isPagesRelatedPath)) return;
|
|
25103
|
+
if (!isAutoRoutesWatchFile(filePath, allowedExtensions, isPagesRelatedPath, service.isPageDeclarationSource)) return;
|
|
24489
25104
|
logger_default.info(`[auto-routes:watch] 删除路由文件 ${configService.relativeCwd(filePath)}`);
|
|
24490
|
-
handleRouteStructureChange(filePath, "delete")
|
|
25105
|
+
handleRouteStructureChange(filePath, "delete", controller).catch((error) => {
|
|
25106
|
+
reportRouteStructureChangeError(filePath, "delete", error, controller);
|
|
25107
|
+
});
|
|
24491
25108
|
});
|
|
24492
|
-
|
|
24493
|
-
sidecarWatcherMap.set(ROUTE_WATCHER_KEY, createAutoRoutesSidecarWatcher(watcher));
|
|
24494
|
-
routeWatcherStarted = true;
|
|
25109
|
+
sidecarWatcherMap.set(ROUTE_WATCHER_KEY, controller);
|
|
24495
25110
|
}
|
|
24496
25111
|
return {
|
|
24497
25112
|
name: "weapp-vite:auto-routes",
|
|
24498
25113
|
enforce: "pre",
|
|
25114
|
+
config() {
|
|
25115
|
+
return { resolve: { alias: [{
|
|
25116
|
+
find: WEVU_AUTO_ROUTES_MODULE_ID,
|
|
25117
|
+
replacement: WEVU_AUTO_ROUTES_VIRTUAL_MODULE_ID
|
|
25118
|
+
}] } };
|
|
25119
|
+
},
|
|
24499
25120
|
configResolved(config) {
|
|
24500
25121
|
resolvedConfig = config;
|
|
24501
25122
|
refreshAutoRoutesAliasTargets();
|
|
@@ -24504,6 +25125,7 @@ function createAutoRoutesPlugin(ctx) {
|
|
|
24504
25125
|
devServer = server;
|
|
24505
25126
|
},
|
|
24506
25127
|
buildStart() {
|
|
25128
|
+
registerPageDeclarationSourceResolver(this);
|
|
24507
25129
|
refreshAutoRoutesAliasTargets();
|
|
24508
25130
|
startRouteFileWatcher();
|
|
24509
25131
|
},
|
|
@@ -24518,50 +25140,111 @@ function createAutoRoutesPlugin(ctx) {
|
|
|
24518
25140
|
}
|
|
24519
25141
|
},
|
|
24520
25142
|
async load(id) {
|
|
24521
|
-
|
|
25143
|
+
const resolvedId = resolveAutoRoutesVirtualId(id, autoRoutesAliasTargets);
|
|
25144
|
+
if (!resolvedId) return null;
|
|
25145
|
+
registerPageDeclarationSourceResolver(this);
|
|
25146
|
+
if (resolvedId === WEVU_AUTO_ROUTES_RESOLVED_MODULE_ID$1 && !service.isEnabled()) this.error(`${WEVU_AUTO_ROUTES_MODULE_ID} 需要启用 weapp.autoRoutes。`);
|
|
24522
25147
|
await service.ensureFresh();
|
|
24523
|
-
if (isAutoRoutesWatchMode(ctx.configService)) addAutoRoutesWatchTargets(this, {
|
|
25148
|
+
if (isAutoRoutesWatchMode(ctx.configService)) addAutoRoutesWatchTargets(resolvedConfig?.command === "serve" ? { addWatchFile: (file) => devServer?.watcher.add(file) } : this, {
|
|
24524
25149
|
files: service.getWatchFiles(),
|
|
24525
|
-
directories: service.getWatchDirectories()
|
|
25150
|
+
directories: resolvedConfig?.command === "serve" ? [] : service.getWatchDirectories()
|
|
24526
25151
|
});
|
|
24527
25152
|
startRouteFileWatcher();
|
|
25153
|
+
if (resolvedConfig?.weappVite?.runtime === "web") servedRouteSignature ??= service.getSignature();
|
|
24528
25154
|
return {
|
|
24529
|
-
code: service.getModuleCode(),
|
|
25155
|
+
code: resolvedId === WEVU_AUTO_ROUTES_RESOLVED_MODULE_ID$1 ? service.getNamedModuleCode() : service.getModuleCode(),
|
|
24530
25156
|
map: { mappings: "" }
|
|
24531
25157
|
};
|
|
24532
25158
|
},
|
|
25159
|
+
async transform(code, id) {
|
|
25160
|
+
if (!mayContainPageDeclaration(code)) return null;
|
|
25161
|
+
const normalizedId = normalizeFsResolvedId(id);
|
|
25162
|
+
if (!isPageScriptTransformRequest(id, normalizedId)) return null;
|
|
25163
|
+
registerPageDeclarationSourceResolver(this);
|
|
25164
|
+
await service.ensureFresh();
|
|
25165
|
+
startRouteFileWatcher();
|
|
25166
|
+
if (!service.isPageDeclarationSource(normalizedId)) return null;
|
|
25167
|
+
const stripped = stripPageDeclaration(code, id);
|
|
25168
|
+
return stripped ? {
|
|
25169
|
+
code: stripped.code,
|
|
25170
|
+
map: normalizeEncodedSourceMapLike(stripped.map)
|
|
25171
|
+
} : null;
|
|
25172
|
+
},
|
|
24533
25173
|
shouldTransformCachedModule({ id }) {
|
|
24534
25174
|
return autoRoutesTopologyDirtyEntries.delete(id) || void 0;
|
|
24535
25175
|
},
|
|
24536
25176
|
async watchChange(id, change) {
|
|
25177
|
+
registerPageDeclarationSourceResolver(this);
|
|
24537
25178
|
const event = change?.event;
|
|
24538
25179
|
if (service.isRouteFile(id)) {
|
|
24539
25180
|
if (resolvedConfig?.command === "serve" && event === "update") return;
|
|
24540
|
-
await service.handleFileChange(id, event);
|
|
25181
|
+
await service.handleFileChange(id, resolveAutoRoutesWatchChangeEvent(event) ?? event);
|
|
25182
|
+
startRouteFileWatcher();
|
|
24541
25183
|
return;
|
|
24542
25184
|
}
|
|
24543
25185
|
if (!isPagesRelatedPath(id)) return;
|
|
24544
25186
|
const resolvedEvent = resolveAutoRoutesWatchChangeEvent(event);
|
|
24545
|
-
if (resolvedEvent)
|
|
25187
|
+
if (resolvedEvent) {
|
|
25188
|
+
await service.handleFileChange(id, resolvedEvent);
|
|
25189
|
+
startRouteFileWatcher();
|
|
25190
|
+
}
|
|
24546
25191
|
},
|
|
24547
25192
|
async handleHotUpdate(context) {
|
|
25193
|
+
const changedSource = normalizeFsResolvedId(context.file);
|
|
25194
|
+
const webRuntime = resolvedConfig?.weappVite?.runtime === "web";
|
|
25195
|
+
const topologyChanged = webRuntime && autoRoutesTopologyDirtyEntries.delete(changedSource);
|
|
25196
|
+
const declarationOwners = new Set(service.getPageDeclarationOwners(changedSource));
|
|
24548
25197
|
const routeFile = service.isRouteFile(context.file);
|
|
24549
25198
|
const hotUpdateAction = resolveAutoRoutesHotUpdateAction(resolvedConfig?.command, {
|
|
24550
25199
|
isRouteFile: routeFile,
|
|
24551
25200
|
isPagesRelatedPath: routeFile ? false : isPagesRelatedPath(context.file)
|
|
24552
25201
|
});
|
|
24553
|
-
if (!hotUpdateAction.shouldHandle) return;
|
|
25202
|
+
if (!hotUpdateAction.shouldHandle && !topologyChanged) return;
|
|
24554
25203
|
let didChangeRoutes = false;
|
|
24555
|
-
if (hotUpdateAction.shouldUpdateRouteFile)
|
|
24556
|
-
|
|
24557
|
-
|
|
24558
|
-
|
|
24559
|
-
|
|
25204
|
+
if (hotUpdateAction.shouldUpdateRouteFile) {
|
|
25205
|
+
didChangeRoutes = await service.handleFileChange(context.file, "update");
|
|
25206
|
+
startRouteFileWatcher();
|
|
25207
|
+
for (const owner of service.getPageDeclarationOwners(changedSource)) declarationOwners.add(owner);
|
|
25208
|
+
}
|
|
25209
|
+
declarationOwners.delete(changedSource);
|
|
25210
|
+
if (resolvedConfig?.command === "serve" && routeFile && !didChangeRoutes && declarationOwners.size === 0) return;
|
|
25211
|
+
const signature = webRuntime ? service.getSignature() : void 0;
|
|
25212
|
+
const reloadRoutes = webRuntime && (topologyChanged || servedRouteSignature !== void 0 && signature !== servedRouteSignature);
|
|
25213
|
+
const modules = new Set(!webRuntime || reloadRoutes ? AUTO_ROUTES_RESOLVED_IDS.map((id) => context.server.moduleGraph.getModuleById(id)).filter((module) => Boolean(module)) : context.modules);
|
|
25214
|
+
for (const owner of declarationOwners) {
|
|
25215
|
+
const ownerModules = context.server.moduleGraph.getModulesByFile(owner);
|
|
25216
|
+
if (ownerModules) {
|
|
25217
|
+
for (const module of ownerModules) modules.add(module);
|
|
25218
|
+
continue;
|
|
25219
|
+
}
|
|
25220
|
+
const ownerModule = context.server.moduleGraph.getModuleById(owner);
|
|
25221
|
+
if (ownerModule) modules.add(ownerModule);
|
|
25222
|
+
}
|
|
25223
|
+
if (topologyChanged) for (const module of context.modules) modules.add(module);
|
|
25224
|
+
if (modules.size > 0) {
|
|
25225
|
+
if (reloadRoutes) {
|
|
25226
|
+
servedRouteSignature = signature;
|
|
25227
|
+
return collectAutoRoutesReloadModules(modules);
|
|
25228
|
+
}
|
|
25229
|
+
return [...modules];
|
|
25230
|
+
}
|
|
25231
|
+
return context.modules.filter((module) => {
|
|
25232
|
+
return module.id !== null && (AUTO_ROUTES_RESOLVED_IDS.includes(module.id) || declarationOwners.has(normalizeFsResolvedId(module.id)));
|
|
25233
|
+
});
|
|
25234
|
+
},
|
|
25235
|
+
async closeBundle() {
|
|
25236
|
+
if (resolvedConfig?.command !== "serve") return;
|
|
25237
|
+
const watcher = ctx.runtimeState.watcher.sidecarWatcherMap.get(ROUTE_WATCHER_KEY);
|
|
25238
|
+
const subscriberId = resolvedConfig.weappVite?.runtime ?? "miniprogram";
|
|
25239
|
+
if (!isAutoRoutesWatcherController(watcher) || watcher.subscribers.get(subscriberId) !== watcherSubscriber) return;
|
|
25240
|
+
watcher.subscribers.delete(subscriberId);
|
|
25241
|
+
if (watcher.subscribers.size === 0) await watcher.close();
|
|
24560
25242
|
}
|
|
24561
25243
|
};
|
|
24562
25244
|
}
|
|
24563
25245
|
function autoRoutes(ctx) {
|
|
24564
|
-
|
|
25246
|
+
if (!ctx.autoRoutesService || !ctx.configService) return [];
|
|
25247
|
+
return [createAutoRoutesPlugin(ctx, ctx.autoRoutesService)];
|
|
24565
25248
|
}
|
|
24566
25249
|
//#endregion
|
|
24567
25250
|
//#region src/plugins/hooks/useLoadEntry/autoImport.ts
|
|
@@ -25059,13 +25742,24 @@ function findNativePageOptionsObject(ast) {
|
|
|
25059
25742
|
return matched;
|
|
25060
25743
|
}
|
|
25061
25744
|
function stripDefinePageMetaCalls(ast) {
|
|
25745
|
+
const calls = new Set(collectPageMetaCallsFromPrograms({ script: ast }));
|
|
25062
25746
|
let mutated = false;
|
|
25063
|
-
traverse(ast, {
|
|
25064
|
-
|
|
25065
|
-
|
|
25066
|
-
|
|
25067
|
-
|
|
25068
|
-
|
|
25747
|
+
traverse(ast, {
|
|
25748
|
+
ImportDeclaration(path) {
|
|
25749
|
+
if (path.node.source.value !== "wevu" || path.node.importKind === "type") return;
|
|
25750
|
+
const specifiers = path.node.specifiers.filter((specifier) => !t.isImportSpecifier(specifier) || (t.isIdentifier(specifier.imported) ? specifier.imported.name : specifier.imported.value) !== WEVU_DEFINE_PAGE_META_MACRO || specifier.importKind === "type");
|
|
25751
|
+
if (specifiers.length === path.node.specifiers.length) return;
|
|
25752
|
+
mutated = true;
|
|
25753
|
+
path.node.specifiers = specifiers;
|
|
25754
|
+
if (!path.node.specifiers.length) path.remove();
|
|
25755
|
+
},
|
|
25756
|
+
ExpressionStatement(path) {
|
|
25757
|
+
const expression = path.node.expression;
|
|
25758
|
+
if (!t.isCallExpression(expression) || !calls.has(expression)) return;
|
|
25759
|
+
mutated = true;
|
|
25760
|
+
path.remove();
|
|
25761
|
+
}
|
|
25762
|
+
});
|
|
25069
25763
|
return mutated;
|
|
25070
25764
|
}
|
|
25071
25765
|
//#endregion
|
|
@@ -25200,7 +25894,6 @@ function createCompilerPageLayoutPlanSignature(plan) {
|
|
|
25200
25894
|
}
|
|
25201
25895
|
//#endregion
|
|
25202
25896
|
//#region src/plugins/vue/transform/pageLayout/meta.ts
|
|
25203
|
-
const PAGE_META_MACRO_NAME = "definePageMeta";
|
|
25204
25897
|
const analyzedPageLayoutSourceCache = /* @__PURE__ */ new Map();
|
|
25205
25898
|
function unwrapStaticExpression(node) {
|
|
25206
25899
|
if (t.isTSAsExpression(node) || t.isTSSatisfiesExpression(node) || t.isTSNonNullExpression(node) || t.isTypeCastExpression(node)) return unwrapStaticExpression(node.expression);
|
|
@@ -25282,14 +25975,10 @@ function extractLayoutValueFromObject(node, filename) {
|
|
|
25282
25975
|
}
|
|
25283
25976
|
return layout;
|
|
25284
25977
|
}
|
|
25285
|
-
function
|
|
25978
|
+
function extractLayoutFromPrograms(programs, filename) {
|
|
25286
25979
|
let layout;
|
|
25287
|
-
|
|
25288
|
-
for (const
|
|
25289
|
-
if (!t.isExpressionStatement(statement) || !t.isCallExpression(statement.expression)) continue;
|
|
25290
|
-
const call = statement.expression;
|
|
25291
|
-
if (!t.isIdentifier(call.callee, { name: PAGE_META_MACRO_NAME })) continue;
|
|
25292
|
-
macroCount += 1;
|
|
25980
|
+
const calls = collectPageMetaCallsFromPrograms(programs);
|
|
25981
|
+
for (const call of calls) {
|
|
25293
25982
|
if (call.arguments.length !== 1) throw new Error(`${filename} 中 definePageMeta() 必须且只能接收一个对象参数。`);
|
|
25294
25983
|
const firstArg = call.arguments[0];
|
|
25295
25984
|
if (t.isSpreadElement(firstArg) || !t.isExpression(firstArg)) throw new Error(`${filename} 中 definePageMeta() 仅支持对象字面量参数。`);
|
|
@@ -25297,7 +25986,7 @@ function extractLayoutFromProgram(ast, filename) {
|
|
|
25297
25986
|
if (!t.isObjectExpression(normalized)) throw new Error(`${filename} 中 definePageMeta() 仅支持对象字面量参数。`);
|
|
25298
25987
|
layout = extractLayoutValueFromObject(normalized, filename);
|
|
25299
25988
|
}
|
|
25300
|
-
if (
|
|
25989
|
+
if (calls.length > 1) throw new Error(`${filename} 中 definePageMeta() 只能声明一次。`);
|
|
25301
25990
|
return layout;
|
|
25302
25991
|
}
|
|
25303
25992
|
function hasSetPageLayoutCallInProgram(ast) {
|
|
@@ -25339,25 +26028,21 @@ function analyzeVueScriptBlocks(source, filename) {
|
|
|
25339
26028
|
function analyzePageLayoutSourceUncached(source, filename) {
|
|
25340
26029
|
if (filename.endsWith(".vue")) {
|
|
25341
26030
|
const { scriptAst, scriptSetupAst } = analyzeVueScriptBlocks(source, filename);
|
|
25342
|
-
|
|
25343
|
-
|
|
25344
|
-
|
|
25345
|
-
|
|
25346
|
-
if (layoutMeta !== void 0 && setupLayout !== void 0) throw new Error(`${filename} 中的 <script> 与 <script setup> 不能同时声明 definePageMeta().`);
|
|
25347
|
-
if (setupLayout !== void 0) layoutMeta = setupLayout;
|
|
25348
|
-
}
|
|
26031
|
+
const layoutMeta = extractLayoutFromPrograms({
|
|
26032
|
+
script: scriptAst,
|
|
26033
|
+
scriptSetup: scriptSetupAst
|
|
26034
|
+
}, filename);
|
|
25349
26035
|
const dynamicSwitch = Boolean(scriptAst && hasSetPageLayoutCallInProgram(scriptAst) || scriptSetupAst && hasSetPageLayoutCallInProgram(scriptSetupAst));
|
|
25350
|
-
const dynamicPropKeys = dynamicSwitch ? Array.from(/* @__PURE__ */ new Set([...scriptAst ? collectSetPageLayoutPropKeysFromProgram(scriptAst) : [], ...scriptSetupAst ? collectSetPageLayoutPropKeysFromProgram(scriptSetupAst) : []])) : [];
|
|
25351
26036
|
return {
|
|
25352
26037
|
layoutMeta,
|
|
25353
26038
|
dynamicSwitch,
|
|
25354
|
-
dynamicPropKeys
|
|
26039
|
+
dynamicPropKeys: dynamicSwitch ? Array.from(/* @__PURE__ */ new Set([...scriptAst ? collectSetPageLayoutPropKeysFromProgram(scriptAst) : [], ...scriptSetupAst ? collectSetPageLayoutPropKeysFromProgram(scriptSetupAst) : []])) : []
|
|
25355
26040
|
};
|
|
25356
26041
|
}
|
|
25357
26042
|
const ast = parseScriptAst(source);
|
|
25358
26043
|
const dynamicSwitch = hasSetPageLayoutCallInProgram(ast);
|
|
25359
26044
|
return {
|
|
25360
|
-
layoutMeta:
|
|
26045
|
+
layoutMeta: extractLayoutFromPrograms({ script: ast }, filename),
|
|
25361
26046
|
dynamicSwitch,
|
|
25362
26047
|
dynamicPropKeys: dynamicSwitch ? collectSetPageLayoutPropKeysFromProgram(ast) : []
|
|
25363
26048
|
};
|
|
@@ -25391,7 +26076,6 @@ const TRAILING_INDEX_RE = /\/index$/;
|
|
|
25391
26076
|
const LEADING_SLASHES_RE = /^\/+/;
|
|
25392
26077
|
const ROUTE_RULE_GLOB_TOKEN_RE = /[*?[\]{}()!+@]/g;
|
|
25393
26078
|
const layoutFilesCache = /* @__PURE__ */ new Map();
|
|
25394
|
-
const PAGE_META_HINT = "definePageMeta";
|
|
25395
26079
|
const SET_PAGE_LAYOUT_HINT = "setPageLayout";
|
|
25396
26080
|
function normalizePageRouteCandidates(filename, configService) {
|
|
25397
26081
|
const fullPath = `/${toPosixPath(configService.relativeOutputPath(removeFileExtension(filename))).replace(LEADING_SLASHES_RE, "")}`;
|
|
@@ -25536,7 +26220,7 @@ function invalidateResolvedPageLayoutsCache(absoluteSrcRoot) {
|
|
|
25536
26220
|
layoutFilesCache.delete(normalizeComparablePath(absoluteSrcRoot));
|
|
25537
26221
|
}
|
|
25538
26222
|
async function resolvePageLayoutPlan(source, filename, configService) {
|
|
25539
|
-
const hasPageMetaHint = source
|
|
26223
|
+
const hasPageMetaHint = mayContainPageMeta(source);
|
|
25540
26224
|
const hasDynamicLayoutHint = source.includes(SET_PAGE_LAYOUT_HINT);
|
|
25541
26225
|
const analyzedSource = hasPageMetaHint || hasDynamicLayoutHint ? analyzePageLayoutSource(source, filename) : void 0;
|
|
25542
26226
|
const layoutMeta = (hasPageMetaHint ? analyzedSource?.layoutMeta : void 0) ?? resolveRouteRuleLayoutMeta(filename, configService);
|
|
@@ -26541,6 +27225,7 @@ async function emitEntryOutput(options) {
|
|
|
26541
27225
|
if (error && typeof error === "object" && "code" in error && error.code === "ENOENT" && configService.isDev && !await fs$1.pathExists(id)) return;
|
|
26542
27226
|
throw error;
|
|
26543
27227
|
}
|
|
27228
|
+
if (type === "page" && !NON_VUE_PAGE_RE.test(id) && mayContainPageDeclaration(code)) code = stripPageDeclaration(code, id)?.code ?? code;
|
|
26544
27229
|
if (type === "page" && templatePath && !NON_VUE_PAGE_RE.test(id)) {
|
|
26545
27230
|
const layoutStartedAt = performance$1.now();
|
|
26546
27231
|
try {
|
|
@@ -26663,7 +27348,7 @@ const VUE_JSON_BLOCK_RE = /<json\b[^>]*>[\s\S]*?<\/json>/gi;
|
|
|
26663
27348
|
const VUE_JSON_MACRO_HINT_RE = /\bdefine(?:App|Page|Component|Sitemap|Theme)Json\s*\(/;
|
|
26664
27349
|
const NO_VUE_CONFIG_SIGNATURE = "no-vue-config";
|
|
26665
27350
|
function hasPageLayoutSourceHint(source) {
|
|
26666
|
-
return source
|
|
27351
|
+
return mayContainPageMeta(source) || source.includes("setPageLayout");
|
|
26667
27352
|
}
|
|
26668
27353
|
function hashText(value) {
|
|
26669
27354
|
return createHash("sha256").update(value).digest("hex").slice(0, 16);
|
|
@@ -27483,6 +28168,7 @@ function useLoadEntry(ctx, options) {
|
|
|
27483
28168
|
},
|
|
27484
28169
|
async emitDirtyEntries() {
|
|
27485
28170
|
entryChunkLifecycle.beginBuild();
|
|
28171
|
+
ctx.runtimeState.build.hmr.forceEmitUnchangedChunks = false;
|
|
27486
28172
|
if (!dirtyEntrySet.size) {
|
|
27487
28173
|
options?.hmr?.setDidEmitAllEntries?.(false);
|
|
27488
28174
|
options?.hmr?.setLastEmittedEntries?.(/* @__PURE__ */ new Set());
|
|
@@ -27517,6 +28203,7 @@ function useLoadEntry(ctx, options) {
|
|
|
27517
28203
|
rootInputIds
|
|
27518
28204
|
});
|
|
27519
28205
|
const pendingEntryIds = pendingResolution.pending;
|
|
28206
|
+
ctx.runtimeState.build.hmr.forceEmitUnchangedChunks = [...pendingEntryIds].some((entryId) => dirtyEntryReasons.get(entryId) !== "metadata");
|
|
27520
28207
|
const pending = [];
|
|
27521
28208
|
chunkEmitStats.chunkEmitCount = 0;
|
|
27522
28209
|
chunkEmitStats.emitFileMs = 0;
|
|
@@ -29559,42 +30246,6 @@ function injectSharedStyleImports(css, modulePath, fileName, sharedStyles, confi
|
|
|
29559
30246
|
return prependSharedStyleImports(css, statements);
|
|
29560
30247
|
}
|
|
29561
30248
|
//#endregion
|
|
29562
|
-
//#region src/plugins/utils/parse.ts
|
|
29563
|
-
function hasOwn$2(source, key) {
|
|
29564
|
-
return Object.prototype.hasOwnProperty.call(source, key);
|
|
29565
|
-
}
|
|
29566
|
-
/**
|
|
29567
|
-
* 参考:https://github.com/tailwindlabs/tailwindcss/blob/main/packages/%40tailwindcss-vite/src/index.ts
|
|
29568
|
-
* 解析请求ID,返回包含文件名和查询参数的对象。
|
|
29569
|
-
* 如果查询参数中包含'wxss',则将其值设置为true。
|
|
29570
|
-
* @param id - 请求ID,格式为'filename?query'
|
|
29571
|
-
* @returns 解析后的请求响应对象
|
|
29572
|
-
*/
|
|
29573
|
-
function parseRequest(id) {
|
|
29574
|
-
const [filename, rawQuery] = id.split(`?`, 2);
|
|
29575
|
-
const query = {};
|
|
29576
|
-
if (rawQuery) {
|
|
29577
|
-
const params = new URLSearchParams(rawQuery);
|
|
29578
|
-
for (const [key, value] of params.entries()) query[key] = value;
|
|
29579
|
-
if (hasOwn$2(query, "wxss")) query.wxss = true;
|
|
29580
|
-
}
|
|
29581
|
-
return {
|
|
29582
|
-
filename,
|
|
29583
|
-
query
|
|
29584
|
-
};
|
|
29585
|
-
}
|
|
29586
|
-
/**
|
|
29587
|
-
* 根据请求响应获取 CSS 文件的真实路径。
|
|
29588
|
-
* 如果请求中包含 wxss 查询参数,则将文件扩展名更改为 'wxss'。
|
|
29589
|
-
* @param res - 解析请求的响应对象,包含文件名和查询参数。
|
|
29590
|
-
* @returns 返回文件的真实路径。
|
|
29591
|
-
*/
|
|
29592
|
-
function getCssRealPath(res) {
|
|
29593
|
-
if (typeof res.query.nativeStyle === "string" && res.query.nativeStyle) return changeFileExtension(res.filename, res.query.nativeStyle);
|
|
29594
|
-
if (res.query.wxss) return changeFileExtension(res.filename, "wxss");
|
|
29595
|
-
return res.filename;
|
|
29596
|
-
}
|
|
29597
|
-
//#endregion
|
|
29598
30249
|
//#region src/plugins/css/styleOwnership.ts
|
|
29599
30250
|
/** 在样式模块上保存实际消费的源文件,避免把仅用于失效的图边当作产物所有权。 */
|
|
29600
30251
|
function createStyleSourceMeta(sources) {
|
|
@@ -29629,6 +30280,16 @@ const LEADING_BLANK_LINES_RE = /^(?:[ \t]*\r?\n)+/;
|
|
|
29629
30280
|
const TAILWIND_CONTENT_HMR_NONCE_RE = /\n\/\* weapp-vite tailwind-content [^*\n]+ \*\/$/;
|
|
29630
30281
|
const VITE_PREPROCESS_STYLE_RE = /\.(?:acss|css|less|sass|scss|styl|stylus|pcss|postcss|sss)$/;
|
|
29631
30282
|
const TAILWIND_GENERATOR_PLACEHOLDER = "/*! weapp-tailwindcss generator-placeholder */";
|
|
30283
|
+
const VITE_STYLE_ASSET_PLACEHOLDER_RE = /__VITE_ASSET__([\w$]+)__(?:\$_(.*?)__)?/g;
|
|
30284
|
+
function resolveViteStyleAssetPlaceholders(source, fileName, pluginCtx) {
|
|
30285
|
+
if (!source.includes("__VITE_ASSET__") || typeof pluginCtx.getFileName !== "function") return source;
|
|
30286
|
+
return source.replace(VITE_STYLE_ASSET_PLACEHOLDER_RE, (_placeholder, referenceId, postfix = "") => {
|
|
30287
|
+
const assetFileName = toPosixPath(pluginCtx.getFileName(referenceId));
|
|
30288
|
+
const relativePath = path.posix.relative(path.posix.dirname(toPosixPath(fileName)), assetFileName);
|
|
30289
|
+
const assetUrl = relativePath.startsWith(".") ? relativePath : `./${relativePath}`;
|
|
30290
|
+
return `${encodeURI(assetUrl)}${postfix}`;
|
|
30291
|
+
});
|
|
30292
|
+
}
|
|
29632
30293
|
const pendingOwnerStyleSources = /* @__PURE__ */ new WeakMap();
|
|
29633
30294
|
function consumePendingOwnerStyleSources(ctx) {
|
|
29634
30295
|
const sources = pendingOwnerStyleSources.get(ctx);
|
|
@@ -29756,7 +30417,8 @@ function emitCssAssetIfChanged(ctx, pluginCtx, bundle, fileName, source, options
|
|
|
29756
30417
|
const cache = ctx.runtimeState?.css?.emittedSource;
|
|
29757
30418
|
const existing = bundle[fileName];
|
|
29758
30419
|
const forceEmit = hasTailwindContentDirtyReason(ctx) || hasManagedTailwindcssOutputMarker(source);
|
|
29759
|
-
const
|
|
30420
|
+
const resolvedSource = resolveViteStyleAssetPlaceholders(source, fileName, pluginCtx);
|
|
30421
|
+
const emittedSource = appendTailwindContentHmrNonce(ctx, resolvedSource);
|
|
29760
30422
|
if (existing?.type === "asset") {
|
|
29761
30423
|
const current = existing.source?.toString?.() ?? "";
|
|
29762
30424
|
if (!forceEmit && isUnchangedDevHmrStyleAsset(ctx, normalizedFileName, current, emittedSource)) {
|
|
@@ -29764,17 +30426,17 @@ function emitCssAssetIfChanged(ctx, pluginCtx, bundle, fileName, source, options
|
|
|
29764
30426
|
return false;
|
|
29765
30427
|
}
|
|
29766
30428
|
if (current !== emittedSource) existing.source = emittedSource;
|
|
29767
|
-
cache?.set(normalizedFileName,
|
|
30429
|
+
cache?.set(normalizedFileName, resolvedSource);
|
|
29768
30430
|
return true;
|
|
29769
30431
|
}
|
|
29770
|
-
if (!forceEmit && cache?.get(normalizedFileName) ===
|
|
30432
|
+
if (!forceEmit && cache?.get(normalizedFileName) === resolvedSource) return false;
|
|
29771
30433
|
pluginCtx.emitFile({
|
|
29772
30434
|
type: "asset",
|
|
29773
30435
|
fileName,
|
|
29774
30436
|
...options?.originalFileName ? { originalFileName: options.originalFileName } : {},
|
|
29775
30437
|
source: emittedSource
|
|
29776
30438
|
});
|
|
29777
|
-
cache?.set(normalizedFileName,
|
|
30439
|
+
cache?.set(normalizedFileName, resolvedSource);
|
|
29778
30440
|
return true;
|
|
29779
30441
|
}
|
|
29780
30442
|
function injectSharedStyleImportsCached(css, modulePath, fileName, sharedStyles, configService, cache) {
|
|
@@ -29914,7 +30576,7 @@ async function handleBundleEntry(ctx, bundle, bundleKey, asset, configService, s
|
|
|
29914
30576
|
const { css, dependencies } = await preprocessStyleSource(preprocessInput, preprocessId, resolvedConfig, { enabled: shouldPreprocess });
|
|
29915
30577
|
syncCssImportDependencies(ctx, preprocessId, freshHmrStyleSourcePath ? preprocessInput : graphSource, dependencies);
|
|
29916
30578
|
if (typeof this.addWatchFile === "function") for (const dependency of dependencies) this.addWatchFile(normalizeWatchPath(dependency));
|
|
29917
|
-
const processedCss = await processCssWithCache(css, configService);
|
|
30579
|
+
const processedCss = resolveViteStyleAssetPlaceholders(await processCssWithCache(css, configService), fileName, this);
|
|
29918
30580
|
if (fileName !== bundleKey) {
|
|
29919
30581
|
delete bundle[bundleKey];
|
|
29920
30582
|
emitCssAssetIfChanged(ctx, this, bundle, fileName, processedCss);
|
|
@@ -30612,6 +31274,74 @@ async function flushIndependentOutputs(ctx, subPackageMeta, emitAsset) {
|
|
|
30612
31274
|
for (const output of outputs) for (const bundleOutput of getBundleOutputs(output)) emitAsset(toEmittedAsset(bundleOutput));
|
|
30613
31275
|
}
|
|
30614
31276
|
//#endregion
|
|
31277
|
+
//#region src/plugins/outputFinalizer/scopedStyles.ts
|
|
31278
|
+
const SCOPE_ATTRIBUTE_RE = /^data-v-[\w-]+$/;
|
|
31279
|
+
/** 支付宝和抖音不支持 scoped 属性选择器,使用同等优先级的 class 保留作用域。 */
|
|
31280
|
+
function normalizeClassScopedTemplate(source) {
|
|
31281
|
+
if (!source.includes("data-v-")) return source;
|
|
31282
|
+
const result = new MagicString(source);
|
|
31283
|
+
let scopes = [];
|
|
31284
|
+
let classEnd;
|
|
31285
|
+
let unquotedClass;
|
|
31286
|
+
let classes = /* @__PURE__ */ new Set();
|
|
31287
|
+
let tagEnd = 0;
|
|
31288
|
+
const parser = new Parser({
|
|
31289
|
+
onopentagname(name) {
|
|
31290
|
+
scopes = [];
|
|
31291
|
+
classEnd = void 0;
|
|
31292
|
+
unquotedClass = void 0;
|
|
31293
|
+
classes = /* @__PURE__ */ new Set();
|
|
31294
|
+
tagEnd = parser.startIndex + 1 + name.length;
|
|
31295
|
+
},
|
|
31296
|
+
onattribute(name, value, quote) {
|
|
31297
|
+
if (SCOPE_ATTRIBUTE_RE.test(name) && value === "") scopes.push(name);
|
|
31298
|
+
if (name === "class") {
|
|
31299
|
+
classEnd = parser.endIndex - (quote ? 1 : 0);
|
|
31300
|
+
classes = new Set(value.split(/\s+/));
|
|
31301
|
+
if (!quote) unquotedClass = {
|
|
31302
|
+
start: parser.startIndex,
|
|
31303
|
+
end: parser.endIndex,
|
|
31304
|
+
value
|
|
31305
|
+
};
|
|
31306
|
+
}
|
|
31307
|
+
},
|
|
31308
|
+
onopentag() {
|
|
31309
|
+
scopes = scopes.filter((scope) => !classes.has(scope));
|
|
31310
|
+
if (!scopes.length) return;
|
|
31311
|
+
if (unquotedClass) result.overwrite(unquotedClass.start, unquotedClass.end, `class="${unquotedClass.value} ${scopes.join(" ")}"`);
|
|
31312
|
+
else if (classEnd !== void 0) result.appendLeft(classEnd, ` ${scopes.join(" ")}`);
|
|
31313
|
+
else result.appendLeft(tagEnd, ` class="${scopes.join(" ")}"`);
|
|
31314
|
+
}
|
|
31315
|
+
}, {
|
|
31316
|
+
xmlMode: true,
|
|
31317
|
+
decodeEntities: false
|
|
31318
|
+
});
|
|
31319
|
+
parser.end(source);
|
|
31320
|
+
return result.toString();
|
|
31321
|
+
}
|
|
31322
|
+
function normalizeClassScopedStyle(source) {
|
|
31323
|
+
if (!source.includes("data-v-")) return source;
|
|
31324
|
+
const root = postcss.parse(source);
|
|
31325
|
+
root.walkRules((rule) => {
|
|
31326
|
+
if (!rule.selector.includes("data-v-")) return;
|
|
31327
|
+
rule.selector = selectorParser((selectors) => {
|
|
31328
|
+
selectors.walkAttributes((attribute) => {
|
|
31329
|
+
if (SCOPE_ATTRIBUTE_RE.test(attribute.attribute) && !attribute.operator) attribute.replaceWith(selectorParser.className({ value: attribute.attribute }));
|
|
31330
|
+
});
|
|
31331
|
+
}).processSync(rule.selector);
|
|
31332
|
+
});
|
|
31333
|
+
return root.toString();
|
|
31334
|
+
}
|
|
31335
|
+
/** 在 bundler 写盘前同时归一化模板和样式,也覆盖仅包含样式资源的 HMR。 */
|
|
31336
|
+
function normalizeClassScopedAssets(bundle, extensions) {
|
|
31337
|
+
for (const output of Object.values(bundle)) {
|
|
31338
|
+
if (output.type !== "asset") continue;
|
|
31339
|
+
const source = typeof output.source === "string" ? output.source : Buffer.from(output.source).toString("utf8");
|
|
31340
|
+
if (output.fileName.endsWith(`.${extensions.wxml}`)) output.source = normalizeClassScopedTemplate(source);
|
|
31341
|
+
else if (output.fileName.endsWith(`.${extensions.wxss}`)) output.source = normalizeClassScopedStyle(source);
|
|
31342
|
+
}
|
|
31343
|
+
}
|
|
31344
|
+
//#endregion
|
|
30615
31345
|
//#region src/plugins/outputFinalizer.ts
|
|
30616
31346
|
const PREPROCESSOR_STYLE_ASSET_RE = /\.(?:less|sass|scss|styl|stylus|pcss|postcss|sss)$/i;
|
|
30617
31347
|
const TEMPLATE_ASSET_RE = /\.(?:wxml|axml|swan|ttml|jxml|qml|ksml|xhsml)$/i;
|
|
@@ -30784,8 +31514,9 @@ function pruneUnchangedDevHmrOutputs(ctx, bundle, rewriteOptions, options) {
|
|
|
30784
31514
|
stabilizeWevuRuntimeChunkAccess(bundle);
|
|
30785
31515
|
}
|
|
30786
31516
|
for (const [fileName, output] of Object.entries(bundle)) {
|
|
30787
|
-
const
|
|
30788
|
-
|
|
31517
|
+
const isCurrentHmrChunk = isHmrBuild && output.type === "chunk" && (emittedChunkFileNames?.has(fileName) === true || emittedChunkFileNames?.has(output.fileName) === true);
|
|
31518
|
+
const shouldForceEmitCurrentHmrChunk = isCurrentHmrChunk && ctx.runtimeState.build.hmr.forceEmitUnchangedChunks !== false;
|
|
31519
|
+
if (isHmrBuild && output.type === "chunk" && emittedChunkFileNames?.size && !isCurrentHmrChunk) {
|
|
30789
31520
|
delete bundle[fileName];
|
|
30790
31521
|
continue;
|
|
30791
31522
|
}
|
|
@@ -30841,6 +31572,7 @@ function createOutputFinalizerPlugin(ctx, subPackageMeta) {
|
|
|
30841
31572
|
if (ctx.configService.platform === "weapp") analyzeGlassEaselBundle(ctx, outputBundle);
|
|
30842
31573
|
normalizePreprocessorStyleAssetEntries(outputBundle, assetEntries.preprocessorStyleAssets, ctx.configService.outputExtensions?.wxss, assets.stage);
|
|
30843
31574
|
normalizeTemplateAssetEntries(ctx, assetEntries.templateAssets, subPackageMeta);
|
|
31575
|
+
if (ctx.configService.platform === "alipay" || ctx.configService.platform === "tt") normalizeClassScopedAssets(outputBundle, ctx.configService.outputExtensions);
|
|
30844
31576
|
pruneUnchangedDevHmrOutputs(ctx, outputBundle, wevuRuntimeRewriteOptions, {
|
|
30845
31577
|
runtimeRewriteDone: true,
|
|
30846
31578
|
preserveCompleteBundle
|
|
@@ -33106,7 +33838,7 @@ async function resolveAppShellForCompilation(ctx, pluginCtx) {
|
|
|
33106
33838
|
if (!configService || !scanService || configService.weappLibConfig?.enabled) return;
|
|
33107
33839
|
const appEntry = await scanService.loadAppEntry();
|
|
33108
33840
|
if (!isAppVueFile(appEntry.path)) return;
|
|
33109
|
-
const { descriptor } = await readAndParseSfc(appEntry.path, createReadAndParseSfcOptions(pluginCtx, configService));
|
|
33841
|
+
const { descriptor } = await readAndParseSfc$1(appEntry.path, createReadAndParseSfcOptions(pluginCtx, configService));
|
|
33110
33842
|
if (!descriptor.template?.content.trim()) return;
|
|
33111
33843
|
return resolveAppShellLayout(configService);
|
|
33112
33844
|
}
|
|
@@ -33943,6 +34675,37 @@ function preflight(ctx) {
|
|
|
33943
34675
|
return [createPluginPruner(), createEnvSynchronizer(ctx)];
|
|
33944
34676
|
}
|
|
33945
34677
|
//#endregion
|
|
34678
|
+
//#region src/plugins/tailwindcss/imports.ts
|
|
34679
|
+
/** 只判断样式导入链的所有权;解析、条件包装与转换仍由 Tailwind 编译器负责。 */
|
|
34680
|
+
async function findManagedStyleImports(code, filename, options) {
|
|
34681
|
+
const dependencies = /* @__PURE__ */ new Set();
|
|
34682
|
+
let managed = false;
|
|
34683
|
+
const visit = async (source, importer) => {
|
|
34684
|
+
if (!source.includes("@import")) return;
|
|
34685
|
+
const requests = [];
|
|
34686
|
+
postcss.parse(source, { from: importer }).walkAtRules("import", (rule) => {
|
|
34687
|
+
const node = valueParser(rule.params).nodes[0];
|
|
34688
|
+
const value = node?.type === "string" ? node.value : node?.type === "function" && node.value === "url" ? node.nodes[0]?.value : void 0;
|
|
34689
|
+
if (value && !/^(?:[a-z]+:|\/\/|#)/i.test(value)) requests.push(value);
|
|
34690
|
+
});
|
|
34691
|
+
for (const request of requests) {
|
|
34692
|
+
const resolved = await options.resolve(request, importer, { skipSelf: true });
|
|
34693
|
+
if (!resolved || resolved.external) continue;
|
|
34694
|
+
const sourcePath = getCssRealPath(parseRequest(resolved.id));
|
|
34695
|
+
const file = normalizeManagedTailwindcssEntryPath(path$1.resolve(path$1.dirname(importer), sourcePath));
|
|
34696
|
+
if (dependencies.has(file)) continue;
|
|
34697
|
+
dependencies.add(file);
|
|
34698
|
+
if (options.isManaged(file)) managed = true;
|
|
34699
|
+
else await visit(await fs$2.readFile(file, "utf8"), file);
|
|
34700
|
+
}
|
|
34701
|
+
};
|
|
34702
|
+
await visit(code, filename);
|
|
34703
|
+
return {
|
|
34704
|
+
managed,
|
|
34705
|
+
dependencies
|
|
34706
|
+
};
|
|
34707
|
+
}
|
|
34708
|
+
//#endregion
|
|
33946
34709
|
//#region src/plugins/tailwindcss/vueStyle.ts
|
|
33947
34710
|
/** 根据 SFC 外部样式的文件身份解析入口,避免依赖编译前后 CSS 文本一致。 */
|
|
33948
34711
|
async function resolveVueStyleSource(request, resolve) {
|
|
@@ -34116,6 +34879,7 @@ function createTailwindcssPlugin(ctx) {
|
|
|
34116
34879
|
const contextualSlots = /* @__PURE__ */ new Set();
|
|
34117
34880
|
const dirtySlots = /* @__PURE__ */ new Set();
|
|
34118
34881
|
const transformedSources = /* @__PURE__ */ new Map();
|
|
34882
|
+
const importedSources = /* @__PURE__ */ new Map();
|
|
34119
34883
|
const previousEntrySources = /* @__PURE__ */ new Map();
|
|
34120
34884
|
const resolvedEntryIndexes = /* @__PURE__ */ new Set();
|
|
34121
34885
|
const loadedEntryIndexes = /* @__PURE__ */ new Set();
|
|
@@ -34242,8 +35006,8 @@ function createTailwindcssPlugin(ctx) {
|
|
|
34242
35006
|
classSet: [],
|
|
34243
35007
|
target: resolved.generatorTarget
|
|
34244
35008
|
})];
|
|
34245
|
-
const snapshot = compiler.mergeSnapshots(snapshots);
|
|
34246
|
-
const seenEntries =
|
|
35009
|
+
const snapshot = compiler.mergeSnapshots([...snapshots, ...Array.from(importedSources.values(), (source) => source.snapshot)]);
|
|
35010
|
+
const seenEntries = new Set(Array.from(importedSources.values()).flatMap((source) => source.entries));
|
|
34247
35011
|
const styleExtension = ctx.configService.outputExtensions.wxss;
|
|
34248
35012
|
const templateExtension = ctx.configService.outputExtensions.wxml;
|
|
34249
35013
|
const scriptSourceMap = Boolean(resolvedConfig?.build.sourcemap);
|
|
@@ -34301,6 +35065,65 @@ function createTailwindcssPlugin(ctx) {
|
|
|
34301
35065
|
applyOutputChunkTransform(output, transformed.code, transformed.map);
|
|
34302
35066
|
}
|
|
34303
35067
|
}
|
|
35068
|
+
function importedSourceKey(id) {
|
|
35069
|
+
const style = parseWeappVueStyleRequest(id);
|
|
35070
|
+
return style ? `${style.filename}?style=${style.index}` : id.split("?")[0];
|
|
35071
|
+
}
|
|
35072
|
+
async function transformImportedSource(code, id) {
|
|
35073
|
+
const style = parseWeappVueStyleRequest(id);
|
|
35074
|
+
const filename = requestSources.get(id) ?? style?.filename ?? normalizeFsResolvedId(id.split("?")[0], { stripLeadingNullByte: true });
|
|
35075
|
+
if (!style && !/\.(?:css|pcss|postcss)$/.test(filename)) return null;
|
|
35076
|
+
const query = new URLSearchParams(id.split("?")[1] ?? "");
|
|
35077
|
+
if (query.has("raw") || query.has("url")) return null;
|
|
35078
|
+
const imports = await findManagedStyleImports(code, filename, {
|
|
35079
|
+
resolve: this.resolve.bind(this),
|
|
35080
|
+
isManaged: (file) => isManagedTailwindcssEntry(ctx, file)
|
|
35081
|
+
});
|
|
35082
|
+
const key = importedSourceKey(id);
|
|
35083
|
+
if (!imports.managed) {
|
|
35084
|
+
const previous = importedSources.get(key);
|
|
35085
|
+
if (previous) {
|
|
35086
|
+
await (await getCompiler()).remove(previous.rootId);
|
|
35087
|
+
importedSources.delete(key);
|
|
35088
|
+
}
|
|
35089
|
+
return null;
|
|
35090
|
+
}
|
|
35091
|
+
const compiler = await getCompiler();
|
|
35092
|
+
const rootId = `${MANAGED_PLUGIN_NAME}:import:${key}`;
|
|
35093
|
+
const configuredSource = createTailwindV4SourceOptions(resolved, filename);
|
|
35094
|
+
const generated = await compiler.generate({
|
|
35095
|
+
id: rootId,
|
|
35096
|
+
target: resolved.generatorTarget,
|
|
35097
|
+
scanSources: true,
|
|
35098
|
+
sourceOptions: {
|
|
35099
|
+
...configuredSource,
|
|
35100
|
+
cssEntries: [],
|
|
35101
|
+
cssSources: [...configuredSource.cssSources ?? [], {
|
|
35102
|
+
css: code,
|
|
35103
|
+
file: filename,
|
|
35104
|
+
base: path.dirname(filename),
|
|
35105
|
+
dependencies: [...imports.dependencies]
|
|
35106
|
+
}]
|
|
35107
|
+
},
|
|
35108
|
+
bareArbitraryValues: resolved.options.arbitraryValues?.bareArbitraryValues,
|
|
35109
|
+
styleOptions: typeof resolved.options.generator === "object" ? resolved.options.generator.styleOptions : void 0
|
|
35110
|
+
});
|
|
35111
|
+
importedSources.set(key, {
|
|
35112
|
+
rootId,
|
|
35113
|
+
snapshot: generated.snapshot,
|
|
35114
|
+
entries: [...imports.dependencies].flatMap((file) => {
|
|
35115
|
+
const index = parseManagedEntryIndex(file, entryIndex);
|
|
35116
|
+
return index === void 0 ? [] : [index];
|
|
35117
|
+
})
|
|
35118
|
+
});
|
|
35119
|
+
const dependencies = /* @__PURE__ */ new Set([...imports.dependencies, ...generated.dependencies]);
|
|
35120
|
+
for (const dependency of dependencies) this.addWatchFile(dependency);
|
|
35121
|
+
return {
|
|
35122
|
+
code: await stripResidualTailwindSourceDirectives((await compiler.transformCss(generated.rawCss, generated.snapshot, { isMainChunk: filename === path.resolve(ctx.configService.absoluteSrcRoot, "app.vue") })).css),
|
|
35123
|
+
map: null,
|
|
35124
|
+
meta: createStyleSourceMeta(dependencies)
|
|
35125
|
+
};
|
|
35126
|
+
}
|
|
34304
35127
|
return [{
|
|
34305
35128
|
name: MANAGED_PLUGIN_NAME,
|
|
34306
35129
|
enforce: "pre",
|
|
@@ -34384,7 +35207,7 @@ function createTailwindcssPlugin(ctx) {
|
|
|
34384
35207
|
if (resolved.options.generator === false || parseSidecarSourceRequest(id)?.dependencyOnly) return null;
|
|
34385
35208
|
const sourceId = requestSources.get(id) ?? id;
|
|
34386
35209
|
const entry = parseManagedEntryIndex(sourceId, entryIndex) ?? resolveAutoEntryIndex(sourceId, code);
|
|
34387
|
-
if (entry === void 0) return null;
|
|
35210
|
+
if (entry === void 0) return code.includes("@import") || importedSources.has(importedSourceKey(id)) ? transformImportedSource.call(this, code, id) : null;
|
|
34388
35211
|
const index = getSourceSlot(id, entry);
|
|
34389
35212
|
dirtySlots.delete(index);
|
|
34390
35213
|
loadedEntryIndexes.add(index);
|
|
@@ -34401,6 +35224,7 @@ function createTailwindcssPlugin(ctx) {
|
|
|
34401
35224
|
};
|
|
34402
35225
|
},
|
|
34403
35226
|
shouldTransformCachedModule({ id }) {
|
|
35227
|
+
if (importedSources.has(importedSourceKey(id))) return true;
|
|
34404
35228
|
const index = parseManagedEntryIndex(requestSources.get(id) ?? id, entryIndex);
|
|
34405
35229
|
if (index !== void 0 && dirtySlots.has(getSourceSlot(id, index))) return true;
|
|
34406
35230
|
},
|
|
@@ -35252,6 +36076,11 @@ function buildCompileVueFileOptions(ctx, pluginCtx, vuePath, isPage, isApp, conf
|
|
|
35252
36076
|
const wevuMinify = isWevuMinifyEnabled(configService.weappViteConfig, configService.isDev);
|
|
35253
36077
|
const jsonKind = isApp ? "app" : isPage ? "page" : "component";
|
|
35254
36078
|
const sourceMap = isVueTransformSourceMapEnabled(configService);
|
|
36079
|
+
const stabilizeCssVarsRuntime = configService.isDev && resolveHmrRuntime({
|
|
36080
|
+
platform: configService.platform,
|
|
36081
|
+
configured: configService.weappViteConfig?.hmr?.runtime,
|
|
36082
|
+
compileHotReLoad: configService.projectPrivateConfig?.setting?.compileHotReLoad
|
|
36083
|
+
}) === "stateful-experimental";
|
|
35255
36084
|
async function resolvePotentialVueSfcEntryId(candidate) {
|
|
35256
36085
|
const trimmed = candidate?.trim();
|
|
35257
36086
|
if (!trimmed) return;
|
|
@@ -35312,6 +36141,7 @@ function buildCompileVueFileOptions(ctx, pluginCtx, vuePath, isPage, isApp, conf
|
|
|
35312
36141
|
isApp,
|
|
35313
36142
|
skipComponentTransform: delegatesComponentRegistration,
|
|
35314
36143
|
autoSetDataPick: isAutoSetDataPickEnabledWithPreset(configService.weappViteConfig),
|
|
36144
|
+
stabilizeCssVarsRuntime,
|
|
35315
36145
|
bindingManifestSourceFile: resolveBindingManifestSourceFile(vuePath, configService),
|
|
35316
36146
|
runtimeBindingManifest: configService.isDev ? "diagnostic" : "compact",
|
|
35317
36147
|
pageLayout,
|
|
@@ -35386,7 +36216,7 @@ function createCompileVueFileOptions(ctx, pluginCtx, vuePath, isPage, isApp, con
|
|
|
35386
36216
|
const appShellSignature = createCompilerAppShellSignature(isPage && !isApp ? resolvedAppShell : void 0);
|
|
35387
36217
|
const cacheKey = getCompileVueFileOptionsCacheKey(vuePath, isPage, isApp, delegatesComponentRegistration, state.emitResolvedComponentEntries !== false, pageLayoutSignature, appShellSignature);
|
|
35388
36218
|
const cached = state.compileOptionsCache?.get(cacheKey);
|
|
35389
|
-
if (cached && compileOptionsOwners.get(cached) === pluginCtx) return cached;
|
|
36219
|
+
if (!configService.isDev && cached && compileOptionsOwners.get(cached) === pluginCtx) return cached;
|
|
35390
36220
|
const created = buildCompileVueFileOptions(ctx, pluginCtx, vuePath, isPage, isApp, configService, state, delegatesComponentRegistration, pageLayout, appShell);
|
|
35391
36221
|
compileOptionsOwners.set(created, pluginCtx);
|
|
35392
36222
|
state.compileOptionsCache?.set(cacheKey, created);
|
|
@@ -35980,7 +36810,7 @@ async function refreshCompiledVueEntryCacheInDev(options) {
|
|
|
35980
36810
|
}
|
|
35981
36811
|
const currentStyleIndependentSignature = dirtyEntryId && filename.endsWith(".vue") && isVueStyleOnlyDirtyReasonSummary(ctx.runtimeState?.build?.hmr?.profile?.dirtyReasonSummary) ? resolveVueSfcStyleIndependentSignature(source, filename) : void 0;
|
|
35982
36812
|
if (dirtyEntryId && filename.endsWith(".vue") && cached.styleIndependentSignature && currentStyleIndependentSignature && cached.styleIndependentSignature === currentStyleIndependentSignature && transformed.signature === cached.autoRoutesSignature && cached.source !== source) {
|
|
35983
|
-
const { descriptor } = await readAndParseSfc(filename, {
|
|
36813
|
+
const { descriptor } = await readAndParseSfc$1(filename, {
|
|
35984
36814
|
source,
|
|
35985
36815
|
checkMtime: configService.isDev
|
|
35986
36816
|
});
|
|
@@ -36270,7 +37100,7 @@ function emitAppShellAssetsIfNeeded(options) {
|
|
|
36270
37100
|
//#endregion
|
|
36271
37101
|
//#region src/plugins/vue/transform/bundle/emitCompiledEntry.ts
|
|
36272
37102
|
function shouldReplaceAppScriptBundleEntry(options) {
|
|
36273
|
-
if (!isAppVueFile(options.filename) || !options.isDev || !options.hasDevHmrEvent) return false;
|
|
37103
|
+
if (options.isBundledDev || !isAppVueFile(options.filename) || !options.isDev || !options.hasDevHmrEvent) return false;
|
|
36274
37104
|
return true;
|
|
36275
37105
|
}
|
|
36276
37106
|
function hasUnresolvedModuleImportDeclaration(script) {
|
|
@@ -36305,7 +37135,8 @@ async function emitResolvedCompiledVueEntryAssets(options) {
|
|
|
36305
37135
|
const shouldReplaceAppScript = shouldReplaceAppScriptBundleEntry({
|
|
36306
37136
|
filename,
|
|
36307
37137
|
isDev: configService.isDev,
|
|
36308
|
-
hasDevHmrEvent: hmrState?.profile?.event !== void 0
|
|
37138
|
+
hasDevHmrEvent: hmrState?.profile?.event !== void 0,
|
|
37139
|
+
isBundledDev: state.isBundledDev
|
|
36309
37140
|
});
|
|
36310
37141
|
if (isAppVueFile(filename) && hasAppShellTemplate(result)) emitAppShellAssetsIfNeeded({
|
|
36311
37142
|
bundle,
|
|
@@ -37107,6 +37938,7 @@ function createVueTransformPlugin(ctx, options = {}) {
|
|
|
37107
37938
|
let appShell;
|
|
37108
37939
|
let pageMatcher = null;
|
|
37109
37940
|
let scanDirtySynced = false;
|
|
37941
|
+
let isBundledDev = false;
|
|
37110
37942
|
const reExportResolutionCache = /* @__PURE__ */ new Map();
|
|
37111
37943
|
const compileOptionsCache = /* @__PURE__ */ new Map();
|
|
37112
37944
|
const componentMetaCache = /* @__PURE__ */ new Map();
|
|
@@ -37122,6 +37954,9 @@ function createVueTransformPlugin(ctx, options = {}) {
|
|
|
37122
37954
|
}
|
|
37123
37955
|
return {
|
|
37124
37956
|
name: `${VUE_PLUGIN_NAME}:transform`,
|
|
37957
|
+
configResolved(config) {
|
|
37958
|
+
isBundledDev = config.command === "serve" && Boolean(config.experimental.bundledDev);
|
|
37959
|
+
},
|
|
37125
37960
|
async buildStart() {
|
|
37126
37961
|
scopedSlotModules.clear();
|
|
37127
37962
|
emittedScopedSlotChunks.clear();
|
|
@@ -37165,7 +38000,7 @@ function createVueTransformPlugin(ctx, options = {}) {
|
|
|
37165
38000
|
},
|
|
37166
38001
|
scopedSlotModules,
|
|
37167
38002
|
parseWeappVueStyleRequest: (id) => parseWeappVueStyleRequest(id) ?? null,
|
|
37168
|
-
readAndParseSfc,
|
|
38003
|
+
readAndParseSfc: readAndParseSfc$1,
|
|
37169
38004
|
createReadAndParseSfcOptions
|
|
37170
38005
|
});
|
|
37171
38006
|
},
|
|
@@ -37194,7 +38029,7 @@ function createVueTransformPlugin(ctx, options = {}) {
|
|
|
37194
38029
|
scopedSlotModules,
|
|
37195
38030
|
emittedScopedSlotChunks,
|
|
37196
38031
|
classStyleRuntimeWarned,
|
|
37197
|
-
readAndParseSfc,
|
|
38032
|
+
readAndParseSfc: readAndParseSfc$1,
|
|
37198
38033
|
createReadAndParseSfcOptions
|
|
37199
38034
|
});
|
|
37200
38035
|
} finally {
|
|
@@ -37206,6 +38041,7 @@ function createVueTransformPlugin(ctx, options = {}) {
|
|
|
37206
38041
|
async generateBundle(_options, bundle) {
|
|
37207
38042
|
await emitVueBundleAssets(bundle, {
|
|
37208
38043
|
ctx,
|
|
38044
|
+
isBundledDev,
|
|
37209
38045
|
pluginCtx: this,
|
|
37210
38046
|
compilationCache,
|
|
37211
38047
|
appShell,
|
|
@@ -37773,9 +38609,13 @@ function mergeMiniprogram(options, ...configs) {
|
|
|
37773
38609
|
}
|
|
37774
38610
|
//#endregion
|
|
37775
38611
|
//#region src/runtime/config/internal/merge/web.ts
|
|
37776
|
-
function mergeWebPlugins(rawPlugins, webPlugin, runtimeProviderPlugin) {
|
|
38612
|
+
function mergeWebPlugins(rawPlugins, webPlugin, runtimeProviderPlugin, internalPlugins = []) {
|
|
37777
38613
|
const remaining = [];
|
|
37778
|
-
const ownedPluginNames = new Set([
|
|
38614
|
+
const ownedPluginNames = new Set([
|
|
38615
|
+
webPlugin,
|
|
38616
|
+
runtimeProviderPlugin,
|
|
38617
|
+
...internalPlugins
|
|
38618
|
+
].map((option) => option && typeof option === "object" && "name" in option ? option.name : void 0).filter((name) => typeof name === "string"));
|
|
37779
38619
|
const collect = (option) => {
|
|
37780
38620
|
if (!option) return;
|
|
37781
38621
|
if (Array.isArray(option)) {
|
|
@@ -37790,6 +38630,7 @@ function mergeWebPlugins(rawPlugins, webPlugin, runtimeProviderPlugin) {
|
|
|
37790
38630
|
return [
|
|
37791
38631
|
runtimeProviderPlugin,
|
|
37792
38632
|
webPlugin,
|
|
38633
|
+
...internalPlugins,
|
|
37793
38634
|
...remaining
|
|
37794
38635
|
].filter(Boolean);
|
|
37795
38636
|
}
|
|
@@ -37824,7 +38665,8 @@ function mergeWeb(options, ...configs) {
|
|
|
37824
38665
|
hmrAcceptCode: resolveRuntimeProviderHmrFooter(runtimeProvider)
|
|
37825
38666
|
}
|
|
37826
38667
|
});
|
|
37827
|
-
|
|
38668
|
+
const autoRoutesPlugins = options.ctx && !options.configService?.weappLibConfig?.enabled && resolveWeappAutoRoutesConfig(options.configService?.weappViteConfig?.autoRoutes).enabled ? autoRoutes(options.ctx) : [];
|
|
38669
|
+
inline.plugins = mergeWebPlugins(inline.plugins, webPlugin, runtimeProviderPlugin, autoRoutesPlugins);
|
|
37828
38670
|
inline.build ??= {};
|
|
37829
38671
|
inline.build.outDir = web.outDir;
|
|
37830
38672
|
inline.build.emptyOutDir ??= !isDev;
|
|
@@ -37940,6 +38782,7 @@ function createMergeFactories(options) {
|
|
|
37940
38782
|
const subPackageRoots = Object.keys(configService.weappViteConfig?.subPackages ?? {});
|
|
37941
38783
|
const sharedOutput = configService.options.chunksConfigured ? createSharedBuildOutput(configService, () => subPackageRoots, { runtime: "web" }) : void 0;
|
|
37942
38784
|
return backend.driver.mergeConfig({ merge: (...backendConfigs) => mergeWeb({
|
|
38785
|
+
ctx,
|
|
37943
38786
|
configService,
|
|
37944
38787
|
config: currentOptions.config,
|
|
37945
38788
|
web: currentOptions.weappWeb,
|
|
@@ -38560,7 +39403,7 @@ async function loadAppEntry(ctx, scanState) {
|
|
|
38560
39403
|
const { path: appEntryPath } = appEntry;
|
|
38561
39404
|
let configFromVue;
|
|
38562
39405
|
if (!appConfigFile && vueAppPath) {
|
|
38563
|
-
const { extractConfigFromVue } = await import("./file-
|
|
39406
|
+
const { extractConfigFromVue } = await import("./file-BRwj-D25.mjs");
|
|
38564
39407
|
configFromVue = await extractConfigFromVue(vueAppPath);
|
|
38565
39408
|
if (configFromVue) appConfigFile = vueAppPath;
|
|
38566
39409
|
}
|