weapp-vite 7.4.0 → 7.6.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 (126) hide show
  1. package/README.md +59 -3
  2. package/THIRD_PARTY_NOTICES.md +60 -0
  3. package/bin/bootstrap.js +14 -1
  4. package/dist/action-B3YZMA-h.mjs +255 -0
  5. package/dist/action-BELcDNNv.mjs +139 -0
  6. package/dist/action-BOk3vGI7.mjs +1110 -0
  7. package/dist/action-DlC6JYpt.mjs +95 -0
  8. package/dist/action-zEDY7oh_.mjs +247 -0
  9. package/dist/adapters-CcHrsYaj.mjs +1 -0
  10. package/dist/analyze-DN79YOAH.mjs +184 -0
  11. package/dist/artifacts-BOyC9Fy-.mjs +106 -0
  12. package/dist/assets-C5_YYXNk.mjs +637 -0
  13. package/dist/auto-import-components/resolvers.mjs +1 -2
  14. package/dist/auto-import-presets/wevu-router.mjs +1 -2
  15. package/dist/auto-import-presets/wevu.mjs +1 -2
  16. package/dist/auto-routes.mjs +2 -1
  17. package/dist/budget-CTLOHwgI.d.mts +177 -0
  18. package/dist/budget-EOeEycc_.mjs +65 -0
  19. package/dist/builtProject-C29udgXY.mjs +541 -0
  20. package/dist/chunkStrategy-DY_LZIIe.mjs +1448 -0
  21. package/dist/classifier-DBJY__kg.mjs +88 -0
  22. package/dist/cli-acceptance.d.mts +1 -0
  23. package/dist/cli-acceptance.mjs +21 -0
  24. package/dist/cli.mjs +519 -5049
  25. package/dist/compatibility.mjs +1 -2
  26. package/dist/{config-Dbvj5yK7.d.mts → config-Bf6DWhyb.d.mts} +220 -76
  27. package/dist/config.d.mts +3 -3
  28. package/dist/config.mjs +1 -1
  29. package/dist/{constants-WOsG3Eqd.mjs → constants-DEZdcsMn.mjs} +1 -1
  30. package/dist/{createContext-UOEgeYnA.mjs → createCompilerContextInstance-aYwi8wQt.mjs} +36862 -32020
  31. package/dist/createContext-tApLtII-.mjs +15 -0
  32. package/dist/dashboard/analyze.d.mts +48 -0
  33. package/dist/dashboard/analyze.mjs +3 -0
  34. package/dist/dashboard/vite.d.mts +1 -1
  35. package/dist/dashboard.d.mts +3 -2
  36. package/dist/dashboard.mjs +1748 -1
  37. package/dist/dashboardTransport-C_Y6jMp-.mjs +16 -0
  38. package/dist/dashboardViteBridge-DCGR43aM.mjs +302 -0
  39. package/dist/dev-C2fgr_Xd.mjs +67 -0
  40. package/dist/devProvider-D-hTfsEO.mjs +3027 -0
  41. package/dist/docs/README.md +59 -3
  42. package/dist/docs/ai-workflows.md +4 -0
  43. package/dist/docs/doctor.md +38 -0
  44. package/dist/docs/getting-started.md +3 -1
  45. package/dist/docs/index.md +3 -1
  46. package/dist/docs/mcp.md +104 -1
  47. package/dist/docs/testing.md +29 -2
  48. package/dist/docs/troubleshooting.md +16 -0
  49. package/dist/docs/uni-app-component-libraries.md +8 -7
  50. package/dist/docs/upload.md +40 -3
  51. package/dist/docs/vite-plugin.md +171 -0
  52. package/dist/docs/vue-sfc.md +42 -0
  53. package/dist/docs/weapp-config.md +54 -0
  54. package/dist/docs/wevu-authoring.md +10 -0
  55. package/dist/doctor-worker.d.mts +1 -0
  56. package/dist/doctor-worker.mjs +60 -0
  57. package/dist/doctor.d.mts +144 -0
  58. package/dist/doctor.mjs +850 -0
  59. package/dist/engine-C66J0HLz.mjs +54 -0
  60. package/dist/eslint.mjs +1 -2
  61. package/dist/{file-giE9UMZa.mjs → file-CcIOmqhC.mjs} +58 -24
  62. package/dist/file-DtcteQ4G.mjs +1 -0
  63. package/dist/files-BqxFIPRp.mjs +45 -0
  64. package/dist/forwardConsole-B0Reo8Lf.mjs +511 -0
  65. package/dist/getInstance-BAIaU2y9.mjs +1 -0
  66. package/dist/getInstance-Dt9IQDKr.mjs +28 -0
  67. package/dist/history-BIiRCzbq.mjs +784 -0
  68. package/dist/i18n.d.mts +1 -1
  69. package/dist/index-D5rgBzYZ.d.mts +740 -0
  70. package/dist/index.d.mts +12 -10
  71. package/dist/index.mjs +3 -2
  72. package/dist/json.d.mts +1 -1
  73. package/dist/json.mjs +1 -2
  74. package/dist/lib-DjccSI1B.mjs +143 -0
  75. package/dist/lifecycle-C36WSbQS.mjs +413 -0
  76. package/dist/loadConfig-BWIsDXR4.mjs +59 -0
  77. package/dist/loadConfig-D-BpBgsk.mjs +1 -0
  78. package/dist/logBuildAppFinish-ChjwATMv.mjs +57 -0
  79. package/dist/logger-DGn5iEVN.mjs +1 -0
  80. package/dist/mcp-CYgX9HpO.mjs +86 -0
  81. package/dist/{mcp-BG6TliEg.mjs → mcp-Cj8Maqo6.mjs} +16 -7
  82. package/dist/mcp.d.mts +6 -3
  83. package/dist/mcp.mjs +1 -2
  84. package/dist/mcpClient-DVLvFLZv.mjs +287 -0
  85. package/dist/metadata-hwF7QRcS.mjs +59 -0
  86. package/dist/nodeEnv-BmH8UZPR.mjs +7 -0
  87. package/dist/openIde-CroqOgk5.mjs +648 -0
  88. package/dist/options-jqFwfD1G.mjs +34 -0
  89. package/dist/package-Cmakyy3J.mjs +4 -0
  90. package/dist/path-CYYIQGS7.mjs +44 -0
  91. package/dist/{platform-DTWs5QRi.mjs → platform-CnkySBKz.mjs} +1 -1
  92. package/dist/processCleanup-BQn2kTcK.mjs +19 -0
  93. package/dist/protocol-Cg6Jdlvb.mjs +141 -0
  94. package/dist/reader-sh_POQ9-.mjs +93 -0
  95. package/dist/realpathScope-Tf9mz-fh.mjs +23 -0
  96. package/dist/report-hyonPGbZ.mjs +107 -0
  97. package/dist/resolvedId-CiDl7SC1.mjs +60 -0
  98. package/dist/{resolvers-icNxkpcy.mjs → resolvers-Dod-euqX.mjs} +4 -1
  99. package/dist/resolvers.mjs +1 -2
  100. package/dist/runtime-CLUhQsdA.mjs +43 -0
  101. package/dist/{runtime-Ee2HY6gR.d.mts → runtime-DpVf714f.d.mts} +1 -1
  102. package/dist/runtime.d.mts +1 -1
  103. package/dist/runtime.mjs +1 -2
  104. package/dist/schematics-kO26eQRT.mjs +91 -0
  105. package/dist/session-D3zsdzIy.mjs +452 -0
  106. package/dist/test.d.mts +1 -0
  107. package/dist/test.mjs +204 -45
  108. package/dist/{types-CgZn5X6j.d.mts → types-D-kfuyVa.d.mts} +1 -2
  109. package/dist/types-D0FFexRF.d.mts +39 -0
  110. package/dist/types.d.mts +3 -3
  111. package/dist/{upload-D0RcEWrq.mjs → upload-DozK8UdN.mjs} +278 -15
  112. package/dist/upload-worker.mjs +136 -3
  113. package/dist/utils-Dy51PYAC.mjs +1034 -0
  114. package/dist/vite.d.mts +9 -0
  115. package/dist/vite.mjs +309 -0
  116. package/dist/volar.d.mts +2 -2
  117. package/dist/web-apis.mjs +1 -2
  118. package/dist/wxs-BT8btflA.mjs +112 -0
  119. package/dist/wxs-Z4VQDeJ_.mjs +1 -0
  120. package/package.json +80 -48
  121. package/dist/adapters-BwnMMIZR.mjs +0 -2
  122. package/dist/dashboard-BzaVesmQ.mjs +0 -558
  123. package/dist/file-D19nbDoN.mjs +0 -2
  124. package/dist/getInstance-CYF1vl5l.mjs +0 -2
  125. package/dist/index-DbqVupg0.d.mts +0 -246
  126. package/dist/logger-mt4mSTqV.mjs +0 -2
