weapp-vite 7.4.0 → 7.5.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.
Files changed (92) hide show
  1. package/README.md +51 -1
  2. package/bin/bootstrap.js +14 -1
  3. package/dist/adapters-CcHrsYaj.mjs +1 -0
  4. package/dist/analyze-ZJUvEdaY.mjs +248 -0
  5. package/dist/auto-import-components/resolvers.mjs +1 -2
  6. package/dist/auto-import-presets/wevu-router.mjs +1 -2
  7. package/dist/auto-import-presets/wevu.mjs +1 -2
  8. package/dist/auto-routes.mjs +2 -1
  9. package/dist/budget-BD7VqLCl.d.mts +178 -0
  10. package/dist/chunkStrategy-DRA5WpB-.mjs +1436 -0
  11. package/dist/cli-acceptance.d.mts +1 -0
  12. package/dist/cli-acceptance.mjs +21 -0
  13. package/dist/cli.mjs +1420 -1554
  14. package/dist/compatibility.mjs +1 -2
  15. package/dist/{config-Dbvj5yK7.d.mts → config-V0L-IAJf.d.mts} +87 -30
  16. package/dist/config.d.mts +2 -2
  17. package/dist/config.mjs +1 -1
  18. package/dist/{constants-WOsG3Eqd.mjs → constants-DEZdcsMn.mjs} +1 -1
  19. package/dist/{createContext-UOEgeYnA.mjs → createCompilerContextInstance-DJH_P_nZ.mjs} +31278 -32148
  20. package/dist/createContext-BqYzHhY9.mjs +12 -0
  21. package/dist/dashboard/analyze.d.mts +48 -0
  22. package/dist/dashboard/analyze.mjs +1 -0
  23. package/dist/dashboard/vite.d.mts +1 -1
  24. package/dist/dashboard-DvqF3Key.mjs +1842 -0
  25. package/dist/dashboard.d.mts +3 -2
  26. package/dist/dashboard.mjs +1 -2
  27. package/dist/dashboardViteBridge-Dy3nAD4m.mjs +299 -0
  28. package/dist/dev-fR5GiJRO.mjs +63 -0
  29. package/dist/devProvider-BGBkw28J.mjs +1050 -0
  30. package/dist/docs/README.md +51 -1
  31. package/dist/docs/ai-workflows.md +4 -0
  32. package/dist/docs/doctor.md +38 -0
  33. package/dist/docs/getting-started.md +3 -1
  34. package/dist/docs/index.md +3 -1
  35. package/dist/docs/mcp.md +94 -1
  36. package/dist/docs/testing.md +29 -2
  37. package/dist/docs/troubleshooting.md +8 -0
  38. package/dist/docs/uni-app-component-libraries.md +8 -7
  39. package/dist/docs/upload.md +40 -3
  40. package/dist/docs/vite-plugin.md +171 -0
  41. package/dist/docs/vue-sfc.md +19 -0
  42. package/dist/docs/weapp-config.md +54 -0
  43. package/dist/docs/wevu-authoring.md +10 -0
  44. package/dist/doctor-worker.d.mts +1 -0
  45. package/dist/doctor-worker.mjs +59 -0
  46. package/dist/doctor.d.mts +144 -0
  47. package/dist/doctor.mjs +848 -0
  48. package/dist/eslint.mjs +1 -2
  49. package/dist/file-DRb4eWqw.mjs +1 -0
  50. package/dist/{file-giE9UMZa.mjs → file-sC3jD7Fh.mjs} +15 -9
  51. package/dist/files-BqxFIPRp.mjs +45 -0
  52. package/dist/getInstance-DiGSzBNI.mjs +28 -0
  53. package/dist/getInstance-SiE6WZRh.mjs +1 -0
  54. package/dist/index-C9HjUX5c.d.mts +741 -0
  55. package/dist/index.d.mts +10 -8
  56. package/dist/index.mjs +3 -2
  57. package/dist/json.d.mts +1 -1
  58. package/dist/json.mjs +1 -2
  59. package/dist/lifecycle-BROTlwSL.mjs +320 -0
  60. package/dist/loadConfig-C3BQhz7F.mjs +59 -0
  61. package/dist/loadConfig-VGtBF4qm.mjs +1 -0
  62. package/dist/logger-DGn5iEVN.mjs +1 -0
  63. package/dist/{mcp-BG6TliEg.mjs → mcp-Cj8Maqo6.mjs} +16 -7
  64. package/dist/mcp-D3Yh24Cj.mjs +529 -0
  65. package/dist/mcp.d.mts +6 -3
  66. package/dist/mcp.mjs +1 -2
  67. package/dist/package-7swhyLmf.mjs +91 -0
  68. package/dist/path-doV773b7.mjs +103 -0
  69. package/dist/{platform-DTWs5QRi.mjs → platform-CnkySBKz.mjs} +1 -1
  70. package/dist/processCleanup-B6KA30Zc.mjs +77 -0
  71. package/dist/protocol-vg8HGJ4n.mjs +138 -0
  72. package/dist/{resolvers-icNxkpcy.mjs → resolvers-Dod-euqX.mjs} +4 -1
  73. package/dist/resolvers.mjs +1 -2
  74. package/dist/runtime.mjs +1 -2
  75. package/dist/session-PskhD-nZ.mjs +390 -0
  76. package/dist/test.d.mts +1 -0
  77. package/dist/test.mjs +201 -44
  78. package/dist/types.d.mts +2 -2
  79. package/dist/{upload-D0RcEWrq.mjs → upload-D4msblBf.mjs} +174 -15
  80. package/dist/upload-worker.mjs +136 -3
  81. package/dist/utils-CJSCgEj6.mjs +1094 -0
  82. package/dist/vite.d.mts +9 -0
  83. package/dist/vite.mjs +270 -0
  84. package/dist/volar.d.mts +2 -2
  85. package/dist/web-apis.mjs +1 -2
  86. package/package.json +67 -41
  87. package/dist/adapters-BwnMMIZR.mjs +0 -2
  88. package/dist/dashboard-BzaVesmQ.mjs +0 -558
  89. package/dist/file-D19nbDoN.mjs +0 -2
  90. package/dist/getInstance-CYF1vl5l.mjs +0 -2
  91. package/dist/index-DbqVupg0.d.mts +0 -246
  92. package/dist/logger-mt4mSTqV.mjs +0 -2
