weapp-vite 6.11.8 → 6.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auto-routes.mjs +5 -2
- package/dist/cli.mjs +334 -124
- package/dist/{config-DHz3M7If.d.mts → config-Av2eTTDE.d.mts} +1 -0
- package/dist/config.d.mts +1 -1
- package/dist/{createContext-DZgOqIMU.mjs → createContext-Cy_160Dm.mjs} +3282 -2026
- package/dist/{file-rRQhPOL8.mjs → file-DKg072cZ.mjs} +15 -8
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +1 -1
- package/dist/json.d.mts +1 -1
- package/dist/mcp.d.mts +1 -1
- package/dist/types.d.mts +1 -1
- package/package.json +6 -6
package/dist/auto-routes.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as getCompilerContext } from "./createContext-
|
|
1
|
+
import { i as getCompilerContext, l as getRouteRuntimeGlobalKeys } from "./createContext-Cy_160Dm.mjs";
|
|
2
2
|
//#region src/auto-routes.ts
|
|
3
3
|
const ROUTE_RUNTIME_OVERRIDE_KEY = Symbol.for("weapp-vite.route-runtime");
|
|
4
4
|
function createGetter(resolver) {
|
|
@@ -28,7 +28,10 @@ function resolveMiniProgramGlobal() {
|
|
|
28
28
|
const runtime = globalThis;
|
|
29
29
|
const overrideRuntime = runtime[ROUTE_RUNTIME_OVERRIDE_KEY];
|
|
30
30
|
if (overrideRuntime) return overrideRuntime;
|
|
31
|
-
|
|
31
|
+
for (const key of getRouteRuntimeGlobalKeys()) {
|
|
32
|
+
const candidate = runtime[key];
|
|
33
|
+
if (candidate) return candidate;
|
|
34
|
+
}
|
|
32
35
|
}
|
|
33
36
|
function callRouteMethod(methodName, option) {
|
|
34
37
|
const miniProgramGlobal = resolveMiniProgramGlobal();
|
package/dist/cli.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { _ as isPathInside, c as
|
|
1
|
+
import { _ as normalizeMiniPlatform, b as isPathInside, c as SHARED_CHUNK_VIRTUAL_PREFIX, d as checkRuntime, f as getProjectConfigFileName, g as getDefaultIdeProjectRoot, h as DEFAULT_MP_PLATFORM, m as createCjsConfigLoadError, n as syncProjectSupportFiles, o as formatBytes, p as parseCommentJson, r as syncManagedTsconfigBootstrapFiles, s as createSharedBuildConfig, t as createCompilerContext, u as resolveWeappConfigFile, v as resolveMiniPlatform, y as shouldPassPlatformArgToIdeOpen } from "./createContext-Cy_160Dm.mjs";
|
|
2
2
|
import { r as logger_default, t as colors } from "./logger-gutcwWKE.mjs";
|
|
3
|
-
import {
|
|
3
|
+
import { p as VERSION } from "./file-DKg072cZ.mjs";
|
|
4
4
|
import { resolveWeappMcpConfig, startWeappViteMcpServer } from "./mcp.mjs";
|
|
5
5
|
import { createRequire } from "node:module";
|
|
6
6
|
import { defu } from "@weapp-core/shared";
|
|
@@ -22,6 +22,20 @@ import { initConfig } from "@weapp-core/init";
|
|
|
22
22
|
//#region src/analyze/subpackages/classifier.ts
|
|
23
23
|
const VIRTUAL_MODULE_INDICATOR = "\0";
|
|
24
24
|
const VIRTUAL_PREFIX = `${SHARED_CHUNK_VIRTUAL_PREFIX}/`;
|
|
25
|
+
function classifyModuleSourceKind(options) {
|
|
26
|
+
if (options.isNodeModule) return "node_modules";
|
|
27
|
+
if (options.inSrc) return "src";
|
|
28
|
+
if (options.inPlugin) return "plugin";
|
|
29
|
+
return "workspace";
|
|
30
|
+
}
|
|
31
|
+
function resolvePluginAssetAbsolute(normalizedFileName, pluginRoot) {
|
|
32
|
+
if (!pluginRoot) return;
|
|
33
|
+
const pluginBase = posix.basename(pluginRoot);
|
|
34
|
+
if (normalizedFileName !== pluginBase && !normalizedFileName.startsWith(`${pluginBase}/`)) return;
|
|
35
|
+
const relative = normalizedFileName === pluginBase ? "" : normalizedFileName.slice(pluginBase.length + 1);
|
|
36
|
+
const absolute = posix.resolve(pluginRoot, relative);
|
|
37
|
+
return isPathInside(pluginRoot, absolute) ? absolute : void 0;
|
|
38
|
+
}
|
|
25
39
|
function classifyPackage(fileName, origin, context) {
|
|
26
40
|
if (fileName.startsWith(VIRTUAL_PREFIX)) {
|
|
27
41
|
const combination = fileName.slice(VIRTUAL_PREFIX.length).split("/")[0] || "shared";
|
|
@@ -56,13 +70,11 @@ function resolveModuleSourceType(absoluteId, ctx) {
|
|
|
56
70
|
const isNodeModule = absoluteId.includes("/node_modules/") || absoluteId.includes("\\node_modules\\");
|
|
57
71
|
const pluginRoot = configService.absolutePluginRoot;
|
|
58
72
|
const srcRoot = configService.absoluteSrcRoot;
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
else if (inPlugin) sourceType = "plugin";
|
|
65
|
-
else sourceType = "workspace";
|
|
73
|
+
const sourceType = classifyModuleSourceKind({
|
|
74
|
+
isNodeModule,
|
|
75
|
+
inSrc: isPathInside(srcRoot, absoluteId),
|
|
76
|
+
inPlugin: pluginRoot ? isPathInside(pluginRoot, absoluteId) : false
|
|
77
|
+
});
|
|
66
78
|
return {
|
|
67
79
|
source: configService.relativeAbsoluteSrcRoot(absoluteId),
|
|
68
80
|
sourceType
|
|
@@ -77,19 +89,12 @@ function resolveAssetSource(fileName, ctx) {
|
|
|
77
89
|
source: configService.relativeAbsoluteSrcRoot(srcCandidate),
|
|
78
90
|
sourceType: "src"
|
|
79
91
|
};
|
|
80
|
-
const
|
|
81
|
-
if (
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
if (isPathInside(pluginRoot, absolute)) return {
|
|
87
|
-
absolute,
|
|
88
|
-
source: configService.relativeAbsoluteSrcRoot(absolute),
|
|
89
|
-
sourceType: "plugin"
|
|
90
|
-
};
|
|
91
|
-
}
|
|
92
|
-
}
|
|
92
|
+
const pluginAbsolute = resolvePluginAssetAbsolute(normalized, configService.absolutePluginRoot);
|
|
93
|
+
if (pluginAbsolute) return {
|
|
94
|
+
absolute: pluginAbsolute,
|
|
95
|
+
source: configService.relativeAbsoluteSrcRoot(pluginAbsolute),
|
|
96
|
+
sourceType: "plugin"
|
|
97
|
+
};
|
|
93
98
|
}
|
|
94
99
|
//#endregion
|
|
95
100
|
//#region src/analyze/subpackages/registry.ts
|
|
@@ -315,14 +320,32 @@ async function analyzeSubpackages(ctx) {
|
|
|
315
320
|
//#endregion
|
|
316
321
|
//#region src/cli/analyze/dashboard.ts
|
|
317
322
|
const ANALYZE_GLOBAL_KEY = "__WEAPP_VITE_ANALYZE_RESULT__";
|
|
323
|
+
const DASHBOARD_EVENTS_GLOBAL_KEY = "__WEAPP_VITE_DASHBOARD_EVENTS__";
|
|
318
324
|
const ANALYZE_DASHBOARD_PACKAGE_NAME = "@weapp-vite/dashboard";
|
|
319
325
|
const ANALYZE_SSE_PATH = "/__weapp_vite_analyze";
|
|
326
|
+
const DASHBOARD_EVENT_NAME = "weapp-dashboard:event";
|
|
320
327
|
const require = createRequire(import.meta.url);
|
|
321
328
|
function createInstallCommand(agent) {
|
|
322
329
|
const resolved = resolveCommand(agent ?? "npm", "install", [ANALYZE_DASHBOARD_PACKAGE_NAME]);
|
|
323
330
|
if (!resolved) return `npm install ${ANALYZE_DASHBOARD_PACKAGE_NAME}`;
|
|
324
331
|
return `${resolved.command} ${resolved.args.join(" ")}`;
|
|
325
332
|
}
|
|
333
|
+
function formatEventTimestamp(date = /* @__PURE__ */ new Date()) {
|
|
334
|
+
return date.toLocaleTimeString("zh-CN", { hour12: false });
|
|
335
|
+
}
|
|
336
|
+
function createDashboardRuntimeEvent(input) {
|
|
337
|
+
return {
|
|
338
|
+
id: `dashboard:${Date.now()}:${Math.random().toString(36).slice(2, 8)}`,
|
|
339
|
+
kind: input.kind,
|
|
340
|
+
level: input.level,
|
|
341
|
+
title: input.title,
|
|
342
|
+
detail: input.detail,
|
|
343
|
+
timestamp: formatEventTimestamp(),
|
|
344
|
+
source: input.source ?? "weapp-vite",
|
|
345
|
+
durationMs: input.durationMs,
|
|
346
|
+
tags: input.tags
|
|
347
|
+
};
|
|
348
|
+
}
|
|
326
349
|
function readDashboardManifest(packageJsonPath) {
|
|
327
350
|
try {
|
|
328
351
|
return parseCommentJson(fs$2.readFileSync(packageJsonPath, "utf8"));
|
|
@@ -371,13 +394,25 @@ function resolveDashboardRoot(options) {
|
|
|
371
394
|
logger_default.warn(`[weapp-vite ui] 未安装可选仪表盘包 ${colors.bold(colors.green(ANALYZE_DASHBOARD_PACKAGE_NAME))},已自动降级关闭 dashboard 能力。`);
|
|
372
395
|
logger_default.info(`如需启用,请执行 ${colors.bold(colors.green(createInstallCommand(options?.packageManagerAgent)))}`);
|
|
373
396
|
}
|
|
374
|
-
function createAnalyzeHtmlPlugin(state, onServerInstance, onBroadcastReady) {
|
|
397
|
+
function createAnalyzeHtmlPlugin(state, runtimeEvents, onServerInstance, onBroadcastReady) {
|
|
375
398
|
const sseClients = /* @__PURE__ */ new Set();
|
|
376
399
|
const hotBridgeScript = `
|
|
377
400
|
const applyAnalyzePayload = (payload) => {
|
|
378
401
|
window.${ANALYZE_GLOBAL_KEY} = payload
|
|
379
402
|
window.dispatchEvent(new CustomEvent('weapp-analyze:update', { detail: payload }))
|
|
380
403
|
}
|
|
404
|
+
const applyDashboardEvents = (payload) => {
|
|
405
|
+
const events = Array.isArray(payload) ? payload : [payload]
|
|
406
|
+
const nextEvents = events.filter(Boolean)
|
|
407
|
+
if (nextEvents.length === 0) {
|
|
408
|
+
return
|
|
409
|
+
}
|
|
410
|
+
window.${DASHBOARD_EVENTS_GLOBAL_KEY} = [
|
|
411
|
+
...(window.${DASHBOARD_EVENTS_GLOBAL_KEY} ?? []),
|
|
412
|
+
...nextEvents,
|
|
413
|
+
]
|
|
414
|
+
window.dispatchEvent(new CustomEvent('${DASHBOARD_EVENT_NAME}', { detail: nextEvents }))
|
|
415
|
+
}
|
|
381
416
|
const source = new EventSource('${ANALYZE_SSE_PATH}')
|
|
382
417
|
source.onmessage = (event) => {
|
|
383
418
|
try {
|
|
@@ -389,6 +424,9 @@ function createAnalyzeHtmlPlugin(state, onServerInstance, onBroadcastReady) {
|
|
|
389
424
|
import.meta.hot.on('weapp-analyze:update', (payload) => {
|
|
390
425
|
applyAnalyzePayload(payload)
|
|
391
426
|
})
|
|
427
|
+
import.meta.hot.on('${DASHBOARD_EVENT_NAME}', (payload) => {
|
|
428
|
+
applyDashboardEvents(payload)
|
|
429
|
+
})
|
|
392
430
|
}
|
|
393
431
|
`.trim();
|
|
394
432
|
const broadcast = (payload) => {
|
|
@@ -407,6 +445,11 @@ function createAnalyzeHtmlPlugin(state, onServerInstance, onBroadcastReady) {
|
|
|
407
445
|
children: `window.${ANALYZE_GLOBAL_KEY} = ${JSON.stringify(state.current)}`,
|
|
408
446
|
injectTo: "head-prepend"
|
|
409
447
|
},
|
|
448
|
+
{
|
|
449
|
+
tag: "script",
|
|
450
|
+
children: `window.${DASHBOARD_EVENTS_GLOBAL_KEY} = ${JSON.stringify(runtimeEvents.current)}`,
|
|
451
|
+
injectTo: "head-prepend"
|
|
452
|
+
},
|
|
410
453
|
{
|
|
411
454
|
tag: "script",
|
|
412
455
|
attrs: {
|
|
@@ -475,9 +518,16 @@ async function startAnalyzeDashboard(result, options) {
|
|
|
475
518
|
if (!resolved) return;
|
|
476
519
|
const { root, configFile } = resolved;
|
|
477
520
|
const state = { current: result };
|
|
521
|
+
const runtimeEvents = { current: [createDashboardRuntimeEvent({
|
|
522
|
+
kind: "command",
|
|
523
|
+
level: "success",
|
|
524
|
+
title: options?.watch ? "dashboard watch session started" : "dashboard static session started",
|
|
525
|
+
detail: options?.watch ? "weapp-vite UI 已进入实时分析模式,后续 analyze 结果会继续推送到 dashboard。" : "weapp-vite UI 已进入静态分析模式,当前页面展示的是一次性分析结果。",
|
|
526
|
+
tags: options?.watch ? ["watch", "analyze"] : ["static", "analyze"]
|
|
527
|
+
})] };
|
|
478
528
|
let serverRef;
|
|
479
529
|
let broadcastAnalyzeResult;
|
|
480
|
-
const plugins = [createAnalyzeHtmlPlugin(state, (server) => {
|
|
530
|
+
const plugins = [createAnalyzeHtmlPlugin(state, runtimeEvents, (server) => {
|
|
481
531
|
serverRef = server;
|
|
482
532
|
}, (broadcast) => {
|
|
483
533
|
broadcastAnalyzeResult = broadcast;
|
|
@@ -507,15 +557,39 @@ async function startAnalyzeDashboard(result, options) {
|
|
|
507
557
|
return [...resolved.local ?? [], ...resolved.network ?? []];
|
|
508
558
|
})();
|
|
509
559
|
const waitPromise = waitForServerExit(server);
|
|
510
|
-
if (serverRef?.ws)
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
560
|
+
if (serverRef?.ws) {
|
|
561
|
+
serverRef.ws.send({
|
|
562
|
+
type: "custom",
|
|
563
|
+
event: "weapp-analyze:update",
|
|
564
|
+
data: state.current
|
|
565
|
+
});
|
|
566
|
+
serverRef.ws.send({
|
|
567
|
+
type: "custom",
|
|
568
|
+
event: DASHBOARD_EVENT_NAME,
|
|
569
|
+
data: runtimeEvents.current
|
|
570
|
+
});
|
|
571
|
+
}
|
|
515
572
|
broadcastAnalyzeResult?.(state.current);
|
|
573
|
+
const emitRuntimeEvents = (events) => {
|
|
574
|
+
if (events.length === 0) return;
|
|
575
|
+
const nextEvents = events.map((event) => createDashboardRuntimeEvent(event));
|
|
576
|
+
runtimeEvents.current = [...nextEvents, ...runtimeEvents.current].slice(0, 24);
|
|
577
|
+
if (serverRef) serverRef.ws.send({
|
|
578
|
+
type: "custom",
|
|
579
|
+
event: DASHBOARD_EVENT_NAME,
|
|
580
|
+
data: nextEvents
|
|
581
|
+
});
|
|
582
|
+
};
|
|
516
583
|
const handle = {
|
|
517
584
|
async update(nextResult) {
|
|
518
585
|
state.current = nextResult;
|
|
586
|
+
emitRuntimeEvents([{
|
|
587
|
+
kind: "build",
|
|
588
|
+
level: "info",
|
|
589
|
+
title: "analyze payload refreshed",
|
|
590
|
+
detail: `已推送新的 analyze 结果,当前包含 ${nextResult.packages.length} 个包与 ${nextResult.modules.length} 个模块。`,
|
|
591
|
+
tags: ["analyze", "refresh"]
|
|
592
|
+
}]);
|
|
519
593
|
if (serverRef) serverRef.ws.send({
|
|
520
594
|
type: "custom",
|
|
521
595
|
event: "weapp-analyze:update",
|
|
@@ -523,6 +597,7 @@ async function startAnalyzeDashboard(result, options) {
|
|
|
523
597
|
});
|
|
524
598
|
broadcastAnalyzeResult?.(nextResult);
|
|
525
599
|
},
|
|
600
|
+
emitRuntimeEvents,
|
|
526
601
|
waitForExit: () => waitPromise,
|
|
527
602
|
close: async () => {
|
|
528
603
|
await server.close();
|
|
@@ -883,10 +958,69 @@ function logBuildPackageSizeReport(options) {
|
|
|
883
958
|
//#endregion
|
|
884
959
|
//#region src/cli/openIde.ts
|
|
885
960
|
const execFileAsync = promisify(execFile);
|
|
961
|
+
/**
|
|
962
|
+
* @description 执行 IDE 打开流程,并在登录失效时允许按键重试。
|
|
963
|
+
*/
|
|
964
|
+
async function runWechatIdeOpenWithRetry(argv) {
|
|
965
|
+
let retrying = true;
|
|
966
|
+
while (retrying) try {
|
|
967
|
+
await parse(argv);
|
|
968
|
+
return;
|
|
969
|
+
} catch (error) {
|
|
970
|
+
if (!isWechatIdeLoginRequiredError(error)) {
|
|
971
|
+
logger_default.error(error);
|
|
972
|
+
return;
|
|
973
|
+
}
|
|
974
|
+
logger_default.error("检测到微信开发者工具登录状态失效,请先登录后重试。");
|
|
975
|
+
logger_default.warn(formatWechatIdeLoginRequiredError(error));
|
|
976
|
+
logger_default.info(formatRetryHotkeyPrompt());
|
|
977
|
+
if (!await waitForRetryKeypress()) {
|
|
978
|
+
logger_default.warn("已取消重试。完成登录后请重新执行当前命令。");
|
|
979
|
+
retrying = false;
|
|
980
|
+
continue;
|
|
981
|
+
}
|
|
982
|
+
logger_default.info(colors.bold(colors.green("正在重试连接微信开发者工具...")));
|
|
983
|
+
}
|
|
984
|
+
}
|
|
985
|
+
async function closeIdeByAppleScript() {
|
|
986
|
+
if (process.platform !== "darwin") return false;
|
|
987
|
+
const appName = process.env.WEAPP_DEVTOOLS_APP_NAME || "wechatwebdevtools";
|
|
988
|
+
try {
|
|
989
|
+
await execFileAsync("osascript", ["-e", `tell application "${appName}" to quit`]);
|
|
990
|
+
return true;
|
|
991
|
+
} catch {
|
|
992
|
+
return false;
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
async function closeIdeByProcessKill(cliPath) {
|
|
996
|
+
if (!cliPath) return false;
|
|
997
|
+
const appContentsRoot = cliPath.includes(".app/") ? cliPath.slice(0, cliPath.indexOf(".app/") + 4) : path.dirname(path.dirname(cliPath));
|
|
998
|
+
try {
|
|
999
|
+
await execFileAsync("pkill", ["-f", appContentsRoot]);
|
|
1000
|
+
return true;
|
|
1001
|
+
} catch {
|
|
1002
|
+
return false;
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1005
|
+
/**
|
|
1006
|
+
* @description 根据 mpDistRoot 推导 IDE 项目目录(目录内应包含 project/mini 配置)
|
|
1007
|
+
*/
|
|
1008
|
+
function resolveIdeProjectPath(mpDistRoot) {
|
|
1009
|
+
if (!mpDistRoot || !mpDistRoot.trim()) return;
|
|
1010
|
+
const parent = path.dirname(mpDistRoot);
|
|
1011
|
+
if (!parent || parent === "." || parent === "/") return;
|
|
1012
|
+
return parent;
|
|
1013
|
+
}
|
|
1014
|
+
/**
|
|
1015
|
+
* @description 结合 mpDistRoot 与配置根目录解析最终 IDE 项目目录。
|
|
1016
|
+
*/
|
|
1017
|
+
function resolveIdeProjectRoot(mpDistRoot, cwd) {
|
|
1018
|
+
return resolveIdeProjectPath(mpDistRoot) ?? cwd;
|
|
1019
|
+
}
|
|
886
1020
|
async function openIde(platform, projectPath) {
|
|
887
1021
|
const argv = ["open", "-p"];
|
|
888
1022
|
if (projectPath) argv.push(projectPath);
|
|
889
|
-
if (platform
|
|
1023
|
+
if (shouldPassPlatformArgToIdeOpen(platform)) argv.push("--platform", platform);
|
|
890
1024
|
await runWechatIdeOpenWithRetry(argv);
|
|
891
1025
|
}
|
|
892
1026
|
async function closeIde() {
|
|
@@ -941,73 +1075,31 @@ async function resolveIdeCommandContext(options) {
|
|
|
941
1075
|
mpDistRoot: ctx.configService.mpDistRoot
|
|
942
1076
|
};
|
|
943
1077
|
} catch {}
|
|
944
|
-
if (!projectPath
|
|
1078
|
+
if (!projectPath) {
|
|
1079
|
+
const defaultProjectRoot = getDefaultIdeProjectRoot(platform);
|
|
1080
|
+
if (defaultProjectRoot) projectPath = resolveIdeProjectRoot(defaultProjectRoot, cwd);
|
|
1081
|
+
}
|
|
945
1082
|
return {
|
|
946
1083
|
platform,
|
|
947
1084
|
projectPath
|
|
948
1085
|
};
|
|
949
1086
|
}
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
let retrying = true;
|
|
955
|
-
while (retrying) try {
|
|
956
|
-
await parse(argv);
|
|
957
|
-
return;
|
|
958
|
-
} catch (error) {
|
|
959
|
-
if (!isWechatIdeLoginRequiredError(error)) {
|
|
960
|
-
logger_default.error(error);
|
|
961
|
-
return;
|
|
962
|
-
}
|
|
963
|
-
logger_default.error("检测到微信开发者工具登录状态失效,请先登录后重试。");
|
|
964
|
-
logger_default.warn(formatWechatIdeLoginRequiredError(error));
|
|
965
|
-
logger_default.info(formatRetryHotkeyPrompt());
|
|
966
|
-
if (!await waitForRetryKeypress()) {
|
|
967
|
-
logger_default.warn("已取消重试。完成登录后请重新执行当前命令。");
|
|
968
|
-
retrying = false;
|
|
969
|
-
continue;
|
|
970
|
-
}
|
|
971
|
-
logger_default.info(colors.bold(colors.green("正在重试连接微信开发者工具...")));
|
|
972
|
-
}
|
|
973
|
-
}
|
|
974
|
-
async function closeIdeByAppleScript() {
|
|
975
|
-
if (process.platform !== "darwin") return false;
|
|
976
|
-
const appName = process.env.WEAPP_DEVTOOLS_APP_NAME || "wechatwebdevtools";
|
|
977
|
-
try {
|
|
978
|
-
await execFileAsync("osascript", ["-e", `tell application "${appName}" to quit`]);
|
|
979
|
-
return true;
|
|
980
|
-
} catch {
|
|
981
|
-
return false;
|
|
982
|
-
}
|
|
983
|
-
}
|
|
984
|
-
async function closeIdeByProcessKill(cliPath) {
|
|
985
|
-
if (!cliPath) return false;
|
|
986
|
-
const appContentsRoot = cliPath.includes(".app/") ? cliPath.slice(0, cliPath.indexOf(".app/") + 4) : path.dirname(path.dirname(cliPath));
|
|
987
|
-
try {
|
|
988
|
-
await execFileAsync("pkill", ["-f", appContentsRoot]);
|
|
989
|
-
return true;
|
|
990
|
-
} catch {
|
|
991
|
-
return false;
|
|
992
|
-
}
|
|
1087
|
+
//#endregion
|
|
1088
|
+
//#region src/cli/commands/build.ts
|
|
1089
|
+
function isSassEmbeddedChild(handle) {
|
|
1090
|
+
return Boolean(handle && typeof handle === "object" && "kill" in handle && "spawnfile" in handle && typeof handle.spawnfile === "string" && handle.spawnfile?.includes("sass-embedded"));
|
|
993
1091
|
}
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
return parent;
|
|
1092
|
+
function terminateStaleSassEmbeddedProcess() {
|
|
1093
|
+
const getHandles = process._getActiveHandles;
|
|
1094
|
+
const handles = typeof getHandles === "function" ? getHandles() : void 0;
|
|
1095
|
+
if (!Array.isArray(handles)) return;
|
|
1096
|
+
for (const handle of handles) if (isSassEmbeddedChild(handle)) try {
|
|
1097
|
+
handle.kill();
|
|
1098
|
+
} catch {}
|
|
1002
1099
|
}
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
*/
|
|
1006
|
-
function resolveIdeProjectRoot(mpDistRoot, cwd) {
|
|
1007
|
-
return resolveIdeProjectPath(mpDistRoot) ?? cwd;
|
|
1100
|
+
function emitDashboardEvents$1(handle, events) {
|
|
1101
|
+
handle?.emitRuntimeEvents(events);
|
|
1008
1102
|
}
|
|
1009
|
-
//#endregion
|
|
1010
|
-
//#region src/cli/commands/build.ts
|
|
1011
1103
|
function registerBuildCommand(cli) {
|
|
1012
1104
|
cli.command("build [root]", "build for production").option("--target <target>", `[string] transpile target (default: 'modules')`).option("--outDir <dir>", `[string] output directory (default: dist)`).option("-p, --platform <platform>", `[string] target platform (weapp | h5 | all)`).option("--project-config <path>", `[string] project config path (miniprogram only)`).option("--sourcemap [output]", `[boolean | "inline" | "hidden"] output source maps for build (default: false)`).option("--minify [minifier]", "[boolean | \"terser\" | \"esbuild\"] enable/disable minification, or specify minifier to use (default: esbuild)").option("--emptyOutDir", `[boolean] force empty outDir when it's outside of root`).option("-w, --watch", `[boolean] rebuilds when modules have changed on disk`).option("--skipNpm", `[boolean] if skip npm build`).option("-o, --open", `[boolean] open ide`).option("--ui", `[boolean] 启动调试 UI(当前提供分析视图)`, { default: false }).option("--analyze", `[boolean] 输出分包分析仪表盘`, { default: false }).action(async (root, options) => {
|
|
1013
1105
|
filterDuplicateOptions(options);
|
|
@@ -1027,44 +1119,73 @@ function registerBuildCommand(cli) {
|
|
|
1027
1119
|
const enableAnalyze = Boolean(isUiEnabled(options) && targets.runMini);
|
|
1028
1120
|
let analyzeHandle;
|
|
1029
1121
|
if (targets.runMini) {
|
|
1122
|
+
const miniBuildStartedAt = Date.now();
|
|
1030
1123
|
const output = await buildService.build(options);
|
|
1031
1124
|
if (!Array.isArray(output) && "output" in output) logBuildPackageSizeReport({
|
|
1032
1125
|
output,
|
|
1033
1126
|
subPackageMap: ctx.scanService?.subPackageMap,
|
|
1034
1127
|
warningBytes: configService.weappViteConfig.packageSizeWarningBytes
|
|
1035
1128
|
});
|
|
1036
|
-
if (enableAnalyze)
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1129
|
+
if (enableAnalyze) {
|
|
1130
|
+
const analyzeResult = await analyzeSubpackages(ctx);
|
|
1131
|
+
analyzeHandle = await startAnalyzeDashboard(analyzeResult, {
|
|
1132
|
+
watch: true,
|
|
1133
|
+
cwd: configService.cwd,
|
|
1134
|
+
packageManagerAgent: configService.packageManager.agent
|
|
1135
|
+
}) ?? void 0;
|
|
1136
|
+
emitDashboardEvents$1(analyzeHandle, [{
|
|
1137
|
+
kind: "build",
|
|
1138
|
+
level: "success",
|
|
1139
|
+
title: "mini build completed",
|
|
1140
|
+
detail: `生产构建已完成,当前 analyze 结果包含 ${analyzeResult.packages.length} 个包。`,
|
|
1141
|
+
durationMs: Date.now() - miniBuildStartedAt,
|
|
1142
|
+
tags: ["build", "mini"]
|
|
1143
|
+
}]);
|
|
1144
|
+
}
|
|
1041
1145
|
}
|
|
1042
1146
|
const webConfig = configService.weappWebConfig;
|
|
1043
|
-
if (targets.runWeb && webConfig?.enabled)
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1147
|
+
if (targets.runWeb && webConfig?.enabled) {
|
|
1148
|
+
const webBuildStartedAt = Date.now();
|
|
1149
|
+
try {
|
|
1150
|
+
await webService?.build();
|
|
1151
|
+
logger_default.success(`Web 构建完成,输出目录:${colors.green(configService.relativeCwd(webConfig.outDir))}`);
|
|
1152
|
+
emitDashboardEvents$1(analyzeHandle, [{
|
|
1153
|
+
kind: "build",
|
|
1154
|
+
level: "success",
|
|
1155
|
+
title: "web build completed",
|
|
1156
|
+
detail: `Web 构建已完成,输出目录 ${configService.relativeCwd(webConfig.outDir)}。`,
|
|
1157
|
+
durationMs: Date.now() - webBuildStartedAt,
|
|
1158
|
+
tags: ["build", "web"]
|
|
1159
|
+
}]);
|
|
1160
|
+
} catch (error) {
|
|
1161
|
+
emitDashboardEvents$1(analyzeHandle, [{
|
|
1162
|
+
kind: "diagnostic",
|
|
1163
|
+
level: "error",
|
|
1164
|
+
title: "web build failed",
|
|
1165
|
+
detail: error instanceof Error ? error.message : String(error),
|
|
1166
|
+
durationMs: Date.now() - webBuildStartedAt,
|
|
1167
|
+
tags: ["build", "web"]
|
|
1168
|
+
}]);
|
|
1169
|
+
logger_default.error(error);
|
|
1170
|
+
throw error;
|
|
1171
|
+
}
|
|
1049
1172
|
}
|
|
1050
1173
|
if (targets.runMini) logBuildAppFinish(configService, void 0, { skipWeb: !targets.runWeb });
|
|
1051
|
-
if (options.open && targets.runMini)
|
|
1174
|
+
if (options.open && targets.runMini) {
|
|
1175
|
+
emitDashboardEvents$1(analyzeHandle, [{
|
|
1176
|
+
kind: "command",
|
|
1177
|
+
level: "info",
|
|
1178
|
+
title: "opening ide",
|
|
1179
|
+
detail: "构建完成后准备打开 IDE 项目。",
|
|
1180
|
+
tags: ["ide", "open"]
|
|
1181
|
+
}]);
|
|
1182
|
+
await openIde(configService.platform, resolveIdeProjectPath(configService.mpDistRoot));
|
|
1183
|
+
}
|
|
1052
1184
|
if (analyzeHandle) await analyzeHandle.waitForExit();
|
|
1053
1185
|
ctx.watcherService?.closeAll();
|
|
1054
1186
|
terminateStaleSassEmbeddedProcess();
|
|
1055
1187
|
});
|
|
1056
1188
|
}
|
|
1057
|
-
function terminateStaleSassEmbeddedProcess() {
|
|
1058
|
-
const getHandles = process._getActiveHandles;
|
|
1059
|
-
const handles = typeof getHandles === "function" ? getHandles() : void 0;
|
|
1060
|
-
if (!Array.isArray(handles)) return;
|
|
1061
|
-
for (const handle of handles) if (isSassEmbeddedChild(handle)) try {
|
|
1062
|
-
handle.kill();
|
|
1063
|
-
} catch {}
|
|
1064
|
-
}
|
|
1065
|
-
function isSassEmbeddedChild(handle) {
|
|
1066
|
-
return Boolean(handle && typeof handle === "object" && "kill" in handle && "spawnfile" in handle && typeof handle.spawnfile === "string" && handle.spawnfile?.includes("sass-embedded"));
|
|
1067
|
-
}
|
|
1068
1189
|
//#endregion
|
|
1069
1190
|
//#region src/cli/commands/close.ts
|
|
1070
1191
|
function registerCloseCommand(cli) {
|
|
@@ -1537,6 +1658,9 @@ function registerPrepareCommand(cli) {
|
|
|
1537
1658
|
}
|
|
1538
1659
|
//#endregion
|
|
1539
1660
|
//#region src/cli/commands/serve.ts
|
|
1661
|
+
function emitDashboardEvents(handle, events) {
|
|
1662
|
+
handle?.emitRuntimeEvents(events);
|
|
1663
|
+
}
|
|
1540
1664
|
function resolveWebHost(host) {
|
|
1541
1665
|
if (host === void 0) return;
|
|
1542
1666
|
if (typeof host === "boolean") return host;
|
|
@@ -1680,6 +1804,7 @@ function registerServeCommand(cli) {
|
|
|
1680
1804
|
let analyzeHandle;
|
|
1681
1805
|
let analyzeRunId = 0;
|
|
1682
1806
|
const runAnalyze = async () => {
|
|
1807
|
+
const startedAt = Date.now();
|
|
1683
1808
|
try {
|
|
1684
1809
|
const result = await analyzeSubpackages(await createCompilerContext({
|
|
1685
1810
|
key: `serve-ui-analyze:${process.pid}:${++analyzeRunId}`,
|
|
@@ -1692,48 +1817,126 @@ function registerServeCommand(cli) {
|
|
|
1692
1817
|
projectConfigPath: options.projectConfig,
|
|
1693
1818
|
syncSupportFiles: false
|
|
1694
1819
|
}));
|
|
1695
|
-
if (hasAnalyzeData(result)) return
|
|
1820
|
+
if (hasAnalyzeData(result)) return {
|
|
1821
|
+
result,
|
|
1822
|
+
durationMs: Date.now() - startedAt,
|
|
1823
|
+
mode: "full"
|
|
1824
|
+
};
|
|
1696
1825
|
} catch (error) {
|
|
1697
1826
|
const message = error instanceof Error ? error.message : String(error);
|
|
1698
1827
|
logger_default.warn(`[ui] 完整分析失败,已回退到 dist 文件扫描:${message}`);
|
|
1828
|
+
return {
|
|
1829
|
+
result: await analyzeUiFallback(ctx),
|
|
1830
|
+
durationMs: Date.now() - startedAt,
|
|
1831
|
+
mode: "fallback",
|
|
1832
|
+
fallbackReason: message
|
|
1833
|
+
};
|
|
1699
1834
|
}
|
|
1700
|
-
return
|
|
1835
|
+
return {
|
|
1836
|
+
result: await analyzeUiFallback(ctx),
|
|
1837
|
+
durationMs: Date.now() - startedAt,
|
|
1838
|
+
mode: "fallback",
|
|
1839
|
+
fallbackReason: "完整分析结果为空,已回退到 dist 文件扫描。"
|
|
1840
|
+
};
|
|
1701
1841
|
};
|
|
1702
|
-
const triggerAnalyzeUpdate = async () => {
|
|
1842
|
+
const triggerAnalyzeUpdate = async (reason = "watch") => {
|
|
1703
1843
|
if (!analyzeHandle) return;
|
|
1844
|
+
emitDashboardEvents(analyzeHandle, [{
|
|
1845
|
+
kind: reason === "watch" ? "hmr" : "build",
|
|
1846
|
+
level: "info",
|
|
1847
|
+
title: reason === "watch" ? "analyze refresh started" : "initial analyze started",
|
|
1848
|
+
detail: reason === "watch" ? "检测到新的构建结束事件,开始刷新 analyze 面板。" : "开发态 UI 已启动,开始生成第一份 analyze 结果。",
|
|
1849
|
+
tags: reason === "watch" ? ["watch", "analyze"] : ["initial", "analyze"]
|
|
1850
|
+
}]);
|
|
1704
1851
|
const next = await runAnalyze();
|
|
1705
|
-
|
|
1852
|
+
if (next.mode === "fallback") emitDashboardEvents(analyzeHandle, [{
|
|
1853
|
+
kind: "diagnostic",
|
|
1854
|
+
level: "warning",
|
|
1855
|
+
title: "analyze fallback enabled",
|
|
1856
|
+
detail: next.fallbackReason ?? "完整分析不可用,已回退到 dist 文件扫描。",
|
|
1857
|
+
durationMs: next.durationMs,
|
|
1858
|
+
tags: ["analyze", "fallback"]
|
|
1859
|
+
}]);
|
|
1860
|
+
await analyzeHandle.update(next.result);
|
|
1861
|
+
emitDashboardEvents(analyzeHandle, [{
|
|
1862
|
+
kind: next.mode === "fallback" ? "diagnostic" : "build",
|
|
1863
|
+
level: next.mode === "fallback" ? "warning" : "success",
|
|
1864
|
+
title: reason === "watch" ? "analyze refresh completed" : "initial analyze completed",
|
|
1865
|
+
detail: next.mode === "fallback" ? `analyze 已回退到 dist 扫描,当前包含 ${next.result.packages.length} 个包。` : `analyze 已刷新完成,当前包含 ${next.result.packages.length} 个包与 ${next.result.modules.length} 个模块。`,
|
|
1866
|
+
durationMs: next.durationMs,
|
|
1867
|
+
tags: next.mode === "fallback" ? ["analyze", "fallback"] : ["analyze", reason === "watch" ? "refresh" : "initial"]
|
|
1868
|
+
}]);
|
|
1706
1869
|
};
|
|
1707
1870
|
if (targets.runMini) {
|
|
1708
1871
|
const buildResult = await buildService.build(options);
|
|
1709
1872
|
if (enableAnalyze) {
|
|
1710
|
-
|
|
1873
|
+
const initialAnalyze = await runAnalyze();
|
|
1874
|
+
analyzeHandle = await startAnalyzeDashboard(initialAnalyze.result, {
|
|
1711
1875
|
watch: true,
|
|
1712
1876
|
cwd: configService.cwd,
|
|
1713
1877
|
packageManagerAgent: configService.packageManager.agent,
|
|
1714
1878
|
silentStartupLog: true
|
|
1715
1879
|
}) ?? void 0;
|
|
1880
|
+
emitDashboardEvents(analyzeHandle, [{
|
|
1881
|
+
kind: "command",
|
|
1882
|
+
level: "success",
|
|
1883
|
+
title: "dev ui session ready",
|
|
1884
|
+
detail: `开发态分析面板已启动,当前包含 ${initialAnalyze.result.packages.length} 个包。`,
|
|
1885
|
+
durationMs: initialAnalyze.durationMs,
|
|
1886
|
+
tags: ["dev", "ui"]
|
|
1887
|
+
}]);
|
|
1888
|
+
if (initialAnalyze.mode === "fallback") emitDashboardEvents(analyzeHandle, [{
|
|
1889
|
+
kind: "diagnostic",
|
|
1890
|
+
level: "warning",
|
|
1891
|
+
title: "initial analyze fallback enabled",
|
|
1892
|
+
detail: initialAnalyze.fallbackReason ?? "完整分析不可用,已回退到 dist 文件扫描。",
|
|
1893
|
+
durationMs: initialAnalyze.durationMs,
|
|
1894
|
+
tags: [
|
|
1895
|
+
"analyze",
|
|
1896
|
+
"fallback",
|
|
1897
|
+
"initial"
|
|
1898
|
+
]
|
|
1899
|
+
}]);
|
|
1716
1900
|
let updating = false;
|
|
1717
1901
|
if (analyzeHandle && buildResult && typeof buildResult.on === "function") buildResult.on("event", (event) => {
|
|
1718
1902
|
if (event.code !== "END" || updating) return;
|
|
1719
1903
|
updating = true;
|
|
1720
|
-
triggerAnalyzeUpdate().finally(() => {
|
|
1904
|
+
triggerAnalyzeUpdate("watch").finally(() => {
|
|
1721
1905
|
updating = false;
|
|
1722
1906
|
});
|
|
1723
1907
|
});
|
|
1724
1908
|
if (analyzeHandle) {
|
|
1725
1909
|
updating = true;
|
|
1726
|
-
await triggerAnalyzeUpdate();
|
|
1910
|
+
await triggerAnalyzeUpdate("initial");
|
|
1727
1911
|
updating = false;
|
|
1728
1912
|
}
|
|
1729
1913
|
}
|
|
1730
1914
|
}
|
|
1731
1915
|
let webServer;
|
|
1732
|
-
if (targets.runWeb)
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1916
|
+
if (targets.runWeb) {
|
|
1917
|
+
const webServerStartedAt = Date.now();
|
|
1918
|
+
try {
|
|
1919
|
+
webServer = await webService?.startDevServer();
|
|
1920
|
+
emitDashboardEvents(analyzeHandle, [{
|
|
1921
|
+
kind: "system",
|
|
1922
|
+
level: "success",
|
|
1923
|
+
title: "web dev server started",
|
|
1924
|
+
detail: "Web 开发服务器已启动,可与小程序调试 UI 并行工作。",
|
|
1925
|
+
durationMs: Date.now() - webServerStartedAt,
|
|
1926
|
+
tags: ["dev", "web"]
|
|
1927
|
+
}]);
|
|
1928
|
+
} catch (error) {
|
|
1929
|
+
emitDashboardEvents(analyzeHandle, [{
|
|
1930
|
+
kind: "diagnostic",
|
|
1931
|
+
level: "error",
|
|
1932
|
+
title: "web dev server failed",
|
|
1933
|
+
detail: error instanceof Error ? error.message : String(error),
|
|
1934
|
+
durationMs: Date.now() - webServerStartedAt,
|
|
1935
|
+
tags: ["dev", "web"]
|
|
1936
|
+
}]);
|
|
1937
|
+
logger_default.error(error);
|
|
1938
|
+
throw error;
|
|
1939
|
+
}
|
|
1737
1940
|
}
|
|
1738
1941
|
if (targets.runMini) logBuildAppFinish(configService, webServer, {
|
|
1739
1942
|
skipWeb: !targets.runWeb,
|
|
@@ -1741,6 +1944,13 @@ function registerServeCommand(cli) {
|
|
|
1741
1944
|
});
|
|
1742
1945
|
else if (targets.runWeb) logBuildAppFinish(configService, webServer, { skipMini: true });
|
|
1743
1946
|
if (options.open && targets.runMini) {
|
|
1947
|
+
emitDashboardEvents(analyzeHandle, [{
|
|
1948
|
+
kind: "command",
|
|
1949
|
+
level: "info",
|
|
1950
|
+
title: "opening ide",
|
|
1951
|
+
detail: "开发服务已就绪,准备打开 IDE 项目。",
|
|
1952
|
+
tags: ["ide", "open"]
|
|
1953
|
+
}]);
|
|
1744
1954
|
if (!await maybeStartForwardConsole({
|
|
1745
1955
|
platform: configService.platform,
|
|
1746
1956
|
mpDistRoot: configService.mpDistRoot,
|