@@ -0,0 +1,95 @@
1
+ import { r as logger_default } from "./logger-DGn5iEVN.mjs";
2
+ import { t as createCompilerContext } from "./createContext-tApLtII-.mjs";
3
+ import { i as resolveRuntimeTargets, t as createInlineConfig } from "./runtime-CLUhQsdA.mjs";
4
+ import { o as resolveConfigFile, r as filterDuplicateOptions } from "./options-jqFwfD1G.mjs";
5
+ import { t as setCommandNodeEnv } from "./nodeEnv-BmH8UZPR.mjs";
6
+ import { o as resolveUploadTimeout, t as UploadCommandError } from "./report-hyonPGbZ.mjs";
7
+ import { n as resolveUploadPlatforms } from "./upload-DozK8UdN.mjs";
8
+ import { t as terminateStaleSassEmbeddedProcess } from "./processCleanup-BQn2kTcK.mjs";
9
+ import { i as prepareAutoUploadMetadata, n as executeUploadTarget, r as UploadExecutionError, t as createUploadTarget } from "./builtProject-C29udgXY.mjs";
10
+ import process from "node:process";
11
+ import path from "node:path";
12
+ //#region src/cli/commands/upload/action.ts
13
+ async function buildUploadTarget(cwd, platform, options, action, item) {
14
+ const targets = resolveRuntimeTargets({ platform });
15
+ const ctx = await createCompilerContext({
16
+ cwd,
17
+ mode: options.mode ?? "production",
18
+ configFile: resolveConfigFile(options),
19
+ inlineConfig: createInlineConfig(targets),
20
+ cliPlatform: platform,
21
+ projectConfigPath: options.projectConfig,
22
+ emitDefaultAutoImportOutputs: false,
23
+ preloadAppEntry: false
24
+ });
25
+ try {
26
+ const target = await createUploadTarget(ctx.configService, options, action);
27
+ if (item) {
28
+ item.platform = target.platform;
29
+ item.requestedVersion = target.context.version;
30
+ item.stage = "build";
31
+ }
32
+ logger_default.info(`[${action}:${target.platform}] 构建${target.context.version ? ` ${target.context.version}` : ""}`);
33
+ await ctx.buildService.build({});
34
+ return target;
35
+ } finally {
36
+ ctx.watcherService.closeAll();
37
+ terminateStaleSassEmbeddedProcess();
38
+ }
39
+ }
40
+ async function runUploadCommand(root, options, action = "upload") {
41
+ filterDuplicateOptions(options);
42
+ const platforms = resolveUploadPlatforms(options.platform ?? options.p);
43
+ setCommandNodeEnv("production");
44
+ const cwd = path.resolve(root ?? process.cwd());
45
+ if (action === "preview") {
46
+ options = await prepareAutoUploadMetadata(cwd, options, action);
47
+ for (const platform of platforms) {
48
+ const target = await buildUploadTarget(cwd, platform, options, action);
49
+ await executeUploadTarget(target, options, action);
50
+ }
51
+ return;
52
+ }
53
+ const report = {
54
+ schemaVersion: 1,
55
+ action: "upload",
56
+ status: "success",
57
+ results: platforms.map((platform) => ({
58
+ platform: platform ?? null,
59
+ stage: "prepare",
60
+ status: "not-run"
61
+ }))
62
+ };
63
+ let active = report.results[0];
64
+ try {
65
+ const timeoutMs = resolveUploadTimeout(options.timeout);
66
+ options = await prepareAutoUploadMetadata(cwd, options, action);
67
+ for (const item of report.results) item.requestedVersion = options.uv?.trim();
68
+ for (const [index, platform] of platforms.entries()) {
69
+ active = report.results[index];
70
+ const target = await buildUploadTarget(cwd, platform, options, action, active);
71
+ active.stage = "validate";
72
+ const result = await executeUploadTarget(target, options, action, {
73
+ timeoutMs,
74
+ onUpload: () => {
75
+ active.stage = "upload";
76
+ }
77
+ });
78
+ active.status = options.dryRun ? "dry-run" : "success";
79
+ if (!options.dryRun) active.result = result;
80
+ }
81
+ return report;
82
+ } catch (error) {
83
+ report.status = "failed";
84
+ report.error = error instanceof Error ? error.message : String(error);
85
+ active.status = "failed";
86
+ active.error = report.error;
87
+ if (error instanceof UploadExecutionError) {
88
+ active.remoteOutcome = error.remoteOutcome;
89
+ if (error.remoteOutcome === "unknown" && error.reason !== "failed") active.status = "unknown";
90
+ }
91
+ throw new UploadCommandError(report);
92
+ }
93
+ }
94
+ //#endregion
95
+ export { runUploadCommand };
@@ -0,0 +1,247 @@
1
+ import { c as getBackendForCapability, n as formatBytes, u as CompilerSession } from "./createCompilerContextInstance-aYwi8wQt.mjs";
2
+ import { r as logger_default, t as colors } from "./logger-DGn5iEVN.mjs";
3
+ import { i as resolveRuntimeTargets, n as logRuntimeTarget, r as resolveConfiguredRuntimeTargets, t as createInlineConfig } from "./runtime-CLUhQsdA.mjs";
4
+ import { i as resolveIdeProjectPath, n as openIde } from "./openIde-CroqOgk5.mjs";
5
+ import { a as parseDashboardUiHost, i as isUiEnabled, o as resolveConfigFile, r as filterDuplicateOptions } from "./options-jqFwfD1G.mjs";
6
+ import { n as formatDuration, r as scheduleCompletedProductionBuildExit, t as logBuildAppFinish } from "./logBuildAppFinish-ChjwATMv.mjs";
7
+ import { n as createDashboardArtifactSnapshot } from "./artifacts-BOyC9Fy-.mjs";
8
+ import { i as startAnalyzeDashboard, n as writeAnalyzeHistorySnapshot, r as analyzeSubpackages, t as readLatestAnalyzeHistorySnapshot } from "./history-BIiRCzbq.mjs";
9
+ import { t as setCommandNodeEnv } from "./nodeEnv-BmH8UZPR.mjs";
10
+ import { a as resolveBuildUploadOptions } from "./report-hyonPGbZ.mjs";
11
+ import { a as prepareAutoUploadMetadataWithRollback, n as executeUploadTarget, o as validateAutoUploadMetadata, t as createUploadTarget } from "./builtProject-C29udgXY.mjs";
12
+ import process from "node:process";
13
+ import { Buffer } from "node:buffer";
14
+ const WINDOWS_SEPARATOR_RE = /\\/g;
15
+ function normalizeFileName(fileName) {
16
+ return fileName.replace(WINDOWS_SEPARATOR_RE, "/");
17
+ }
18
+ function getOutputItemBytes(item) {
19
+ if (item.type === "chunk") return typeof item.code === "string" ? Buffer.byteLength(item.code, "utf8") : 0;
20
+ if (typeof item.source === "string") return Buffer.byteLength(item.source, "utf8");
21
+ if (item.source instanceof Uint8Array) return item.source.byteLength;
22
+ return 0;
23
+ }
24
+ function resolveSubPackageRoot(fileName, roots) {
25
+ const normalized = normalizeFileName(fileName);
26
+ return roots.find((root) => normalized === root || normalized.startsWith(`${root}/`));
27
+ }
28
+ function collectPackageSizeReports(output, subPackageMap) {
29
+ const outputs = Array.isArray(output) ? output : [output];
30
+ const roots = [...subPackageMap?.keys() ?? []].filter(Boolean).sort((a, b) => b.length - a.length || a.localeCompare(b));
31
+ const packageBytes = /* @__PURE__ */ new Map([["__main__", 0]]);
32
+ for (const root of roots) packageBytes.set(root, 0);
33
+ for (const current of outputs) for (const item of current.output ?? []) {
34
+ const root = resolveSubPackageRoot(item.fileName, roots) ?? "__main__";
35
+ packageBytes.set(root, (packageBytes.get(root) ?? 0) + getOutputItemBytes(item));
36
+ }
37
+ const reports = [{
38
+ root: "__main__",
39
+ label: "主包",
40
+ bytes: packageBytes.get("__main__") ?? 0
41
+ }];
42
+ for (const root of roots) {
43
+ const meta = subPackageMap?.get(root);
44
+ const isIndependent = Boolean(meta?.subPackage.independent);
45
+ reports.push({
46
+ root,
47
+ label: `${isIndependent ? "独立分包" : "分包"} ${root}`,
48
+ bytes: packageBytes.get(root) ?? 0
49
+ });
50
+ }
51
+ return reports;
52
+ }
53
+ function logBuildPackageSizeReport(options) {
54
+ const warningBytes = Number(options.warningBytes ?? 2097152);
55
+ const reports = collectPackageSizeReports(options.output, options.subPackageMap);
56
+ logger_default.success("主包/分包体积报告:");
57
+ for (const report of reports) logger_default.info(`${report.label}:${formatBytes(report.bytes)}`);
58
+ if (!(Number.isFinite(warningBytes) && warningBytes > 0)) return;
59
+ for (const report of reports) {
60
+ if (report.bytes <= warningBytes) continue;
61
+ logger_default.warn(`[包体积] ${colors.yellow(report.label)} 体积 ${colors.yellow(formatBytes(report.bytes))},已超过阈值 ${colors.yellow(formatBytes(warningBytes))}。`);
62
+ }
63
+ }
64
+ //#endregion
65
+ //#region src/cli/commands/build/action.ts
66
+ function emitDashboardEvents(handle, events) {
67
+ handle?.emitRuntimeEvents(events);
68
+ }
69
+ function normalizeBuildSourcemap(value) {
70
+ if (value === "true") return true;
71
+ if (value === "false") return false;
72
+ return value;
73
+ }
74
+ function normalizeBuildMinify(value) {
75
+ if (value === "true") return true;
76
+ if (value === "false") return false;
77
+ return value;
78
+ }
79
+ function hasCliOption(options, key) {
80
+ return Object.prototype.hasOwnProperty.call(options, key);
81
+ }
82
+ function createBuildInlineConfig(options) {
83
+ const build = {};
84
+ if (typeof options.outDir === "string") build.outDir = options.outDir;
85
+ if (hasCliOption(options, "sourcemap")) build.sourcemap = normalizeBuildSourcemap(options.sourcemap);
86
+ if (hasCliOption(options, "minify")) build.minify = normalizeBuildMinify(options.minify);
87
+ if (typeof options.emptyOutDir === "boolean") build.emptyOutDir = options.emptyOutDir;
88
+ return Object.keys(build).length ? { build } : void 0;
89
+ }
90
+ /** 执行已完成参数校验的生产构建,复用注册器持有的原始命令参数。 */
91
+ async function runBuildCommand(cli, root, options) {
92
+ let analyzeHandle;
93
+ let session;
94
+ let ctx;
95
+ let targets;
96
+ let uploadMetadataRollback;
97
+ let buildCompleted = false;
98
+ let buildFailed = false;
99
+ try {
100
+ options = { ...options };
101
+ filterDuplicateOptions(options);
102
+ options.uiHost = parseDashboardUiHost(options.uiHost);
103
+ let uploadOptions = resolveBuildUploadOptions(cli, options);
104
+ setCommandNodeEnv("production");
105
+ const cwd = root ?? process.cwd();
106
+ const configFile = resolveConfigFile(options);
107
+ targets = resolveRuntimeTargets(options);
108
+ if (uploadOptions) validateAutoUploadMetadata(uploadOptions, "upload");
109
+ if (uploadOptions && !getBackendForCapability(targets, "miniprogram", "build")) throw new Error("--upload 仅支持包含小程序目标的构建,不能用于纯 Web 构建。");
110
+ const inlineConfig = createInlineConfig(targets, {
111
+ scope: options.scope,
112
+ inlineConfig: createBuildInlineConfig(options)
113
+ });
114
+ if (uploadOptions) {
115
+ const prepared = await prepareAutoUploadMetadataWithRollback(cwd, uploadOptions, "upload");
116
+ uploadOptions = prepared.options;
117
+ uploadMetadataRollback = prepared.rollback;
118
+ }
119
+ session = new CompilerSession();
120
+ ctx = await session.initialize({
121
+ cwd,
122
+ mode: options.mode ?? "production",
123
+ configFile,
124
+ inlineConfig,
125
+ cliPlatform: targets.rawPlatform,
126
+ projectConfigPath: options.projectConfig,
127
+ emitDefaultAutoImportOutputs: false,
128
+ preloadAppEntry: false
129
+ });
130
+ targets = resolveConfiguredRuntimeTargets(targets, ctx.configService.options?.sourceConfig?.weapp?.platform);
131
+ if (uploadOptions && !getBackendForCapability(targets, "miniprogram", "build")) {
132
+ await uploadMetadataRollback?.();
133
+ uploadMetadataRollback = void 0;
134
+ throw new Error("--upload 仅支持包含小程序目标的构建,不能用于纯 Web 构建。");
135
+ }
136
+ uploadMetadataRollback = void 0;
137
+ for (const backend of targets.select("build")) session.onClose(() => backend.driver.close(ctx));
138
+ const { configService } = ctx;
139
+ const uploadTarget = uploadOptions ? await createUploadTarget(configService, uploadOptions, "upload") : void 0;
140
+ const miniBackend = getBackendForCapability(targets, "miniprogram", "build");
141
+ const webBackend = getBackendForCapability(targets, "web", "build");
142
+ logRuntimeTarget(targets, { resolvedConfigPlatform: configService.platform });
143
+ const enableAnalyze = Boolean(isUiEnabled(options) && miniBackend);
144
+ for (const backend of targets.select("build")) {
145
+ if (backend.descriptor.id === "miniprogram") {
146
+ const miniBuildStartedAt = Date.now();
147
+ const output = await session.run(() => backend.driver.build(ctx, options));
148
+ const miniBuildDurationMs = Date.now() - miniBuildStartedAt;
149
+ logger_default.success(`小程序构建完成,耗时:${colors.green(formatDuration(miniBuildDurationMs))}`);
150
+ if (!Array.isArray(output) && "output" in output) logBuildPackageSizeReport({
151
+ output,
152
+ subPackageMap: ctx.scanService?.subPackageMap,
153
+ warningBytes: configService.weappViteConfig.packageSizeWarningBytes
154
+ });
155
+ if (enableAnalyze) {
156
+ const analyzeStartedAt = Date.now();
157
+ const previousAnalyzeResult = await readLatestAnalyzeHistorySnapshot(configService);
158
+ const artifactSnapshot = createDashboardArtifactSnapshot();
159
+ const analyzeResult = await analyzeSubpackages(ctx, { onArtifact: artifactSnapshot.capture });
160
+ await writeAnalyzeHistorySnapshot(analyzeResult, configService);
161
+ const analyzeDurationMs = Date.now() - analyzeStartedAt;
162
+ analyzeHandle = await startAnalyzeDashboard(analyzeResult, {
163
+ watch: true,
164
+ uiHost: options.uiHost,
165
+ artifacts: artifactSnapshot.files,
166
+ cwd: configService.cwd,
167
+ packageManagerAgent: configService.packageManager.agent,
168
+ pluginRoot: configService.absolutePluginRoot,
169
+ srcRoot: configService.absoluteSrcRoot,
170
+ previousResult: previousAnalyzeResult,
171
+ initialEvents: [{
172
+ kind: "build",
173
+ level: "success",
174
+ title: "mini build completed",
175
+ detail: `生产构建已完成,当前 analyze 结果包含 ${analyzeResult.packages.length} 个包。`,
176
+ durationMs: miniBuildDurationMs,
177
+ tags: ["build", "mini"]
178
+ }, {
179
+ kind: "build",
180
+ level: "success",
181
+ title: "analyze completed",
182
+ detail: `分析已完成,当前包含 ${analyzeResult.packages.length} 个包与 ${analyzeResult.modules.length} 个模块。`,
183
+ durationMs: analyzeDurationMs,
184
+ tags: ["build", "analyze"]
185
+ }]
186
+ }) ?? void 0;
187
+ }
188
+ continue;
189
+ }
190
+ const webConfig = configService.weappWebConfig;
191
+ if (backend.descriptor.id !== "web" || !webConfig?.enabled) continue;
192
+ const webBuildStartedAt = Date.now();
193
+ try {
194
+ await session.run(() => backend.driver.build(ctx, options));
195
+ const webBuildDurationMs = Date.now() - webBuildStartedAt;
196
+ logger_default.success(`Web 构建完成,输出目录:${colors.green(configService.relativeCwd(webConfig.outDir))},耗时:${colors.green(formatDuration(webBuildDurationMs))}`);
197
+ emitDashboardEvents(analyzeHandle, [{
198
+ kind: "build",
199
+ level: "success",
200
+ title: "web build completed",
201
+ detail: `Web 构建已完成,输出目录 ${configService.relativeCwd(webConfig.outDir)}。`,
202
+ durationMs: webBuildDurationMs,
203
+ tags: ["build", "web"]
204
+ }]);
205
+ } catch (error) {
206
+ emitDashboardEvents(analyzeHandle, [{
207
+ kind: "diagnostic",
208
+ level: "error",
209
+ title: "web build failed",
210
+ detail: error instanceof Error ? error.message : String(error),
211
+ durationMs: Date.now() - webBuildStartedAt,
212
+ tags: ["build", "web"]
213
+ }]);
214
+ logger_default.error(error);
215
+ throw error;
216
+ }
217
+ }
218
+ if (uploadTarget && uploadOptions) await executeUploadTarget(uploadTarget, uploadOptions, "upload");
219
+ if (miniBackend) logBuildAppFinish(configService, void 0, { skipWeb: !webBackend });
220
+ if (options.open && getBackendForCapability(targets, "miniprogram", "ide")) {
221
+ emitDashboardEvents(analyzeHandle, [{
222
+ kind: "command",
223
+ level: "info",
224
+ title: "opening ide",
225
+ detail: "构建完成后准备打开 IDE 项目。",
226
+ tags: ["ide", "open"]
227
+ }]);
228
+ const generatedProjectConfig = configService.multiPlatform.projectConfigs !== void 0;
229
+ await openIde(configService.platform, resolveIdeProjectPath(generatedProjectConfig ? configService.outDir : configService.mpDistRoot, generatedProjectConfig), {
230
+ openRecovery: options.openRecovery,
231
+ trustProject: options.trustProject,
232
+ openStrategy: options.ideOpenStrategy
233
+ });
234
+ }
235
+ if (analyzeHandle) await analyzeHandle.waitForExit();
236
+ buildCompleted = true;
237
+ } catch (error) {
238
+ buildFailed = true;
239
+ throw error;
240
+ } finally {
241
+ if (buildFailed) await session?.close().catch((error) => logger_default.error(error));
242
+ else await session?.close();
243
+ if (buildCompleted) scheduleCompletedProductionBuildExit(options, analyzeHandle);
244
+ }
245
+ }
246
+ //#endregion
247
+ export { runBuildCommand };
@@ -0,0 +1 @@
1
+ export { MINI_PROGRAM_PLATFORM_DESCRIPTORS as t } from "@weapp-core/shared";
@@ -0,0 +1,184 @@
1
+ //#region src/dashboard/analyze/comparison.ts
2
+ function createModuleComparisonKey(source, sourceType) {
3
+ const origin = sourceType === "node_modules" || sourceType === "workspace" ? "dependency" : sourceType;
4
+ const queryIndex = source.indexOf("?");
5
+ let canonicalSource = (queryIndex === -1 ? source : source.slice(0, queryIndex)).replaceAll("\\", "/").replace(/^\0/, "");
6
+ if (origin === "dependency") {
7
+ const nodeModulesIndex = canonicalSource.lastIndexOf("/node_modules/");
8
+ if (nodeModulesIndex >= 0) canonicalSource = canonicalSource.slice(nodeModulesIndex + 14);
9
+ else if (canonicalSource.startsWith("node_modules/")) canonicalSource = canonicalSource.slice(13);
10
+ else if (sourceType === "workspace") canonicalSource = (canonicalSource.match(/(?:^|\/)packages-runtime\/(wevu\/.*)$/) ?? canonicalSource.match(/(?:^|\/)(@[^/]+\/[^/]+\/dist\/.*)$/))?.[1] ?? canonicalSource;
11
+ }
12
+ return `${origin}\0${canonicalSource}`;
13
+ }
14
+ function classifyIncrementCategory(source, sourceType) {
15
+ if (source.includes("wevu") || source.includes("@weapp-vite/dashboard")) return "WeVu / runtime";
16
+ if (sourceType === "node_modules" || source.includes("node_modules")) return "第三方依赖";
17
+ if (sourceType === "workspace") return "工作区包";
18
+ if (sourceType === "plugin") return "插件生成";
19
+ if (source.endsWith(".wxss") || source.endsWith(".css") || source.endsWith(".scss")) return "样式资源";
20
+ if (source.endsWith(".wxml") || source.endsWith(".json")) return "页面结构";
21
+ return "业务源码";
22
+ }
23
+ function createChangeAdvice(category, change) {
24
+ if (change === "unmeasured") return "缺少体积测量,不能判断增长或缩小。";
25
+ if (change === "removed" || change === "decreased") return "确认体积减少符合预期,检查受影响页面与依赖边界。";
26
+ if (category === "第三方依赖") return "检查依赖边界或公共入口。";
27
+ if (category === "WeVu / runtime") return "排查组件和 API 引用边界。";
28
+ if (category === "样式资源") return "检查样式复用和生成范围。";
29
+ return change === "added" ? "确认分包归属和懒加载边界。" : "对比新增引用和共享模块。";
30
+ }
31
+ function createSizeMaps(result) {
32
+ const packages = /* @__PURE__ */ new Map();
33
+ const files = /* @__PURE__ */ new Map();
34
+ const moduleIds = /* @__PURE__ */ new Map();
35
+ let totalBytes = 0;
36
+ let unmeasuredFiles = 0;
37
+ for (const pkg of result.packages) {
38
+ let packageBytes = 0;
39
+ let packageUnmeasuredFiles = 0;
40
+ for (const file of pkg.files) {
41
+ const bytes = file.size ?? null;
42
+ if (bytes === null) packageUnmeasuredFiles += 1;
43
+ else packageBytes += bytes;
44
+ const fileKey = `file:${pkg.id}\0${file.file}`;
45
+ files.set(fileKey, {
46
+ key: fileKey,
47
+ label: file.file,
48
+ bytes,
49
+ packageId: pkg.id,
50
+ packageLabel: pkg.label,
51
+ file: file.file,
52
+ category: classifyIncrementCategory(file.source ?? file.file)
53
+ });
54
+ for (const mod of file.modules ?? []) {
55
+ const moduleBytes = mod.bytes ?? mod.originalBytes ?? null;
56
+ const existing = moduleIds.get(mod.id);
57
+ if (existing) {
58
+ existing.bytes = existing.bytes === null || moduleBytes === null ? null : Math.max(existing.bytes, moduleBytes);
59
+ continue;
60
+ }
61
+ const queryIndex = mod.source.indexOf("?");
62
+ moduleIds.set(mod.id, {
63
+ key: `module:${createModuleComparisonKey(mod.source, mod.sourceType)}`,
64
+ label: mod.source,
65
+ bytes: moduleBytes,
66
+ moduleId: mod.id,
67
+ sourceType: mod.sourceType,
68
+ packageId: pkg.id,
69
+ packageLabel: pkg.label,
70
+ file: file.file,
71
+ category: classifyIncrementCategory(queryIndex === -1 ? mod.source : mod.source.slice(0, queryIndex), mod.sourceType)
72
+ });
73
+ }
74
+ }
75
+ totalBytes += packageBytes;
76
+ unmeasuredFiles += packageUnmeasuredFiles;
77
+ const key = `package:${pkg.id}`;
78
+ packages.set(key, {
79
+ key,
80
+ label: pkg.label,
81
+ bytes: packageUnmeasuredFiles > 0 ? null : packageBytes,
82
+ packageId: pkg.id,
83
+ packageLabel: pkg.label
84
+ });
85
+ }
86
+ const modules = /* @__PURE__ */ new Map();
87
+ for (const mod of moduleIds.values()) {
88
+ const existing = modules.get(mod.key);
89
+ if (!existing) modules.set(mod.key, mod);
90
+ else if (existing.bytes === null || mod.bytes === null) existing.bytes = null;
91
+ else if (existing.bytes < mod.bytes) modules.set(mod.key, mod);
92
+ }
93
+ return {
94
+ packages,
95
+ files,
96
+ modules,
97
+ totalBytes: unmeasuredFiles > 0 ? null : totalBytes,
98
+ unmeasuredFiles
99
+ };
100
+ }
101
+ function compareSizeMaps(current, previous) {
102
+ const changes = [];
103
+ const append = (entry, currentBytes, previousBytes, change) => {
104
+ changes.push({
105
+ key: entry.key,
106
+ label: entry.label,
107
+ packageId: entry.packageId,
108
+ packageLabel: entry.packageLabel,
109
+ file: entry.file,
110
+ moduleId: entry.moduleId,
111
+ sourceType: entry.sourceType,
112
+ category: entry.category,
113
+ change,
114
+ currentBytes,
115
+ previousBytes,
116
+ deltaBytes: currentBytes === null || previousBytes === null ? null : currentBytes - previousBytes,
117
+ advice: entry.category ? createChangeAdvice(entry.category, change) : void 0
118
+ });
119
+ };
120
+ for (const [key, entry] of current) {
121
+ const old = previous.get(key);
122
+ if (!old) append(entry, entry.bytes, 0, "added");
123
+ else if (entry.bytes === null || old.bytes === null) append(entry, entry.bytes, old.bytes, "unmeasured");
124
+ else if (entry.bytes !== old.bytes) append(entry, entry.bytes, old.bytes, entry.bytes > old.bytes ? "increased" : "decreased");
125
+ }
126
+ for (const [key, entry] of previous) if (!current.has(key)) append(entry, 0, entry.bytes, "removed");
127
+ return changes.sort((a, b) => (b.deltaBytes ?? -Infinity) - (a.deltaBytes ?? -Infinity) || a.key.localeCompare(b.key));
128
+ }
129
+ /** 比较两个真实快照;模块仅按已记录的 chunk 贡献归并,缺失测量不视为零。 */
130
+ function createAnalyzeComparison(current, previous) {
131
+ const currentMaps = createSizeMaps(current);
132
+ const previousMaps = createSizeMaps(previous);
133
+ return {
134
+ currentBytes: currentMaps.totalBytes,
135
+ previousBytes: previousMaps.totalBytes,
136
+ deltaBytes: currentMaps.totalBytes === null || previousMaps.totalBytes === null ? null : currentMaps.totalBytes - previousMaps.totalBytes,
137
+ currentUnmeasuredFiles: currentMaps.unmeasuredFiles,
138
+ previousUnmeasuredFiles: previousMaps.unmeasuredFiles,
139
+ packages: compareSizeMaps(currentMaps.packages, previousMaps.packages),
140
+ files: compareSizeMaps(currentMaps.files, previousMaps.files),
141
+ modules: compareSizeMaps(currentMaps.modules, previousMaps.modules)
142
+ };
143
+ }
144
+ //#endregion
145
+ //#region src/dashboard/analyze/moduleBytes.ts
146
+ /** 取每个原始模块 ID 的最大已知贡献,缺少产物贡献时使用原始体积。 */
147
+ function createModuleByteMap(result) {
148
+ const bytes = /* @__PURE__ */ new Map();
149
+ for (const pkg of result.packages) for (const file of pkg.files) for (const mod of file.modules ?? []) bytes.set(mod.id, Math.max(bytes.get(mod.id) ?? 0, mod.bytes ?? mod.originalBytes ?? 0));
150
+ return bytes;
151
+ }
152
+ //#endregion
153
+ //#region src/dashboard/analyze/duplicates.ts
154
+ function createDuplicateAdvice(sourceType, hasIndependentPackage, estimatedSavingBytes) {
155
+ if (hasIndependentPackage) return estimatedSavingBytes > 0 ? "含独立分包,先确认隔离要求,再评估是否抽公共入口。" : "含独立分包,重复可能来自隔离边界。";
156
+ if (sourceType === "node_modules") return "依赖被多个包带入,检查引用边界或考虑主包公共入口。";
157
+ if (sourceType === "src" || sourceType === "workspace") return "共享源码跨包重复,优先抽公共模块或调整分包归属。";
158
+ if (sourceType === "plugin") return "插件生成内容跨包重复,检查插件产物输出策略。";
159
+ return "检查该模块是否需要在多个包内重复存在。";
160
+ }
161
+ /** 按原始模块 ID 统计跨包重复,节省量是估算值,不代表可安全移除的字节。 */
162
+ function createDuplicateModuleInsights(result) {
163
+ const moduleBytes = createModuleByteMap(result);
164
+ const packageTypes = new Map(result.packages.map((pkg) => [pkg.id, pkg.type]));
165
+ return result.modules.filter((module) => module.packages.length > 1).map((module) => {
166
+ const bytes = moduleBytes.get(module.id) ?? 0;
167
+ const packages = module.packages.map((pkg) => pkg.packageId);
168
+ const estimatedSavingBytes = bytes * (packages.length - 1);
169
+ const hasIndependentPackage = packages.some((id) => packageTypes.get(id) === "independent");
170
+ return {
171
+ id: module.id,
172
+ source: module.source,
173
+ sourceType: module.sourceType,
174
+ packageCount: packages.length,
175
+ bytes,
176
+ estimatedSavingBytes,
177
+ packages,
178
+ hasIndependentPackage,
179
+ advice: createDuplicateAdvice(module.sourceType, hasIndependentPackage, estimatedSavingBytes)
180
+ };
181
+ }).sort((a, b) => b.estimatedSavingBytes - a.estimatedSavingBytes || b.packageCount - a.packageCount || b.bytes - a.bytes || a.source.localeCompare(b.source) || a.id.localeCompare(b.id));
182
+ }
183
+ //#endregion
184
+ export { createModuleByteMap as n, createAnalyzeComparison as r, createDuplicateModuleInsights as t };
@@ -0,0 +1,106 @@
1
+ import { createRequire } from "node:module";
2
+ import process from "node:process";
3
+ import path from "pathe";
4
+ import fs from "node:fs";
5
+ import { Buffer } from "node:buffer";
6
+ //#region src/dashboard/assets.ts
7
+ const ANALYZE_DASHBOARD_PACKAGE_NAME = "@weapp-vite/dashboard";
8
+ const require = createRequire(import.meta.url);
9
+ function parseDashboardManifest(source) {
10
+ const parsed = JSON.parse(source);
11
+ const metadata = parsed && typeof parsed === "object" && "weappViteDashboard" in parsed ? parsed.weappViteDashboard : void 0;
12
+ if (!metadata || typeof metadata !== "object") return;
13
+ return { weappViteDashboard: {
14
+ devConfigFile: "devConfigFile" in metadata && typeof metadata.devConfigFile === "string" ? metadata.devConfigFile : void 0,
15
+ devRoot: "devRoot" in metadata && typeof metadata.devRoot === "string" ? metadata.devRoot : void 0,
16
+ distDir: "distDir" in metadata && typeof metadata.distDir === "string" ? metadata.distDir : void 0
17
+ } };
18
+ }
19
+ function resolveDashboardPackage(cwd) {
20
+ const resolvePaths = cwd && cwd !== process.cwd() ? [cwd, process.cwd()] : cwd ? [cwd] : void 0;
21
+ try {
22
+ const packageJsonPath = require.resolve(`${ANALYZE_DASHBOARD_PACKAGE_NAME}/package.json`, { paths: resolvePaths });
23
+ let manifest;
24
+ try {
25
+ manifest = parseDashboardManifest(fs.readFileSync(packageJsonPath, "utf8"));
26
+ } catch {
27
+ manifest = void 0;
28
+ }
29
+ return {
30
+ root: path.dirname(packageJsonPath),
31
+ manifest,
32
+ packageJsonPath
33
+ };
34
+ } catch {
35
+ return;
36
+ }
37
+ }
38
+ function resolveDashboardDistRoot(packageRoot, manifest) {
39
+ const root = path.resolve(packageRoot, manifest?.weappViteDashboard?.distDir ?? "dist");
40
+ return fs.existsSync(path.join(root, "index.html")) ? { root } : void 0;
41
+ }
42
+ function resolveDashboardDevRoot(packageRoot, manifest) {
43
+ const devRoot = manifest?.weappViteDashboard?.devRoot;
44
+ const devConfigFile = manifest?.weappViteDashboard?.devConfigFile;
45
+ if (!devRoot || !devConfigFile) return;
46
+ const root = path.resolve(packageRoot, devRoot);
47
+ const configFile = path.resolve(root, devConfigFile);
48
+ return fs.existsSync(root) && fs.existsSync(configFile) ? {
49
+ root,
50
+ configFile
51
+ } : void 0;
52
+ }
53
+ /** 同一次解析绑定 Dashboard 资源目录及其传输依赖的安装所有者。 */
54
+ function resolveDashboardInstallation(options) {
55
+ const resolved = resolveDashboardPackage(options.cwd);
56
+ if (!resolved) return;
57
+ const assets = options.watch ? resolveDashboardDevRoot(resolved.root, resolved.manifest) ?? resolveDashboardDistRoot(resolved.root, resolved.manifest) : resolveDashboardDistRoot(resolved.root, resolved.manifest) ?? resolveDashboardDevRoot(resolved.root, resolved.manifest);
58
+ return assets ? {
59
+ ...assets,
60
+ packageJsonPath: resolved.packageJsonPath
61
+ } : void 0;
62
+ }
63
+ /** 定位可选仪表盘包的原生构建 SPA;未安装或尚未构建时返回 undefined。 */
64
+ function resolveDashboardClientAssets(cwd) {
65
+ const resolved = resolveDashboardPackage(cwd);
66
+ return resolved ? resolveDashboardDistRoot(resolved.root, resolved.manifest)?.root : void 0;
67
+ }
68
+ //#endregion
69
+ //#region src/dashboard/artifacts.ts
70
+ const MAX_DASHBOARD_FILE_CONTENT_BYTES = 2097152;
71
+ /** 保留同一次分析的产物内容,不读取或改写开发构建目录。 */
72
+ function createDashboardArtifactSnapshot() {
73
+ const files = /* @__PURE__ */ new Map();
74
+ let retainedBytes = 0;
75
+ return {
76
+ files,
77
+ capture(fileName, source) {
78
+ const key = fileName.replaceAll("\\", "/");
79
+ const previous = files.get(key);
80
+ if (previous?.content !== void 0) retainedBytes -= previous.size;
81
+ const size = typeof source === "string" ? Buffer.byteLength(source, "utf8") : source.byteLength;
82
+ if (size > 2097152) {
83
+ files.set(key, {
84
+ size,
85
+ error: `文件超过 ${MAX_DASHBOARD_FILE_CONTENT_BYTES} 字节,已拒绝读取。`
86
+ });
87
+ return;
88
+ }
89
+ if (retainedBytes + size > 33554432) {
90
+ files.set(key, {
91
+ size,
92
+ error: "分析产物内容超过快照容量上限,已拒绝读取。"
93
+ });
94
+ return;
95
+ }
96
+ const content = typeof source === "string" ? source : Buffer.from(source.buffer, source.byteOffset, source.byteLength).toString("utf8");
97
+ files.set(key, {
98
+ content,
99
+ size
100
+ });
101
+ retainedBytes += size;
102
+ }
103
+ };
104
+ }
105
+ //#endregion
106
+ export { resolveDashboardInstallation as a, resolveDashboardClientAssets as i, createDashboardArtifactSnapshot as n, ANALYZE_DASHBOARD_PACKAGE_NAME as r, MAX_DASHBOARD_FILE_CONTENT_BYTES as t };