@@ -0,0 +1,1094 @@
1
+ import { c as isSkippableResolvedId, i as normalizeRoot, l as normalizeFsResolvedId, s as toPosixPath } from "./path-doV773b7.mjs";
2
+ import { S as shouldNormalizeUsingComponents, l as getProjectPlatformOptions, p as normalizePlatformNpmImportPath, v as shouldFillComponentGenericsDefault, x as shouldNormalizePlatformNpmImportPath } from "./platform-CnkySBKz.mjs";
3
+ import { n as changeFileExtension } from "./file-sC3jD7Fh.mjs";
4
+ import { i as scriptExtensions, s as vueExtensions } from "./constants-DEZdcsMn.mjs";
5
+ import "./logger-DGn5iEVN.mjs";
6
+ import { createRequire } from "node:module";
7
+ import process from "node:process";
8
+ import path from "pathe";
9
+ import { existsSync, readFileSync } from "node:fs";
10
+ import { pathToFileURL } from "node:url";
11
+ import path$1 from "node:path";
12
+ import { defuOverrideArray, get, isObject, removeExtensionDeep, set } from "@weapp-core/shared";
13
+ import { parse, stringify } from "comment-json";
14
+ import { fs as fs$1 } from "@weapp-core/shared/fs";
15
+ import { parseJsLikeWithEngine } from "@weapp-vite/ast";
16
+ import { BABEL_TS_MODULE_PARSER_OPTIONS as BABEL_TS_MODULE_PARSER_OPTIONS$1, generate as generate$1, parse as parse$2, parseJsLike as parseJsLike$1, traverse as traverse$1 } from "@weapp-vite/ast/babel";
17
+ import picomatch from "picomatch";
18
+ import { invalidateFileCache, pathExists, readFile as readFile$2 } from "wevu/compiler";
19
+ import fs$2, { readFile as readFile$1, readdir, realpath, unlink } from "node:fs/promises";
20
+ import { loadConfigFromFile } from "vite";
21
+ import "semver/functions/gte.js";
22
+ import "semver/functions/satisfies.js";
23
+ import "semver/functions/valid.js";
24
+ //#region src/utils/npmImport.ts
25
+ const WINDOWS_PATH_SEPARATORS_RE = /\\/g;
26
+ const WINDOWS_ABSOLUTE_PATH_RE = /^[a-z]:[\\/]/i;
27
+ const NPM_PROTOCOL_RE = /^npm:/;
28
+ const PLUGIN_PROTOCOL_RE = /^plugin:\/\//;
29
+ const EXPLICIT_NPM_DIR_RE = /^\/(?:miniprogram_npm|node_modules)\//;
30
+ const LEADING_SLASHES_RE = /^\/+/;
31
+ const NODE_MODULES_SEGMENT = "/node_modules/";
32
+ const STRIP_SCRIPT_EXTENSION_RE = /\.[cm]?[jt]sx?$/;
33
+ const INFERRED_MINIPROGRAM_ROOTS = ["miniprogram_dist", "miniprogram"];
34
+ const miniprogramRootCache = /* @__PURE__ */ new Map();
35
+ const packageRootCache = /* @__PURE__ */ new Map();
36
+ const resolveFromCurrentModule = createRequire(import.meta.url);
37
+ function stripScriptExtension(value) {
38
+ return value.replace(STRIP_SCRIPT_EXTENSION_RE, "");
39
+ }
40
+ function stripInferredMiniprogramRoot(subPath) {
41
+ for (const miniprogramRoot of INFERRED_MINIPROGRAM_ROOTS) if (subPath === miniprogramRoot || subPath.startsWith(`${miniprogramRoot}/`)) return subPath.slice(miniprogramRoot.length).replace(LEADING_SLASHES_RE, "");
42
+ return subPath;
43
+ }
44
+ function readMiniprogramRoot(packageRoot) {
45
+ const cached = miniprogramRootCache.get(packageRoot);
46
+ if (cached !== void 0 || miniprogramRootCache.has(packageRoot)) return cached;
47
+ const packageJsonPath = path$1.join(packageRoot, "package.json");
48
+ if (!existsSync(packageJsonPath)) {
49
+ miniprogramRootCache.set(packageRoot, void 0);
50
+ return;
51
+ }
52
+ try {
53
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf8"));
54
+ const miniprogramRoot = typeof packageJson.miniprogram === "string" ? packageJson.miniprogram.replace(WINDOWS_PATH_SEPARATORS_RE, "/").replace(LEADING_SLASHES_RE, "") : void 0;
55
+ miniprogramRootCache.set(packageRoot, miniprogramRoot);
56
+ return miniprogramRoot;
57
+ } catch {
58
+ miniprogramRootCache.set(packageRoot, void 0);
59
+ return;
60
+ }
61
+ }
62
+ function resolveInstalledPackageRoot(packageName, basedir) {
63
+ const cacheKey = `${basedir}::${packageName}`;
64
+ const cached = packageRootCache.get(cacheKey);
65
+ if (cached !== void 0 || packageRootCache.has(cacheKey)) return cached;
66
+ try {
67
+ const packageJsonPath = resolveFromCurrentModule.resolve(`${packageName}/package.json`, { paths: [basedir] });
68
+ const resolvedPackageRoot = path$1.dirname(packageJsonPath);
69
+ packageRootCache.set(cacheKey, resolvedPackageRoot);
70
+ return resolvedPackageRoot;
71
+ } catch {
72
+ packageRootCache.set(cacheKey, void 0);
73
+ return;
74
+ }
75
+ }
76
+ function normalizeAbsoluteNodeModulesImport(importee) {
77
+ const nodeModulesIndex = importee.lastIndexOf(NODE_MODULES_SEGMENT);
78
+ if (nodeModulesIndex === -1) return;
79
+ const packageStart = nodeModulesIndex + 14;
80
+ const packageTokens = importee.slice(packageStart).replace(LEADING_SLASHES_RE, "").split("/").filter(Boolean);
81
+ if (packageTokens.length === 0) return;
82
+ const packageTokenCount = packageTokens[0].startsWith("@") ? 2 : 1;
83
+ if (packageTokens.length < packageTokenCount) return;
84
+ const packageName = packageTokens.slice(0, packageTokenCount).join("/");
85
+ const inferredPackageRoot = `${importee.slice(0, packageStart)}${packageName}`;
86
+ const packageRoot = existsSync(path$1.join(inferredPackageRoot, "package.json")) ? inferredPackageRoot : resolveInstalledPackageRoot(packageName, path$1.dirname(importee)) ?? inferredPackageRoot;
87
+ let subPath = packageTokens.slice(packageTokenCount).join("/");
88
+ const miniprogramRoot = readMiniprogramRoot(packageRoot);
89
+ if (miniprogramRoot && (subPath === miniprogramRoot || subPath.startsWith(`${miniprogramRoot}/`))) subPath = subPath.slice(miniprogramRoot.length).replace(LEADING_SLASHES_RE, "");
90
+ else subPath = stripInferredMiniprogramRoot(subPath);
91
+ const normalizedSubPath = stripScriptExtension(subPath);
92
+ return normalizedSubPath ? `${packageName}/${normalizedSubPath}` : packageName;
93
+ }
94
+ function normalizeNpmImportLookupPath(importee) {
95
+ const normalized = importee.replace(WINDOWS_PATH_SEPARATORS_RE, "/").replace(NPM_PROTOCOL_RE, "");
96
+ const nodeModulesResolved = normalizeAbsoluteNodeModulesImport(normalized);
97
+ if (nodeModulesResolved) return nodeModulesResolved;
98
+ return normalized.replace(EXPLICIT_NPM_DIR_RE, "").replace(LEADING_SLASHES_RE, "");
99
+ }
100
+ function resolveNpmDependencyId(importee) {
101
+ const normalizedImportee = normalizeNpmImportLookupPath(importee);
102
+ const importeeTokens = normalizedImportee.split("/").filter(Boolean);
103
+ if (importeeTokens.length === 0) return "";
104
+ if (normalizedImportee.startsWith("@") && importeeTokens.length > 1) return `${importeeTokens[0]}/${importeeTokens[1]}`;
105
+ return importeeTokens[0];
106
+ }
107
+ function normalizeNpmPackageSpecifier(specifier) {
108
+ const normalized = specifier.trim();
109
+ if (!normalized || normalized.startsWith(".") || normalized.startsWith("/") || normalized.startsWith("\\")) return;
110
+ if (WINDOWS_ABSOLUTE_PATH_RE.test(normalized)) return;
111
+ return normalized;
112
+ }
113
+ function parseNpmPackageSpecifier(specifier) {
114
+ const normalized = normalizeNpmPackageSpecifier(specifier);
115
+ if (!normalized) return;
116
+ const normalizedImportee = normalizeNpmImportLookupPath(normalized);
117
+ if (normalizedImportee.startsWith("@") && !normalizedImportee.includes("/")) return;
118
+ const packageName = resolveNpmDependencyId(normalizedImportee);
119
+ if (!packageName) return;
120
+ return {
121
+ packageName,
122
+ subPath: normalizedImportee.slice(packageName.length).replace(LEADING_SLASHES_RE, "")
123
+ };
124
+ }
125
+ function hasNpmDependencyPrefix(dependencies, importee) {
126
+ if (!dependencies) return false;
127
+ const importeeTokens = normalizeNpmImportLookupPath(importee).split("/").filter(Boolean);
128
+ if (importeeTokens.length === 0) return false;
129
+ return Object.keys(dependencies).some((dep) => {
130
+ const depTokens = dep.replace(WINDOWS_PATH_SEPARATORS_RE, "/").split("/").filter(Boolean);
131
+ if (depTokens.length === 0 || depTokens.length > importeeTokens.length) return false;
132
+ for (let i = 0; i < depTokens.length; i++) if (depTokens[i] !== importeeTokens[i]) return false;
133
+ return true;
134
+ });
135
+ }
136
+ function shouldNormalizeNpmImportByPlatform(importee, options) {
137
+ const trimmed = importee.trim();
138
+ if (!trimmed || PLUGIN_PROTOCOL_RE.test(trimmed)) return false;
139
+ if (!options.platform || !shouldNormalizePlatformNpmImportPath(options.platform)) return false;
140
+ const normalized = trimmed.replace(NPM_PROTOCOL_RE, "");
141
+ if (EXPLICIT_NPM_DIR_RE.test(normalized)) return true;
142
+ return hasNpmDependencyPrefix(options.dependencies, normalized);
143
+ }
144
+ function normalizeNpmImportPathByPlatform(importee, options) {
145
+ const trimmed = importee.trim();
146
+ if (!shouldNormalizeNpmImportByPlatform(trimmed, options)) return importee;
147
+ if (!options.platform) return importee;
148
+ const normalized = trimmed.replace(NPM_PROTOCOL_RE, "");
149
+ return normalizePlatformNpmImportPath(options.platform, normalized, { alipayNpmMode: options.alipayNpmMode });
150
+ }
151
+ //#endregion
152
+ //#region src/utils/json.ts
153
+ const ALIPAY_GENERIC_COMPONENT_PLACEHOLDER = "./__weapp_vite_generic_component";
154
+ const WEAPP_SCOPED_SLOT_GENERIC_COMPONENT_PLACEHOLDER = "./__weapp_vite_scoped_slot_generic_component";
155
+ const JSON_FILE_JS_EXTENSION_RE = /\.[jt]s$/;
156
+ const COMPONENT_NAME_LOWER_TO_UPPER_RE = /([a-z0-9])([A-Z])/g;
157
+ const COMPONENT_NAME_MULTI_UPPER_RE = /([A-Z]+)([A-Z][a-z])/g;
158
+ const COMPONENT_NAME_HAS_UPPER_RE = /[A-Z]/;
159
+ const SCOPED_SLOT_GENERIC_KEY_RE = /^scoped-slots-/;
160
+ function parseCommentJson(json) {
161
+ return parse(json, void 0, true);
162
+ }
163
+ function jsonFileRemoveJsExtension(fileName) {
164
+ return fileName.replace(JSON_FILE_JS_EXTENSION_RE, "");
165
+ }
166
+ function stringifyJson(value, replacer) {
167
+ return stringify(value, replacer, 2);
168
+ }
169
+ function normalizeAppJson(json) {
170
+ if (!json || typeof json !== "object" || Array.isArray(json)) return json;
171
+ const subPackages = Array.isArray(json.subPackages) ? json.subPackages : Array.isArray(json.subpackages) ? json.subpackages : [];
172
+ const { subpackages: _subpackages, ...rest } = json;
173
+ return {
174
+ ...rest,
175
+ subPackages: subPackages.map((subPackage) => ({
176
+ ...subPackage,
177
+ pages: Array.isArray(subPackage?.pages) ? subPackage.pages : []
178
+ }))
179
+ };
180
+ }
181
+ function matches(pattern, importee) {
182
+ if (pattern instanceof RegExp) return pattern.test(importee);
183
+ if (importee.length < pattern.length) return false;
184
+ if (importee === pattern) return true;
185
+ return importee.startsWith(pattern + "/");
186
+ }
187
+ function getAliasEntries(options = {}) {
188
+ if (options === false) return [];
189
+ const { entries } = options;
190
+ if (!entries) return [];
191
+ if (Array.isArray(entries)) return entries.map((entry) => {
192
+ return {
193
+ find: entry.find,
194
+ replacement: entry.replacement
195
+ };
196
+ });
197
+ return Object.entries(entries).map(([key, value]) => {
198
+ return {
199
+ find: key,
200
+ replacement: value
201
+ };
202
+ });
203
+ }
204
+ function resolveImportee(importee, jsonPath, aliasEntries) {
205
+ if (Array.isArray(aliasEntries)) {
206
+ if (!jsonPath) return importee;
207
+ const matchedEntry = aliasEntries.find((x) => matches(x.find, importee));
208
+ if (!matchedEntry) return importee;
209
+ const updatedId = importee.replace(matchedEntry.find, matchedEntry.replacement);
210
+ return toPosixPath(path.relative(path.dirname(jsonPath), updatedId));
211
+ }
212
+ return importee;
213
+ }
214
+ function toKebabCaseComponentName(name) {
215
+ return name.replace(COMPONENT_NAME_LOWER_TO_UPPER_RE, "$1-$2").replace(COMPONENT_NAME_MULTI_UPPER_RE, "$1-$2").toLowerCase();
216
+ }
217
+ function normalizeUsingComponentPathByPlatform(importee, platform, dependencies, mode) {
218
+ if (!hasNpmDependencyPrefix(dependencies, importee) && !importee.trim().startsWith("/")) return importee;
219
+ return normalizeNpmImportPathByPlatform(importee, {
220
+ platform,
221
+ dependencies,
222
+ alipayNpmMode: mode
223
+ });
224
+ }
225
+ function normalizeUsingComponentsByPlatform(usingComponents, platform, options) {
226
+ if (!shouldNormalizeUsingComponents(platform)) return usingComponents;
227
+ const normalized = {};
228
+ for (const [key, value] of Object.entries(usingComponents)) {
229
+ const nextKey = COMPONENT_NAME_HAS_UPPER_RE.test(key) ? toKebabCaseComponentName(key) : key;
230
+ const nextValue = normalizeUsingComponentPathByPlatform(value, platform, options?.dependencies, options?.alipayNpmMode);
231
+ if (!Reflect.has(normalized, nextKey)) normalized[nextKey] = nextValue;
232
+ }
233
+ return normalized;
234
+ }
235
+ function normalizeComponentGenericsByPlatform(componentGenerics, platform) {
236
+ if (!shouldFillComponentGenericsDefault(platform) && platform !== "weapp") return componentGenerics;
237
+ const normalized = {};
238
+ for (const [key, value] of Object.entries(componentGenerics)) {
239
+ const placeholder = platform === "weapp" ? SCOPED_SLOT_GENERIC_KEY_RE.test(key) ? WEAPP_SCOPED_SLOT_GENERIC_COMPONENT_PLACEHOLDER : void 0 : ALIPAY_GENERIC_COMPONENT_PLACEHOLDER;
240
+ if (!placeholder) {
241
+ normalized[key] = value;
242
+ continue;
243
+ }
244
+ if (value === true) {
245
+ normalized[key] = { default: placeholder };
246
+ continue;
247
+ }
248
+ if (isObject(value)) {
249
+ const nextValue = { ...value };
250
+ if (typeof nextValue.default !== "string" || !nextValue.default.trim()) nextValue.default = placeholder;
251
+ normalized[key] = nextValue;
252
+ continue;
253
+ }
254
+ normalized[key] = value;
255
+ }
256
+ return normalized;
257
+ }
258
+ function resolveJson(entry, aliasEntries, platform, options) {
259
+ if (entry.json) {
260
+ const json = entry.type === "app" ? normalizeAppJson(structuredClone(entry.json)) : structuredClone(entry.json);
261
+ if (entry.type === "app" && options?.omitEmptySubPackages && json.subPackages?.length === 0) delete json.subPackages;
262
+ if (entry.jsonPath && Array.isArray(aliasEntries)) {
263
+ const usingComponents = get(json, "usingComponents");
264
+ if (isObject(usingComponents)) {
265
+ for (const [key, importee] of Object.entries(usingComponents)) {
266
+ const resolvedId = resolveImportee(importee, entry.jsonPath, aliasEntries);
267
+ set(json, `usingComponents.${key}`, resolvedId);
268
+ }
269
+ set(json, "usingComponents", normalizeUsingComponentsByPlatform(usingComponents, platform, options));
270
+ }
271
+ if (entry.type === "app") for (const field of ["subPackages", "subpackages"]) {
272
+ const subPackages = get(json, field);
273
+ if (Array.isArray(subPackages)) {
274
+ for (const subPackage of subPackages) if (subPackage.entry) subPackage.entry = changeFileExtension(subPackage.entry, "js");
275
+ }
276
+ }
277
+ } else {
278
+ const usingComponents = get(json, "usingComponents");
279
+ if (isObject(usingComponents)) set(json, "usingComponents", normalizeUsingComponentsByPlatform(usingComponents, platform, options));
280
+ }
281
+ const componentGenerics = get(json, "componentGenerics");
282
+ if (isObject(componentGenerics)) set(json, "componentGenerics", normalizeComponentGenericsByPlatform(componentGenerics, platform));
283
+ if (Reflect.has(json, "$schema")) delete json.$schema;
284
+ return stringifyJson(json);
285
+ }
286
+ }
287
+ const PROD_PATH_EXISTS_TTL_MS = 6e4;
288
+ function getPathExistsTtlMs(config) {
289
+ return config?.isDev ? 250 : PROD_PATH_EXISTS_TTL_MS;
290
+ }
291
+ function getReadFileCheckMtime(config) {
292
+ return Boolean(config?.isDev);
293
+ }
294
+ //#endregion
295
+ //#region src/utils/configErrors.ts
296
+ const CJS_ERROR_PATTERNS = [
297
+ "__dirname is not defined",
298
+ "__filename is not defined",
299
+ "require is not defined",
300
+ "module is not defined",
301
+ "exports is not defined",
302
+ "es module scope"
303
+ ];
304
+ function collectErrorText(error, texts) {
305
+ if (!error) return;
306
+ if (typeof error === "string") {
307
+ texts.push(error);
308
+ return;
309
+ }
310
+ if (typeof error === "object") {
311
+ const err = error;
312
+ if (err.message) texts.push(String(err.message));
313
+ if (err.stack) texts.push(String(err.stack));
314
+ if ("cause" in err) collectErrorText(err.cause, texts);
315
+ }
316
+ }
317
+ function formatConfigPath(configPath, cwd) {
318
+ if (!configPath) return "vite.config.ts";
319
+ const relative = path.relative(cwd, configPath);
320
+ if (relative && !relative.startsWith("..") && !path.isAbsolute(relative)) return relative;
321
+ return configPath;
322
+ }
323
+ function createCjsConfigLoadError(options) {
324
+ const texts = [];
325
+ collectErrorText(options.error, texts);
326
+ const haystack = texts.join("\n").toLowerCase();
327
+ if (!CJS_ERROR_PATTERNS.some((pattern) => haystack.includes(pattern))) return;
328
+ const message = `${formatConfigPath(options.configPath, options.cwd)} 为 CJS 格式,需要改为 ESM 写法(可参考 import.meta.dirname 等用法)。`;
329
+ const error = new Error(message);
330
+ if (options.error instanceof Error) error.cause = options.error;
331
+ return error;
332
+ }
333
+ //#endregion
334
+ //#region src/utils/entryResolve.ts
335
+ function buildCandidates(base, extensions) {
336
+ return extensions.map((ext) => changeFileExtension(base, ext));
337
+ }
338
+ function resolveEntryExtensions(kind, isDir) {
339
+ return kind === "named" || isDir ? [...scriptExtensions, ...vueExtensions] : [...vueExtensions, ...scriptExtensions];
340
+ }
341
+ function createCachedEntryResolveOptions(configService, options) {
342
+ return {
343
+ kind: options?.kind,
344
+ indexBaseName: options?.indexBaseName,
345
+ exists: (filePath) => pathExists(filePath, { ttlMs: getPathExistsTtlMs(configService) }),
346
+ stat: (filePath) => fs$1.stat(filePath)
347
+ };
348
+ }
349
+ /**
350
+ * 用于处理 resolver 返回“目录路径”或“无扩展名路径”的场景。
351
+ *
352
+ * - 如果 `input` 是目录:尝试 `${dir}/${indexBaseName}.{js/ts..}`(必要时再尝试 .vue)
353
+ * - 如果 `input` 没扩展名:尝试补全 `{.vue, .ts, .js...}`(default 优先 .vue,named 优先 js/ts)
354
+ *
355
+ * 如果 `input` 已带扩展名,则返回 `undefined`(表示无需补全)。
356
+ */
357
+ async function resolveEntryPath(input, options) {
358
+ if (!input || typeof input !== "string") return;
359
+ if (path.extname(input)) return;
360
+ const kind = options?.kind ?? "default";
361
+ const exists = options?.exists ?? (async (p) => fs$1.pathExists(p));
362
+ const stat = options?.stat ?? (async (p) => fs$1.stat(p));
363
+ const indexBaseName = options?.indexBaseName ?? "index";
364
+ let base = input;
365
+ let isDir = false;
366
+ try {
367
+ isDir = Boolean((await stat(input))?.isDirectory?.());
368
+ } catch {
369
+ isDir = false;
370
+ }
371
+ if (isDir) base = path.join(input, indexBaseName);
372
+ const extensions = resolveEntryExtensions(kind, isDir);
373
+ for (const candidate of buildCandidates(base, extensions)) if (await exists(candidate)) return candidate;
374
+ }
375
+ //#endregion
376
+ //#region src/utils/loadViteConfigFile.ts
377
+ const DEFAULT_VITE_CONFIG_FILES = [
378
+ "vite.config.ts",
379
+ "vite.config.mts",
380
+ "vite.config.cts",
381
+ "vite.config.js",
382
+ "vite.config.mjs",
383
+ "vite.config.cjs"
384
+ ];
385
+ const DEFAULT_VITE_CONFIG_FILE_SET = new Set(DEFAULT_VITE_CONFIG_FILES);
386
+ const TYPELESS_PACKAGE_JSON_WARNING_CODE = "MODULE_TYPELESS_PACKAGE_JSON";
387
+ function resolveWarningCode(warning, typeOrOptions, code) {
388
+ if (warning instanceof Error && typeof warning.code === "string") return warning.code;
389
+ if (typeOrOptions && typeof typeOrOptions === "object" && typeof typeOrOptions.code === "string") return typeOrOptions.code;
390
+ return code;
391
+ }
392
+ async function withSuppressedWarningCodes(suppressedCodes, fn) {
393
+ if (!suppressedCodes || suppressedCodes.length === 0) return fn();
394
+ const suppressedCodeSet = new Set(suppressedCodes);
395
+ const originalEmitWarning = process.emitWarning.bind(process);
396
+ process.emitWarning = ((warning, typeOrOptions, code) => {
397
+ const warningCode = resolveWarningCode(warning, typeOrOptions, code);
398
+ if (warningCode && suppressedCodeSet.has(warningCode)) return;
399
+ return originalEmitWarning(warning, typeOrOptions, code);
400
+ });
401
+ try {
402
+ return await fn();
403
+ } finally {
404
+ process.emitWarning = originalEmitWarning;
405
+ }
406
+ }
407
+ function isDefaultViteConfigBasename(filePath) {
408
+ return DEFAULT_VITE_CONFIG_FILE_SET.has(path.basename(filePath));
409
+ }
410
+ async function resolveImplicitConfigFile(configRoot) {
411
+ for (const fileName of DEFAULT_VITE_CONFIG_FILES) {
412
+ const filePath = path.resolve(configRoot, fileName);
413
+ try {
414
+ await fs$2.access(filePath);
415
+ return filePath;
416
+ } catch {
417
+ continue;
418
+ }
419
+ }
420
+ }
421
+ async function loadViteConfigFile(configEnv, configFile, configRoot, configFileDependencies, configFileExport, configLoader, suppressedWarningCodes, logLevel) {
422
+ const resolvedConfigFile = configFile ?? await resolveImplicitConfigFile(configRoot);
423
+ const resolvedConfigLoader = configLoader ?? "bundle";
424
+ return withSuppressedWarningCodes(suppressedWarningCodes, () => loadConfigFromFile(configEnv, resolvedConfigFile, configRoot, logLevel, void 0, resolvedConfigLoader));
425
+ }
426
+ //#endregion
427
+ //#region src/utils/preloadScan.ts
428
+ const HOST_ROUTER_METHODS = /* @__PURE__ */ new Set([
429
+ "navigateTo",
430
+ "redirectTo",
431
+ "reLaunch",
432
+ "switchTab"
433
+ ]);
434
+ const ROUTER_METHODS = /* @__PURE__ */ new Set(["push", "replace"]);
435
+ const ROUTER_MODULES = /* @__PURE__ */ new Set([
436
+ "vue-router",
437
+ "wevu",
438
+ "wevu/router"
439
+ ]);
440
+ const ROUTER_FACTORY_METHODS = /* @__PURE__ */ new Map([
441
+ ["createRouter", ROUTER_METHODS],
442
+ ["useNativeRouter", HOST_ROUTER_METHODS],
443
+ ["useRouter", ROUTER_METHODS]
444
+ ]);
445
+ const TEMPLATE_NAVIGATOR_RE = /<navigator(?=\s|>)[^>]*?\surl\s*=\s*(["'])([^"'{}\s]+)\1/gi;
446
+ function normalizePagePath$1(value) {
447
+ return path.posix.normalize(value).replace(/^\/+/, "").replace(/^\.\//, "");
448
+ }
449
+ function normalizeStaticTarget(target, sourcePage) {
450
+ const route = toPosixPath(target).split(/[?#]/, 1)[0];
451
+ return normalizePagePath$1(route.startsWith("/") ? route : route.startsWith("./") || route.startsWith("../") ? path.posix.join(path.posix.dirname(sourcePage), route) : route);
452
+ }
453
+ function getStaticString(node) {
454
+ if (node?.type === "StringLiteral" || node?.type === "Literal" && typeof node.value === "string") return node.value;
455
+ if (node?.type === "TemplateLiteral" && node.expressions.length === 0) return node.quasis[0]?.value.cooked ?? node.quasis[0]?.value.raw;
456
+ }
457
+ function getPropertyName(node) {
458
+ if (!node) return;
459
+ if (node.type === "Identifier" && !node.computed) return node.name;
460
+ return getStaticString(node);
461
+ }
462
+ function getRouteFromObject(argument) {
463
+ if (argument?.type !== "ObjectExpression") return;
464
+ for (const property of argument.properties ?? []) {
465
+ if (property.type !== "ObjectProperty" && property.type !== "Property") continue;
466
+ const name = getPropertyName(property.key);
467
+ if (name !== "url" && name !== "path") continue;
468
+ const value = getStaticString(property.value);
469
+ if (value) return value;
470
+ }
471
+ }
472
+ function getIdentifierName(node) {
473
+ return node?.type === "Identifier" ? node.name : void 0;
474
+ }
475
+ function collectRouterBindings(ast) {
476
+ const importedFactories = /* @__PURE__ */ new Map();
477
+ const routerObjects = /* @__PURE__ */ new Map();
478
+ const routerFunctions = /* @__PURE__ */ new Map();
479
+ traverse$1(ast, { ImportDeclaration(importPath) {
480
+ if (!ROUTER_MODULES.has(importPath.node.source?.value)) return;
481
+ for (const specifier of importPath.node.specifiers ?? []) {
482
+ if (specifier.type !== "ImportSpecifier") continue;
483
+ const imported = getIdentifierName(specifier.imported) ?? getStaticString(specifier.imported);
484
+ const local = getIdentifierName(specifier.local);
485
+ const methods = imported ? ROUTER_FACTORY_METHODS.get(imported) : void 0;
486
+ const binding = local ? importPath.scope.getBinding(local) : void 0;
487
+ if (methods && binding) importedFactories.set(binding, methods);
488
+ }
489
+ } });
490
+ traverse$1(ast, { VariableDeclarator(declaratorPath) {
491
+ const init = declaratorPath.node.init;
492
+ const factory = init?.type === "CallExpression" ? getIdentifierName(init.callee) : void 0;
493
+ if (!factory) return;
494
+ const factoryBinding = declaratorPath.scope.getBinding(factory);
495
+ const methods = factoryBinding ? importedFactories.get(factoryBinding) : ROUTER_FACTORY_METHODS.get(factory);
496
+ if (!methods) return;
497
+ const id = declaratorPath.node.id;
498
+ const objectName = getIdentifierName(id);
499
+ if (objectName) {
500
+ const binding = declaratorPath.scope.getBinding(objectName);
501
+ if (binding?.constant) routerObjects.set(binding, methods);
502
+ return;
503
+ }
504
+ if (id?.type !== "ObjectPattern") return;
505
+ for (const property of id.properties ?? []) {
506
+ if (property.type !== "ObjectProperty" && property.type !== "Property") continue;
507
+ const importedMethod = getPropertyName(property.key);
508
+ const local = getIdentifierName(property.value);
509
+ const binding = local ? declaratorPath.scope.getBinding(local) : void 0;
510
+ if (importedMethod && methods.has(importedMethod) && binding?.constant) routerFunctions.set(binding, importedMethod);
511
+ }
512
+ } });
513
+ return {
514
+ routerFunctions,
515
+ routerObjects
516
+ };
517
+ }
518
+ function getNavigationMethod(callPath, bindings) {
519
+ const callee = callPath.node.callee;
520
+ const directName = getIdentifierName(callee);
521
+ const directMethod = directName ? bindings.routerFunctions.get(callPath.scope.getBinding(directName)) : void 0;
522
+ if (directMethod) return directMethod;
523
+ if (callee?.type !== "MemberExpression" && callee?.type !== "OptionalMemberExpression") return;
524
+ const objectName = getIdentifierName(callee.object);
525
+ const method = getPropertyName(callee.property);
526
+ if (objectName === "wx" && !callPath.scope.getBinding("wx") && method && HOST_ROUTER_METHODS.has(method)) return method;
527
+ if (objectName && method) {
528
+ if (bindings.routerObjects.get(callPath.scope.getBinding(objectName))?.has(method)) return method;
529
+ }
530
+ }
531
+ function collectScriptTargets(source, sourcePage) {
532
+ const targets = [];
533
+ try {
534
+ const ast = parseJsLike$1(source);
535
+ const bindings = collectRouterBindings(ast);
536
+ traverse$1(ast, { CallExpression(callPath) {
537
+ if (!getNavigationMethod(callPath, bindings)) return;
538
+ const argument = callPath.node.arguments?.[0];
539
+ const target = getStaticString(argument) ?? getRouteFromObject(argument);
540
+ if (target) targets.push(normalizeStaticTarget(target, sourcePage));
541
+ } });
542
+ } catch {}
543
+ return [...new Set(targets)];
544
+ }
545
+ function collectTemplateTargets(source, sourcePage) {
546
+ const targets = [];
547
+ const withoutComments = source.replace(/<!--[\s\S]*?-->/g, "");
548
+ TEMPLATE_NAVIGATOR_RE.lastIndex = 0;
549
+ for (const match of withoutComments.matchAll(TEMPLATE_NAVIGATOR_RE)) {
550
+ const target = match[2];
551
+ if (target) targets.push(normalizeStaticTarget(target, sourcePage));
552
+ }
553
+ return [...new Set(targets)];
554
+ }
555
+ function collectStaticRouteTargets(source, kind, sourcePage) {
556
+ return kind === "template" ? collectTemplateTargets(source, sourcePage) : collectScriptTargets(source, sourcePage);
557
+ }
558
+ //#endregion
559
+ //#region src/utils/preloadRule.ts
560
+ const PRELOAD_RULE_GLOB_RE = /[*?[\]{}()!+@]/g;
561
+ function normalizePagePath(value) {
562
+ return normalizeRoot(value).replace(/^\/+/, "");
563
+ }
564
+ function normalizePackageRoot(value) {
565
+ return normalizeRoot(value).replace(/^\/+|\/+$/g, "");
566
+ }
567
+ function normalizeRule(value, pattern) {
568
+ if (!isObject(value)) throw new TypeError(`routeRules.${pattern}.preload 必须是对象。`);
569
+ const packages = value.packages;
570
+ if (!Array.isArray(packages) || packages.length === 0 || packages.some((item) => typeof item !== "string" || !item.trim())) throw new TypeError(`routeRules.${pattern}.preload.packages 必须是非空字符串数组。`);
571
+ const network = value.network;
572
+ if (network !== void 0 && network !== "all" && network !== "wifi") throw new TypeError(`routeRules.${pattern}.preload.network 只能是 "all" 或 "wifi"。`);
573
+ const normalizedPackages = [...new Set(packages.map((item) => normalizePackageRoot(item)).filter(Boolean))];
574
+ if (normalizedPackages.length === 0) throw new TypeError(`routeRules.${pattern}.preload.packages 必须包含有效的分包 root。`);
575
+ return {
576
+ packages: normalizedPackages,
577
+ ...network === void 0 ? {} : { network }
578
+ };
579
+ }
580
+ function getRuleScore(pattern) {
581
+ const segments = pattern.split("/").filter(Boolean);
582
+ const wildcards = pattern.match(PRELOAD_RULE_GLOB_RE) ?? [];
583
+ PRELOAD_RULE_GLOB_RE.lastIndex = 0;
584
+ return [
585
+ segments.filter((segment) => {
586
+ PRELOAD_RULE_GLOB_RE.lastIndex = 0;
587
+ return !PRELOAD_RULE_GLOB_RE.test(segment);
588
+ }).length,
589
+ pattern.replace(PRELOAD_RULE_GLOB_RE, "").length,
590
+ -wildcards.length,
591
+ segments.length,
592
+ pattern.length
593
+ ];
594
+ }
595
+ function compareScores(left, right) {
596
+ for (let index = 0; index < Math.max(left.length, right.length); index += 1) {
597
+ const leftValue = left[index] ?? 0;
598
+ const rightValue = right[index] ?? 0;
599
+ if (leftValue !== rightValue) return leftValue > rightValue ? 1 : -1;
600
+ }
601
+ return 0;
602
+ }
603
+ function pageCandidates(page) {
604
+ const normalized = normalizePagePath(page);
605
+ const withoutPagesPrefix = normalized.startsWith("pages/") ? normalized.slice(6) : normalized;
606
+ const candidates = /* @__PURE__ */ new Set();
607
+ for (const route of [normalized, withoutPagesPrefix]) {
608
+ const withoutIndex = route.replace(/\/index$/, "") || route;
609
+ for (const value of [route, withoutIndex]) {
610
+ candidates.add(value);
611
+ candidates.add(`/${value}`);
612
+ }
613
+ }
614
+ return [...candidates];
615
+ }
616
+ function findRouteRuleMatch(page, routeRules) {
617
+ if (!routeRules) return;
618
+ const candidates = pageCandidates(page);
619
+ let matched;
620
+ for (const [pattern, value] of Object.entries(routeRules)) {
621
+ if (!value || value.preload === void 0) continue;
622
+ if (!candidates.some((candidate) => picomatch(pattern)(candidate))) continue;
623
+ const rule = normalizeRule(value.preload, pattern);
624
+ const score = getRuleScore(pattern);
625
+ if (!matched || compareScores(score, matched.score) > 0) matched = {
626
+ page,
627
+ rule,
628
+ pattern,
629
+ score
630
+ };
631
+ }
632
+ if (!matched) return;
633
+ const { score: _score, ...result } = matched;
634
+ return result;
635
+ }
636
+ function collectSubPackages(appJson) {
637
+ return (Array.isArray(appJson.subPackages) ? appJson.subPackages : Array.isArray(appJson.subpackages) ? appJson.subpackages : []).flatMap((item) => {
638
+ if (!isObject(item) || typeof item.root !== "string") return [];
639
+ const root = normalizePackageRoot(item.root);
640
+ return (Array.isArray(item.pages) ? item.pages.filter((page) => typeof page === "string" && page.trim().length > 0) : []).map((page) => ({
641
+ route: normalizePagePath(path.posix.join(root, page)),
642
+ packageRoot: root,
643
+ ...item.independent === true ? { independent: true } : {}
644
+ }));
645
+ });
646
+ }
647
+ function collectPreloadPages(appJson) {
648
+ return [...Array.isArray(appJson.pages) ? appJson.pages.filter((page) => typeof page === "string" && page.trim().length > 0).map((page) => ({ route: normalizePagePath(page) })) : [], ...collectSubPackages(appJson)];
649
+ }
650
+ function findPreloadRuleKey(page, preloadRule) {
651
+ const candidates = pageCandidates(page);
652
+ return Object.keys(preloadRule).find((candidate) => candidates.includes(normalizePagePath(candidate)));
653
+ }
654
+ function resolvePreloadPackageIdentifier(value, appJson) {
655
+ const normalized = value === "__APP__" ? value : normalizePackageRoot(value);
656
+ if (!normalized || normalized === "__APP__") return normalized || void 0;
657
+ const source = Array.isArray(appJson.subPackages) ? appJson.subPackages : Array.isArray(appJson.subpackages) ? appJson.subpackages : [];
658
+ for (const item of source) {
659
+ if (!isObject(item) || typeof item.root !== "string") continue;
660
+ const root = normalizePackageRoot(item.root);
661
+ if (root === normalized || typeof item.name === "string" && item.name === value) return root;
662
+ }
663
+ return normalized;
664
+ }
665
+ function cloneRule(rule) {
666
+ if (!isObject(rule)) return rule;
667
+ const packages = Array.isArray(rule.packages) ? rule.packages.filter((item) => typeof item === "string") : [];
668
+ return {
669
+ ...rule,
670
+ packages: [...packages]
671
+ };
672
+ }
673
+ /**
674
+ * @description 将 routeRules 中的 preload 声明合成为 app.json.preloadRule。
675
+ * 手写的 preloadRule 保持优先,其他平台不生成微信专属字段。
676
+ */
677
+ function applyPreloadRulesToAppJson(appJson, routeRules, platform) {
678
+ if (platform !== "weapp" || !routeRules) return appJson;
679
+ const existing = isObject(appJson.preloadRule) ? appJson.preloadRule : {};
680
+ const next = { ...existing };
681
+ for (const page of collectPreloadPages(appJson)) {
682
+ const match = findRouteRuleMatch(page.route, routeRules);
683
+ if (!match || findPreloadRuleKey(page.route, existing) !== void 0) continue;
684
+ next[page.route] = cloneRule(match.rule);
685
+ }
686
+ if (Object.keys(next).length > 0) appJson.preloadRule = next;
687
+ return appJson;
688
+ }
689
+ function suggestPreloadRules(appJson, pageSources) {
690
+ const pages = collectPreloadPages(appJson);
691
+ const pageByRoute = new Map(pages.map((page) => [page.route, page]));
692
+ const suggestions = [];
693
+ const uncovered = /* @__PURE__ */ new Set();
694
+ for (const page of pages) {
695
+ const source = pageSources.get(page.route);
696
+ for (const kind of ["template", "script"]) for (const target of collectStaticRouteTargets(source?.[kind] ?? "", kind, page.route)) {
697
+ const targetPage = pageByRoute.get(target);
698
+ if (!targetPage) continue;
699
+ const packageRoot = targetPage.packageRoot ?? (page.independent ? "__APP__" : void 0);
700
+ if (!packageRoot || packageRoot === page.packageRoot) continue;
701
+ const suggestion = {
702
+ page: page.route,
703
+ packageRoot,
704
+ target,
705
+ source: kind
706
+ };
707
+ suggestions.push(suggestion);
708
+ }
709
+ if (source && !source.template && !source.script) uncovered.add(page.route);
710
+ }
711
+ return {
712
+ pages,
713
+ suggestions,
714
+ uncovered: [...uncovered]
715
+ };
716
+ }
717
+ //#endregion
718
+ //#region src/plugins/asset/prune.ts
719
+ /** 成功写出后仅撤销上一轮持有的文件,不清空目录,也不越过输出根内的符号链接。 */
720
+ async function pruneOwnedAssetFiles(outDir, fileNames) {
721
+ const root = path$1.resolve(outDir);
722
+ const files = [...fileNames].map((fileName) => {
723
+ const normalized = fileName.replaceAll("\\", "/");
724
+ const file = path$1.resolve(root, normalized);
725
+ const relative = path$1.relative(root, file);
726
+ if (!relative || relative === ".." || relative.startsWith(`..${path$1.sep}`) || path$1.isAbsolute(relative) || path$1.posix.isAbsolute(normalized) || /^[a-z]:/i.test(normalized)) throw new Error(`Invalid owned output asset path: ${fileName}`);
727
+ return file;
728
+ });
729
+ if (!files.length) return;
730
+ let realRoot;
731
+ try {
732
+ realRoot = await realpath(root);
733
+ } catch (error) {
734
+ if (error.code === "ENOENT") return;
735
+ throw error;
736
+ }
737
+ for (const file of files) try {
738
+ const parent = await realpath(path$1.dirname(file));
739
+ const relative = path$1.relative(realRoot, parent);
740
+ if (relative === ".." || relative.startsWith(`..${path$1.sep}`) || path$1.isAbsolute(relative)) throw new Error("Owned output asset parent resolves outside the output directory");
741
+ await unlink(file);
742
+ } catch (error) {
743
+ if (error.code !== "ENOENT") throw error;
744
+ }
745
+ }
746
+ //#endregion
747
+ //#region src/runtime/viteHost/engine.ts
748
+ function readIdentity(file) {
749
+ const value = JSON.parse(readFileSync(file, "utf8"));
750
+ if (!value || typeof value !== "object" || !("name" in value) || typeof value.name !== "string" || !("version" in value) || typeof value.version !== "string") throw new Error("[weapp-vite] Vite 宿主 package.json 缺少 name/version。");
751
+ return {
752
+ name: value.name,
753
+ version: value.version
754
+ };
755
+ }
756
+ /** 按宿主的真实导出解析引擎,不依赖扁平 node_modules 布局或版本号相等。 */
757
+ function resolveViteHost(importer = import.meta.url) {
758
+ const packagePath = createRequire(importer).resolve("vite/package.json");
759
+ const identity = readIdentity(packagePath);
760
+ const hostRequire = createRequire(packagePath);
761
+ if (identity.name === "@voidzero-dev/vite-plus-core") return {
762
+ kind: "vite-plus",
763
+ packagePath,
764
+ packageVersion: identity.version,
765
+ experimentalPath: hostRequire.resolve("@voidzero-dev/vite-plus-core/rolldown/experimental")
766
+ };
767
+ if (identity.name !== "vite") throw new Error(`[weapp-vite] 不支持的 Vite 宿主:${identity.name}@${identity.version}。`);
768
+ return {
769
+ kind: "vite",
770
+ packagePath,
771
+ packageVersion: identity.version,
772
+ experimentalPath: hostRequire.resolve("rolldown/experimental")
773
+ };
774
+ }
775
+ /** 加载与宿主绑定的引擎;缺失能力时保留原始错误,禁止回退到另一套引擎。 */
776
+ async function loadHostRolldown(importer) {
777
+ let identity;
778
+ try {
779
+ identity = resolveViteHost(importer);
780
+ const runtime = await import(pathToFileURL(identity.experimentalPath).href);
781
+ if (typeof runtime.dev !== "function" || typeof runtime.scan !== "function") throw new TypeError("Rolldown 缺少 dev/scan 能力");
782
+ return runtime;
783
+ } catch (cause) {
784
+ const host = identity ? `${identity.kind}@${identity.packageVersion}` : "vite";
785
+ throw new Error(`[weapp-vite] 无法加载 ${host} 配套的 Rolldown;请检查宿主依赖和 Vite+ alias 配置。`, { cause });
786
+ }
787
+ }
788
+ /** 原生输出写出也绑定宿主引擎,避免 Vite+ 额外加载包内另一套 Rolldown。 */
789
+ async function loadHostRolldownBuild(importer) {
790
+ const identity = resolveViteHost(importer);
791
+ const entry = createRequire(identity.packagePath).resolve(identity.kind === "vite-plus" ? "@voidzero-dev/vite-plus-core/rolldown" : "rolldown");
792
+ const runtime = await import(pathToFileURL(entry).href);
793
+ if (typeof runtime.rolldown !== "function") throw new TypeError(`[weapp-vite] ${identity.kind}@${identity.packageVersion} 缺少 Rolldown 原生写出能力。`);
794
+ return runtime;
795
+ }
796
+ //#endregion
797
+ //#region src/utils/projectConfigOutput.ts
798
+ /** 平台项目目录独立发布,禁止覆盖由主编译持有的小程序目录。 */
799
+ async function collectProjectConfigAssets(sourceDir, outputRoot, outDir, watch) {
800
+ const assets = [];
801
+ async function visit(dir) {
802
+ watch?.(path.normalize(await realpath(dir)));
803
+ for (const entry of await readdir(dir, { withFileTypes: true })) {
804
+ const file = path.join(dir, entry.name);
805
+ if (entry.isSymbolicLink()) throw new Error(`[weapp-vite] 平台项目配置目录不支持符号链接:${path.relative(sourceDir, file)}`);
806
+ const fileName = path.relative(sourceDir, file);
807
+ const target = path.resolve(outputRoot, fileName);
808
+ const relative = path.relative(path.resolve(outDir), target);
809
+ if (!relative || !relative.startsWith("../") && relative !== ".." && !path.isAbsolute(relative)) throw new Error(`[weapp-vite] 平台项目配置不能覆盖小程序输出:${fileName}`);
810
+ if (entry.isDirectory()) await visit(file);
811
+ else if (entry.isFile()) {
812
+ watch?.(path.normalize(await realpath(file)));
813
+ assets.push({
814
+ fileName,
815
+ source: await readFile$1(file)
816
+ });
817
+ }
818
+ }
819
+ }
820
+ await visit(sourceDir);
821
+ return assets;
822
+ }
823
+ /** 使用宿主配套引擎写出平台配置,写入失败时不删除上一轮文件。 */
824
+ async function publishProjectConfigAssets(outputRoot, assets, previous = /* @__PURE__ */ new Set()) {
825
+ const entry = "\0weapp-vite-project-config-output";
826
+ const { rolldown } = await loadHostRolldownBuild();
827
+ const bundle = await rolldown({
828
+ input: entry,
829
+ logLevel: "silent",
830
+ plugins: [{
831
+ name: "weapp-vite:project-config-writer",
832
+ resolveId: (id) => id === entry ? entry : void 0,
833
+ load: (id) => id === entry ? "export {}" : void 0,
834
+ generateBundle(_options, output) {
835
+ for (const [name, item] of Object.entries(output)) if (item.type === "chunk" && item.facadeModuleId === entry) delete output[name];
836
+ for (const asset of assets) this.emitFile({
837
+ type: "asset",
838
+ ...asset
839
+ });
840
+ }
841
+ }]
842
+ });
843
+ const current = new Set(assets.map((asset) => asset.fileName));
844
+ try {
845
+ await bundle.write({
846
+ dir: outputRoot,
847
+ format: "es"
848
+ });
849
+ await pruneOwnedAssetFiles(outputRoot, [...previous].filter((file) => !current.has(file)));
850
+ } finally {
851
+ await bundle.close();
852
+ }
853
+ return current;
854
+ }
855
+ //#endregion
856
+ //#region src/utils/projectConfig.ts
857
+ async function readProjectConfigFile(filePath, required) {
858
+ if (!await fs$1.pathExists(filePath)) {
859
+ if (required) throw new Error(`找不到项目配置文件:${filePath}`);
860
+ return {};
861
+ }
862
+ try {
863
+ return await fs$1.readJson(filePath) || {};
864
+ } catch {
865
+ throw new Error(`解析 json 格式失败, ${filePath} 为非法的 json 格式`);
866
+ }
867
+ }
868
+ const DEFAULT_PROJECT_PRIVATE_CONFIG_FILE_NAME = "project.private.config.json";
869
+ function getProjectConfigFileName(platform) {
870
+ return getProjectPlatformOptions(platform).projectConfigFileName;
871
+ }
872
+ function getProjectPrivateConfigFileName(_) {
873
+ return DEFAULT_PROJECT_PRIVATE_CONFIG_FILE_NAME;
874
+ }
875
+ function getProjectConfigRootKeys(platform) {
876
+ return getProjectPlatformOptions(platform).projectConfigRootKeys;
877
+ }
878
+ function resolveProjectConfigRoot(projectConfig, platform) {
879
+ const keys = getProjectConfigRootKeys(platform);
880
+ for (const key of keys) {
881
+ const value = projectConfig[key];
882
+ if (typeof value === "string" && value.trim()) return value;
883
+ }
884
+ }
885
+ async function getProjectConfig(root, options) {
886
+ const baseJsonPath = path.resolve(root, options?.basePath ?? "project.config.json");
887
+ const privateJsonPath = path.resolve(root, options?.privatePath ?? "project.private.config.json");
888
+ const baseJson = await readProjectConfigFile(baseJsonPath, true);
889
+ const privateJson = options?.ignorePrivate ? {} : await readProjectConfigFile(privateJsonPath, false);
890
+ return defuOverrideArray(privateJson, baseJson);
891
+ }
892
+ async function getProjectPrivateConfig(root, options) {
893
+ return await readProjectConfigFile(path.resolve(root, options?.privatePath ?? "project.private.config.json"), false);
894
+ }
895
+ async function disableProjectPrivateConfigHotReload(filePath) {
896
+ const config = await readProjectConfigFile(filePath, true);
897
+ const setting = config.setting && typeof config.setting === "object" && !Array.isArray(config.setting) ? config.setting : {};
898
+ if (setting.compileHotReLoad === false) return false;
899
+ config.setting = {
900
+ ...setting,
901
+ compileHotReLoad: false
902
+ };
903
+ await fs$1.writeFile(filePath, `${JSON.stringify(config, null, 2)}\n`, "utf8");
904
+ return true;
905
+ }
906
+ function resolveProjectConfigSyncDirs(options) {
907
+ const outputRoot = path.dirname(options.outDir);
908
+ const sourceBasePath = path.resolve(options.projectConfigPath);
909
+ const sourceDir = path.dirname(sourceBasePath);
910
+ const resolvedOutputRoot = path.resolve(outputRoot);
911
+ const resolvedSourceDir = path.resolve(sourceDir);
912
+ return {
913
+ outputRoot,
914
+ sourceBasePath,
915
+ sourceDir,
916
+ resolvedOutputRoot,
917
+ resolvedSourceDir,
918
+ shouldSync: resolvedSourceDir !== resolvedOutputRoot
919
+ };
920
+ }
921
+ async function syncProjectConfigToOutput(options) {
922
+ if (!options.enabled || !options.projectConfigPath) return;
923
+ const syncDirs = resolveProjectConfigSyncDirs({
924
+ outDir: options.outDir,
925
+ projectConfigPath: options.projectConfigPath
926
+ });
927
+ if (!syncDirs.shouldSync) return;
928
+ const assets = await collectProjectConfigAssets(syncDirs.sourceDir, syncDirs.outputRoot, options.outDir);
929
+ await publishProjectConfigAssets(syncDirs.outputRoot, assets);
930
+ }
931
+ //#endregion
932
+ //#region src/utils/reExport.ts
933
+ function getExportedName(spec) {
934
+ const exported = spec?.exported;
935
+ if (!exported) return;
936
+ if (exported.type === "Identifier") return exported.name;
937
+ if (exported.type === "StringLiteral") return exported.value;
938
+ }
939
+ function getSourceValue(node) {
940
+ const source = node?.source;
941
+ if (!source || source.type !== "StringLiteral" && source.type !== "Literal") return;
942
+ return source.value;
943
+ }
944
+ function getReExportCacheKey(file, astEngine) {
945
+ return `${astEngine ?? "babel"}::${file}`;
946
+ }
947
+ function parseModuleForReExport(code, astEngine) {
948
+ if (astEngine === "oxc") return parseJsLikeWithEngine(code, {
949
+ engine: "oxc",
950
+ filename: "inline.ts"
951
+ });
952
+ return parse$2(code, BABEL_TS_MODULE_PARSER_OPTIONS$1).program;
953
+ }
954
+ async function resolveReExportedInternal(exporterFile, exportName, depth, visited, options) {
955
+ if (depth <= 0) return;
956
+ if (visited.has(exporterFile)) return;
957
+ visited.add(exporterFile);
958
+ const cacheKey = getReExportCacheKey(exporterFile, options.astEngine);
959
+ let entry = options.cache.get(cacheKey);
960
+ if (!entry) {
961
+ entry = /* @__PURE__ */ new Map();
962
+ options.cache.set(cacheKey, entry);
963
+ }
964
+ if (entry.has(exportName)) return entry.get(exportName);
965
+ let code;
966
+ try {
967
+ code = await options.readFile(exporterFile);
968
+ } catch {
969
+ entry.set(exportName, void 0);
970
+ return;
971
+ }
972
+ let ast;
973
+ try {
974
+ ast = parseModuleForReExport(code, options.astEngine);
975
+ } catch {
976
+ entry.set(exportName, void 0);
977
+ return;
978
+ }
979
+ const exportAllSources = [];
980
+ for (const node of ast.body ?? []) {
981
+ if (node?.type === "ExportNamedDeclaration") {
982
+ const source = getSourceValue(node);
983
+ if (!source) continue;
984
+ for (const spec of node.specifiers ?? []) {
985
+ if (spec?.type !== "ExportSpecifier") continue;
986
+ const exportedName = getExportedName(spec);
987
+ if (!exportedName || exportedName !== exportName) continue;
988
+ const resolved = await options.resolveId(source, exporterFile);
989
+ if (resolved) {
990
+ entry.set(exportName, resolved);
991
+ return resolved;
992
+ }
993
+ }
994
+ }
995
+ if (node?.type === "ExportAllDeclaration") {
996
+ const source = getSourceValue(node);
997
+ if (source) exportAllSources.push(source);
998
+ }
999
+ }
1000
+ for (const source of exportAllSources) {
1001
+ const hopId = await options.resolveId(source, exporterFile);
1002
+ if (!hopId) continue;
1003
+ const nested = await resolveReExportedInternal(hopId, exportName, depth - 1, visited, options);
1004
+ if (nested) {
1005
+ entry.set(exportName, nested);
1006
+ return nested;
1007
+ }
1008
+ }
1009
+ entry.set(exportName, void 0);
1010
+ }
1011
+ async function resolveReExportedName(exporterFile, exportName, options) {
1012
+ return resolveReExportedInternal(exporterFile, exportName, options.maxDepth ?? 4, /* @__PURE__ */ new Set(), options);
1013
+ }
1014
+ //#endregion
1015
+ //#region src/utils/toAbsoluteId.ts
1016
+ function resolveAbsoluteIdBaseDir(configService, importer, options) {
1017
+ const cleanImporter = importer ? normalizeFsResolvedId(importer) : void 0;
1018
+ if (cleanImporter && !isSkippableResolvedId(cleanImporter) && path.isAbsolute(cleanImporter)) return path.dirname(cleanImporter);
1019
+ return options?.base === "cwd" ? configService.cwd : configService.absoluteSrcRoot;
1020
+ }
1021
+ /**
1022
+ * 将可能为相对路径的 id 解析为绝对路径。
1023
+ *
1024
+ * - 会先对 id/importer 做 `normalizeFsResolvedId`(去 query、处理 file://、/@fs/、\0vue: 等)
1025
+ * - 若 id 已是绝对路径则直接返回
1026
+ * - 若 importer 是绝对路径,则以 importer 所在目录为基准解析
1027
+ * - 否则使用 `configService.absoluteSrcRoot`(默认)或 `configService.cwd`(可选)作为基准解析
1028
+ *
1029
+ * 注意:对于 `\0xxx` / `node:` 这类虚拟 id,会原样返回(不做路径解析)。
1030
+ */
1031
+ function toAbsoluteId(id, configService, importer, options) {
1032
+ const cleanId = normalizeFsResolvedId(id);
1033
+ if (!cleanId || isSkippableResolvedId(cleanId)) return cleanId;
1034
+ if (path.isAbsolute(cleanId)) return cleanId;
1035
+ const baseDir = resolveAbsoluteIdBaseDir(configService, importer, options);
1036
+ return path.resolve(baseDir, cleanId);
1037
+ }
1038
+ //#endregion
1039
+ //#region src/utils/usingComponentFrom.ts
1040
+ function shouldResolveUsingComponentFrom(normalizedResolvedFile) {
1041
+ return Boolean(normalizedResolvedFile && !isSkippableResolvedId(normalizedResolvedFile) && path.isAbsolute(normalizedResolvedFile));
1042
+ }
1043
+ function usingComponentFromResolvedFile(resolvedFile, configService) {
1044
+ if (!resolvedFile) return;
1045
+ const normalized = normalizeFsResolvedId(resolvedFile);
1046
+ if (!shouldResolveUsingComponentFrom(normalized)) return;
1047
+ const base = removeExtensionDeep(normalized);
1048
+ const relative = configService.relativeOutputPath(base);
1049
+ if (!relative || relative.startsWith("..")) return;
1050
+ return `/${toPosixPath(relative)}`;
1051
+ }
1052
+ //#endregion
1053
+ //#region src/utils/weappConfig.ts
1054
+ const WEAPP_VITE_CONFIG_CANDIDATES = [
1055
+ "weapp-vite.config.ts",
1056
+ "weapp-vite.config.mts",
1057
+ "weapp-vite.config.cts",
1058
+ "weapp-vite.config.js",
1059
+ "weapp-vite.config.mjs",
1060
+ "weapp-vite.config.cjs",
1061
+ "weapp-vite.config.json"
1062
+ ];
1063
+ const WEAPP_VITE_CONFIG_SET = new Set(WEAPP_VITE_CONFIG_CANDIDATES);
1064
+ function resolveSpecifiedWeappConfigPath(root, specified) {
1065
+ return path.isAbsolute(specified) ? specified : path.resolve(root, specified);
1066
+ }
1067
+ function isWeappConfigBasename(filePath) {
1068
+ return WEAPP_VITE_CONFIG_SET.has(path.basename(filePath));
1069
+ }
1070
+ function isExplicitCustomConfigFile(filePath) {
1071
+ return path.basename(filePath).includes(".config.") && !isDefaultViteConfigBasename(filePath) && !isWeappConfigBasename(filePath);
1072
+ }
1073
+ async function findWeappConfigInDirectory(directory) {
1074
+ for (const filename of WEAPP_VITE_CONFIG_CANDIDATES) {
1075
+ const candidatePath = path.resolve(directory, filename);
1076
+ if (await fs$1.pathExists(candidatePath)) return candidatePath;
1077
+ }
1078
+ }
1079
+ async function resolveWeappConfigFile(options) {
1080
+ const { root, specified } = options;
1081
+ if (specified) {
1082
+ const resolvedSpecified = resolveSpecifiedWeappConfigPath(root, specified);
1083
+ if (isWeappConfigBasename(resolvedSpecified)) {
1084
+ if (await fs$1.pathExists(resolvedSpecified)) return resolvedSpecified;
1085
+ return;
1086
+ }
1087
+ if (isExplicitCustomConfigFile(resolvedSpecified)) return;
1088
+ const fromSpecifiedDirectory = await findWeappConfigInDirectory(path.dirname(resolvedSpecified));
1089
+ if (fromSpecifiedDirectory) return fromSpecifiedDirectory;
1090
+ }
1091
+ return findWeappConfigInDirectory(root);
1092
+ }
1093
+ //#endregion
1094
+ export { parseNpmPackageSpecifier as $, pathExists as A, ALIPAY_GENERIC_COMPONENT_PLACEHOLDER as B, resolvePreloadPackageIdentifier as C, createCachedEntryResolveOptions as D, loadViteConfigFile as E, BABEL_TS_MODULE_PARSER_OPTIONS$1 as F, normalizeAppJson as G, getAliasEntries as H, generate$1 as I, resolveJson as J, parseCommentJson as K, parse$2 as L, createCjsConfigLoadError as M, getPathExistsTtlMs as N, resolveEntryPath as O, getReadFileCheckMtime as P, normalizeNpmImportPathByPlatform as Q, parseJsLike$1 as R, findPreloadRuleKey as S, TYPELESS_PACKAGE_JSON_WARNING_CODE as T, jsonFileRemoveJsExtension as U, WEAPP_SCOPED_SLOT_GENERIC_COMPONENT_PLACEHOLDER as V, matches as W, hasNpmDependencyPrefix as X, toKebabCaseComponentName as Y, normalizeNpmImportLookupPath as Z, loadHostRolldown as _, resolveReExportedName as a, applyPreloadRulesToAppJson as b, getProjectConfigFileName as c, getProjectPrivateConfigFileName as d, resolveNpmDependencyId as et, resolveProjectConfigRoot as f, publishProjectConfigAssets as g, collectProjectConfigAssets as h, toAbsoluteId as i, readFile$2 as j, invalidateFileCache as k, getProjectConfigRootKeys as l, syncProjectConfigToOutput as m, shouldResolveUsingComponentFrom as n, disableProjectPrivateConfigHotReload as o, resolveProjectConfigSyncDirs as p, resolveImportee as q, usingComponentFromResolvedFile as r, getProjectConfig as s, resolveWeappConfigFile as t, getProjectPrivateConfig as u, loadHostRolldownBuild as v, suggestPreloadRules as w, collectPreloadPages as x, pruneOwnedAssetFiles as y, traverse$1 as z };