weapp-vite 6.15.0 → 6.15.3
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 +1 -1
- package/dist/cli.mjs +284 -221
- package/dist/{config-c4UHLLoh.d.mts → config-B5YFoO3u.d.mts} +33 -11
- package/dist/config.d.mts +1 -1
- package/dist/{createContext-DZzBkyLu.mjs → createContext-BuwQryVc.mjs} +4927 -4341
- package/dist/file-BVlUDAip.mjs +2 -0
- package/dist/{file-DZdM8x0_.mjs → file-x_pM3sdN.mjs} +59 -59
- package/dist/getInstance-DPy6RmDl.mjs +2 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +2 -2
- package/dist/json.d.mts +1 -1
- package/dist/mcp.d.mts +1 -1
- package/dist/{runtime-tVnzZwtl.mjs → runtime-Cn2Y_tqB.mjs} +2 -2
- package/dist/{runtime-58wbbRDf.d.mts → runtime-DSLk7kWi.d.mts} +1 -0
- package/dist/runtime.d.mts +1 -1
- package/dist/runtime.mjs +1 -1
- package/dist/types.d.mts +2 -2
- package/dist/web-apis.d.mts +3 -1
- package/dist/web-apis.mjs +2 -1
- package/package.json +11 -10
- package/dist/file-BKp0PdYt.mjs +0 -2
- package/dist/getInstance-CIT2xNbn.mjs +0 -2
package/dist/auto-routes.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as getCompilerContext, u as getRouteRuntimeGlobalKeys } from "./createContext-
|
|
1
|
+
import { i as getCompilerContext, u as getRouteRuntimeGlobalKeys } from "./createContext-BuwQryVc.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) {
|
package/dist/cli.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { S as isPathInside, _ as DEFAULT_MP_PLATFORM, b as resolveMiniPlatform, c as createSharedBuildConfig, d as resolveWeappConfigFile, f as checkRuntime, g as createCjsConfigLoadError, h as parseCommentJson, l as SHARED_CHUNK_VIRTUAL_PREFIX, m as loadViteConfigFile, n as syncProjectSupportFiles, p as getProjectConfigFileName, r as syncManagedTsconfigBootstrapFiles, s as formatBytes, t as createCompilerContext, v as getDefaultIdeProjectRoot, x as shouldPassPlatformArgToIdeOpen, y as normalizeMiniPlatform } from "./createContext-
|
|
1
|
+
import { S as isPathInside, _ as DEFAULT_MP_PLATFORM, b as resolveMiniPlatform, c as createSharedBuildConfig, d as resolveWeappConfigFile, f as checkRuntime, g as createCjsConfigLoadError, h as parseCommentJson, l as SHARED_CHUNK_VIRTUAL_PREFIX, m as loadViteConfigFile, n as syncProjectSupportFiles, p as getProjectConfigFileName, r as syncManagedTsconfigBootstrapFiles, s as formatBytes, t as createCompilerContext, v as getDefaultIdeProjectRoot, x as shouldPassPlatformArgToIdeOpen, y as normalizeMiniPlatform } from "./createContext-BuwQryVc.mjs";
|
|
2
2
|
import { r as logger_default, t as colors } from "./logger-CgxdNjvb.mjs";
|
|
3
|
-
import {
|
|
3
|
+
import { h as VERSION } from "./file-x_pM3sdN.mjs";
|
|
4
4
|
import { a as resolveWeappMcpConfig, o as startWeappViteMcpServer } from "./mcp-DRlj32v4.mjs";
|
|
5
5
|
import { createRequire } from "node:module";
|
|
6
|
-
import { defu, fs } from "@weapp-core/shared";
|
|
7
6
|
import path, { posix } from "pathe";
|
|
7
|
+
import { defu, fs } from "@weapp-core/shared";
|
|
8
8
|
import process from "node:process";
|
|
9
9
|
import fs$1 from "node:fs/promises";
|
|
10
10
|
import { build, createServer } from "vite";
|
|
@@ -1626,7 +1626,7 @@ function registerInitCommand(cli) {
|
|
|
1626
1626
|
});
|
|
1627
1627
|
}
|
|
1628
1628
|
//#endregion
|
|
1629
|
-
//#region src/cli/mcpClient.ts
|
|
1629
|
+
//#region src/cli/mcpClient/shared.ts
|
|
1630
1630
|
const CODEX_BLOCK_PREFIX = "# >>> weapp-vite mcp ";
|
|
1631
1631
|
const CODEX_BLOCK_SUFFIX = " >>>";
|
|
1632
1632
|
const CODEX_BLOCK_END_PREFIX = "# <<< weapp-vite mcp ";
|
|
@@ -1710,6 +1710,9 @@ function resolveHttpEntry(client, url) {
|
|
|
1710
1710
|
};
|
|
1711
1711
|
return { url };
|
|
1712
1712
|
}
|
|
1713
|
+
function resolveConfigEntry(client, transport, workspaceRoot, url) {
|
|
1714
|
+
return transport === "http" ? resolveHttpEntry(client, url ?? "") : resolveCommandEntry(client, workspaceRoot);
|
|
1715
|
+
}
|
|
1713
1716
|
function resolveCodexBlockPattern(serverName) {
|
|
1714
1717
|
const startMarker = `${CODEX_BLOCK_PREFIX}${serverName}${CODEX_BLOCK_SUFFIX}`;
|
|
1715
1718
|
const endMarker = `${CODEX_BLOCK_END_PREFIX}${serverName}${CODEX_BLOCK_END_SUFFIX}`;
|
|
@@ -1750,40 +1753,8 @@ function resolveTarget(client, workspaceRoot) {
|
|
|
1750
1753
|
serverName
|
|
1751
1754
|
};
|
|
1752
1755
|
}
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
throw new Error(`不支持的 MCP 客户端:${input}。当前仅支持 codex、claude-code、cursor。`);
|
|
1756
|
-
}
|
|
1757
|
-
function buildMcpClientConfigPlan(options) {
|
|
1758
|
-
const workspaceRoot = path.resolve(options.workspaceRoot);
|
|
1759
|
-
const target = resolveTarget(options.client, workspaceRoot);
|
|
1760
|
-
const entry = options.transport === "http" ? resolveHttpEntry(options.client, options.url ?? "") : resolveCommandEntry(options.client, workspaceRoot);
|
|
1761
|
-
if (options.transport === "http" && !entry.url) throw new Error("HTTP 模式缺少 MCP 服务地址,请使用 --url 指定或在当前项目中检测到可用地址。");
|
|
1762
|
-
return {
|
|
1763
|
-
entry,
|
|
1764
|
-
preview: target.client === "codex" ? renderCodexBlock(target.serverName, entry) : renderJsonPreview(target.serverName, entry),
|
|
1765
|
-
target,
|
|
1766
|
-
transport: options.transport
|
|
1767
|
-
};
|
|
1768
|
-
}
|
|
1769
|
-
async function writeMcpClientConfig(plan) {
|
|
1770
|
-
await fs.ensureDir(path.dirname(plan.target.configPath));
|
|
1771
|
-
const existing = await fs.readFile(plan.target.configPath, "utf8").catch(() => "");
|
|
1772
|
-
if (plan.target.client === "codex") {
|
|
1773
|
-
const nextContent = upsertCodexManagedBlock(existing, plan.target.serverName, plan.preview);
|
|
1774
|
-
await fs.writeFile(plan.target.configPath, nextContent, "utf8");
|
|
1775
|
-
return;
|
|
1776
|
-
}
|
|
1777
|
-
const parsed = parseJsonConfig(existing, plan.target.configPath);
|
|
1778
|
-
const nextConfig = {
|
|
1779
|
-
...parsed,
|
|
1780
|
-
mcpServers: {
|
|
1781
|
-
...parsed.mcpServers ?? {},
|
|
1782
|
-
[plan.target.serverName]: plan.entry
|
|
1783
|
-
}
|
|
1784
|
-
};
|
|
1785
|
-
await fs.writeFile(plan.target.configPath, `${JSON.stringify(nextConfig, null, 2)}\n`, "utf8");
|
|
1786
|
-
}
|
|
1756
|
+
//#endregion
|
|
1757
|
+
//#region src/cli/mcpClient/inspect.ts
|
|
1787
1758
|
async function probeHttpEndpoint(url) {
|
|
1788
1759
|
const controller = new AbortController();
|
|
1789
1760
|
const timer = setTimeout$1(() => {
|
|
@@ -1888,6 +1859,24 @@ async function inspectMcpClientConfig(options) {
|
|
|
1888
1859
|
if (target.client === "codex") return await inspectCodexConfig(target);
|
|
1889
1860
|
return await inspectJsonConfig(target);
|
|
1890
1861
|
}
|
|
1862
|
+
//#endregion
|
|
1863
|
+
//#region src/cli/mcpClient/plan.ts
|
|
1864
|
+
function resolveSupportedMcpClient(input) {
|
|
1865
|
+
if (input === "codex" || input === "claude-code" || input === "cursor") return input;
|
|
1866
|
+
throw new Error(`不支持的 MCP 客户端:${input}。当前仅支持 codex、claude-code、cursor。`);
|
|
1867
|
+
}
|
|
1868
|
+
function buildMcpClientConfigPlan(options) {
|
|
1869
|
+
const workspaceRoot = path.resolve(options.workspaceRoot);
|
|
1870
|
+
const target = resolveTarget(options.client, workspaceRoot);
|
|
1871
|
+
const entry = resolveConfigEntry(options.client, options.transport, workspaceRoot, options.url);
|
|
1872
|
+
if (options.transport === "http" && !entry.url) throw new Error("HTTP 模式缺少 MCP 服务地址,请使用 --url 指定或在当前项目中检测到可用地址。");
|
|
1873
|
+
return {
|
|
1874
|
+
entry,
|
|
1875
|
+
preview: target.client === "codex" ? renderCodexBlock(target.serverName, entry) : renderJsonPreview(target.serverName, entry),
|
|
1876
|
+
target,
|
|
1877
|
+
transport: options.transport
|
|
1878
|
+
};
|
|
1879
|
+
}
|
|
1891
1880
|
function formatMcpQuickStart(options) {
|
|
1892
1881
|
const suffix = options.transport === "http" && options.httpUrl ? ` --transport http --url ${options.httpUrl}` : "";
|
|
1893
1882
|
return [
|
|
@@ -1898,6 +1887,26 @@ function formatMcpQuickStart(options) {
|
|
|
1898
1887
|
];
|
|
1899
1888
|
}
|
|
1900
1889
|
//#endregion
|
|
1890
|
+
//#region src/cli/mcpClient/index.ts
|
|
1891
|
+
async function writeMcpClientConfig(plan) {
|
|
1892
|
+
await fs.ensureDir(path.dirname(plan.target.configPath));
|
|
1893
|
+
const existing = await fs.readFile(plan.target.configPath, "utf8").catch(() => "");
|
|
1894
|
+
if (plan.target.client === "codex") {
|
|
1895
|
+
const nextContent = upsertCodexManagedBlock(existing, plan.target.serverName, plan.preview);
|
|
1896
|
+
await fs.writeFile(plan.target.configPath, nextContent, "utf8");
|
|
1897
|
+
return;
|
|
1898
|
+
}
|
|
1899
|
+
const parsed = parseJsonConfig(existing, plan.target.configPath);
|
|
1900
|
+
const nextConfig = {
|
|
1901
|
+
...parsed,
|
|
1902
|
+
mcpServers: {
|
|
1903
|
+
...parsed.mcpServers ?? {},
|
|
1904
|
+
[plan.target.serverName]: plan.entry
|
|
1905
|
+
}
|
|
1906
|
+
};
|
|
1907
|
+
await fs.writeFile(plan.target.configPath, `${JSON.stringify(nextConfig, null, 2)}\n`, "utf8");
|
|
1908
|
+
}
|
|
1909
|
+
//#endregion
|
|
1901
1910
|
//#region src/cli/commands/mcp.ts
|
|
1902
1911
|
function resolvePort(port) {
|
|
1903
1912
|
if (typeof port === "number" && Number.isInteger(port)) return port;
|
|
@@ -2068,25 +2077,13 @@ function registerPrepareCommand(cli) {
|
|
|
2068
2077
|
}
|
|
2069
2078
|
//#endregion
|
|
2070
2079
|
//#region package.json
|
|
2071
|
-
var version = "6.15.
|
|
2080
|
+
var version = "6.15.3";
|
|
2072
2081
|
//#endregion
|
|
2073
|
-
//#region src/cli/devHotkeys.ts
|
|
2074
|
-
const DEV_SCREENSHOT_DIR = ".weapp-vite/dev-screenshots";
|
|
2075
|
-
const DEFAULT_SCREENSHOT_TIMEOUT = 3e4;
|
|
2076
|
-
const REG_PENDING_PREFIX = /^正在/;
|
|
2082
|
+
//#region src/cli/devHotkeys/format.ts
|
|
2077
2083
|
const FULLWIDTH_ASCII_START = 65281;
|
|
2078
2084
|
const FULLWIDTH_ASCII_END = 65374;
|
|
2079
2085
|
const FULLWIDTH_ASCII_OFFSET = 65248;
|
|
2080
|
-
const
|
|
2081
|
-
function formatMcpUrl(host, port, endpoint) {
|
|
2082
|
-
return `http://${host}:${port}${endpoint}`;
|
|
2083
|
-
}
|
|
2084
|
-
function forwardSigint() {
|
|
2085
|
-
process.kill(process.pid, "SIGINT");
|
|
2086
|
-
}
|
|
2087
|
-
function forwardSigtstp() {
|
|
2088
|
-
process.kill(process.pid, "SIGTSTP");
|
|
2089
|
-
}
|
|
2086
|
+
const REG_PENDING_PREFIX = /^正在/;
|
|
2090
2087
|
function formatProjectLabel(cwd) {
|
|
2091
2088
|
return path.basename(cwd) || cwd;
|
|
2092
2089
|
}
|
|
@@ -2157,6 +2154,59 @@ function formatDevHotkeyHintWithState(state) {
|
|
|
2157
2154
|
if (state.currentAction) return `${formatFooterLine(state)},按 ${key("h")} 显示帮助,按 ${key("q")} 退出`;
|
|
2158
2155
|
return `开发快捷键已就绪,按 ${key("h")} 显示帮助,按 ${key("q")} 退出`;
|
|
2159
2156
|
}
|
|
2157
|
+
function normalizeInputChar(input) {
|
|
2158
|
+
if (input.length !== 1) return input;
|
|
2159
|
+
const codePoint = input.codePointAt(0);
|
|
2160
|
+
if (!codePoint) return input;
|
|
2161
|
+
if (codePoint >= FULLWIDTH_ASCII_START && codePoint <= FULLWIDTH_ASCII_END) return String.fromCodePoint(codePoint - FULLWIDTH_ASCII_OFFSET);
|
|
2162
|
+
return input;
|
|
2163
|
+
}
|
|
2164
|
+
function resolveProjectLabel(cwd) {
|
|
2165
|
+
return formatProjectLabel(cwd);
|
|
2166
|
+
}
|
|
2167
|
+
//#endregion
|
|
2168
|
+
//#region src/cli/devHotkeys/mcp.ts
|
|
2169
|
+
function formatMcpUrl(host, port, endpoint) {
|
|
2170
|
+
return `http://${host}:${port}${endpoint}`;
|
|
2171
|
+
}
|
|
2172
|
+
function createToggleMcpAction(options) {
|
|
2173
|
+
const { cwd, getHandle, resolvedMcp, setHandle } = options;
|
|
2174
|
+
return async function toggleMcp() {
|
|
2175
|
+
if (!resolvedMcp.enabled) {
|
|
2176
|
+
logger_default.warn("[dev action] MCP 已在配置中禁用,跳过切换。");
|
|
2177
|
+
return "MCP 已禁用";
|
|
2178
|
+
}
|
|
2179
|
+
const existingHandle = getHandle();
|
|
2180
|
+
if (existingHandle?.close) {
|
|
2181
|
+
const url = formatMcpUrl(resolvedMcp.host, resolvedMcp.port, resolvedMcp.endpoint);
|
|
2182
|
+
logger_default.info(`[dev action] 正在关闭 MCP 服务:${colors.cyan(url)}`);
|
|
2183
|
+
await existingHandle.close();
|
|
2184
|
+
setHandle(void 0);
|
|
2185
|
+
logger_default.success(`[dev action] MCP 服务已关闭:${colors.cyan(url)}`);
|
|
2186
|
+
return `MCP 已关闭 (${url})`;
|
|
2187
|
+
}
|
|
2188
|
+
const url = formatMcpUrl(resolvedMcp.host, resolvedMcp.port, resolvedMcp.endpoint);
|
|
2189
|
+
logger_default.info(`[dev action] 正在启动 MCP 服务:${colors.cyan(url)}`);
|
|
2190
|
+
setHandle(await startWeappViteMcpServer({
|
|
2191
|
+
endpoint: resolvedMcp.endpoint,
|
|
2192
|
+
host: resolvedMcp.host,
|
|
2193
|
+
port: resolvedMcp.port,
|
|
2194
|
+
transport: "streamable-http",
|
|
2195
|
+
unref: false,
|
|
2196
|
+
workspaceRoot: cwd
|
|
2197
|
+
}));
|
|
2198
|
+
logger_default.success(`[dev action] MCP 服务已启动:${colors.cyan(url)}`);
|
|
2199
|
+
for (const line of formatMcpQuickStart({
|
|
2200
|
+
httpUrl: url,
|
|
2201
|
+
transport: "http"
|
|
2202
|
+
})) logger_default.info(line);
|
|
2203
|
+
return `MCP 已启动 (${url})`;
|
|
2204
|
+
};
|
|
2205
|
+
}
|
|
2206
|
+
//#endregion
|
|
2207
|
+
//#region src/cli/devHotkeys/screenshot.ts
|
|
2208
|
+
const DEV_SCREENSHOT_DIR = ".weapp-vite/dev-screenshots";
|
|
2209
|
+
const DEFAULT_SCREENSHOT_TIMEOUT = 3e4;
|
|
2160
2210
|
/**
|
|
2161
2211
|
* @description 生成开发态截图输出路径。
|
|
2162
2212
|
*/
|
|
@@ -2172,13 +2222,6 @@ function formatLogPath(cwd, targetPath) {
|
|
|
2172
2222
|
function formatResolvedScreenshotPath(cwd, fallbackPath, result) {
|
|
2173
2223
|
return formatLogPath(cwd, result.path ?? fallbackPath);
|
|
2174
2224
|
}
|
|
2175
|
-
function normalizeInputChar(input) {
|
|
2176
|
-
if (input.length !== 1) return input;
|
|
2177
|
-
const codePoint = input.codePointAt(0);
|
|
2178
|
-
if (!codePoint) return input;
|
|
2179
|
-
if (codePoint >= FULLWIDTH_ASCII_START && codePoint <= FULLWIDTH_ASCII_END) return String.fromCodePoint(codePoint - FULLWIDTH_ASCII_OFFSET);
|
|
2180
|
-
return input;
|
|
2181
|
-
}
|
|
2182
2225
|
/**
|
|
2183
2226
|
* @description 执行当前页面截图并输出结果日志。
|
|
2184
2227
|
*/
|
|
@@ -2197,6 +2240,14 @@ async function runScreenshotAction(options) {
|
|
|
2197
2240
|
logger_default.success(`[dev action] 当前页面截图完成:${colors.cyan(resolvedPath)}`);
|
|
2198
2241
|
return resolvedPath;
|
|
2199
2242
|
}
|
|
2243
|
+
//#endregion
|
|
2244
|
+
//#region src/cli/devHotkeys/index.ts
|
|
2245
|
+
function forwardSigint() {
|
|
2246
|
+
process.kill(process.pid, "SIGINT");
|
|
2247
|
+
}
|
|
2248
|
+
function forwardSigtstp() {
|
|
2249
|
+
process.kill(process.pid, "SIGTSTP");
|
|
2250
|
+
}
|
|
2200
2251
|
/**
|
|
2201
2252
|
* @description 在开发态启动终端快捷键,并将动作输出到本地日志。
|
|
2202
2253
|
*/
|
|
@@ -2222,7 +2273,7 @@ function startDevHotkeys(options) {
|
|
|
2222
2273
|
lastAction,
|
|
2223
2274
|
mcpEnabled: resolvedMcp.enabled,
|
|
2224
2275
|
mcpRunning: Boolean(mcpHandle?.close),
|
|
2225
|
-
projectLabel:
|
|
2276
|
+
projectLabel: resolveProjectLabel(options.cwd)
|
|
2226
2277
|
});
|
|
2227
2278
|
const detachTerminal = () => {
|
|
2228
2279
|
if (hasSetRawMode) process.stdin.setRawMode(false);
|
|
@@ -2279,36 +2330,14 @@ function startDevHotkeys(options) {
|
|
|
2279
2330
|
detachTerminal();
|
|
2280
2331
|
forwardSigtstp();
|
|
2281
2332
|
};
|
|
2282
|
-
const toggleMcp =
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2333
|
+
const toggleMcp = createToggleMcpAction({
|
|
2334
|
+
cwd: options.cwd,
|
|
2335
|
+
getHandle: () => mcpHandle,
|
|
2336
|
+
resolvedMcp,
|
|
2337
|
+
setHandle: (handle) => {
|
|
2338
|
+
mcpHandle = handle;
|
|
2286
2339
|
}
|
|
2287
|
-
|
|
2288
|
-
const url = formatMcpUrl(resolvedMcp.host, resolvedMcp.port, resolvedMcp.endpoint);
|
|
2289
|
-
logger_default.info(`[dev action] 正在关闭 MCP 服务:${colors.cyan(url)}`);
|
|
2290
|
-
await mcpHandle.close();
|
|
2291
|
-
mcpHandle = void 0;
|
|
2292
|
-
logger_default.success(`[dev action] MCP 服务已关闭:${colors.cyan(url)}`);
|
|
2293
|
-
return `MCP 已关闭 (${url})`;
|
|
2294
|
-
}
|
|
2295
|
-
const url = formatMcpUrl(resolvedMcp.host, resolvedMcp.port, resolvedMcp.endpoint);
|
|
2296
|
-
logger_default.info(`[dev action] 正在启动 MCP 服务:${colors.cyan(url)}`);
|
|
2297
|
-
mcpHandle = await startWeappViteMcpServer({
|
|
2298
|
-
endpoint: resolvedMcp.endpoint,
|
|
2299
|
-
host: resolvedMcp.host,
|
|
2300
|
-
port: resolvedMcp.port,
|
|
2301
|
-
transport: "streamable-http",
|
|
2302
|
-
unref: false,
|
|
2303
|
-
workspaceRoot: options.cwd
|
|
2304
|
-
});
|
|
2305
|
-
logger_default.success(`[dev action] MCP 服务已启动:${colors.cyan(url)}`);
|
|
2306
|
-
for (const line of formatMcpQuickStart({
|
|
2307
|
-
httpUrl: url,
|
|
2308
|
-
transport: "http"
|
|
2309
|
-
})) logger_default.info(line);
|
|
2310
|
-
return `MCP 已启动 (${url})`;
|
|
2311
|
-
};
|
|
2340
|
+
});
|
|
2312
2341
|
const runAction = (label, pendingLabel, action) => {
|
|
2313
2342
|
if (running) {
|
|
2314
2343
|
const current = currentAction ?? "已有命令";
|
|
@@ -2363,12 +2392,12 @@ function startDevHotkeys(options) {
|
|
|
2363
2392
|
const handleInputOnce = (input, source) => {
|
|
2364
2393
|
const normalizedInput = normalizeInputChar(input);
|
|
2365
2394
|
const now = Date.now();
|
|
2366
|
-
for (const [token, timestamp] of recentInputs) if (now - Number(timestamp.split(":")[1] ?? 0) >
|
|
2395
|
+
for (const [token, timestamp] of recentInputs) if (now - Number(timestamp.split(":")[1] ?? 0) > 32) recentInputs.delete(token);
|
|
2367
2396
|
const dedupKey = normalizedInput;
|
|
2368
2397
|
const recentEntry = recentInputs.get(dedupKey);
|
|
2369
2398
|
if (recentEntry !== void 0) {
|
|
2370
2399
|
const [recentSource, recentTimestamp] = recentEntry.split(":");
|
|
2371
|
-
if (recentSource !== source && now - Number(recentTimestamp) <=
|
|
2400
|
+
if (recentSource !== source && now - Number(recentTimestamp) <= 32) return;
|
|
2372
2401
|
}
|
|
2373
2402
|
recentInputs.set(dedupKey, `${source}:${now}`);
|
|
2374
2403
|
handleInput(normalizedInput);
|
|
@@ -2404,32 +2433,15 @@ function startDevHotkeys(options) {
|
|
|
2404
2433
|
};
|
|
2405
2434
|
}
|
|
2406
2435
|
//#endregion
|
|
2407
|
-
//#region src/cli/commands/serve.ts
|
|
2436
|
+
//#region src/cli/commands/serve/analyze.ts
|
|
2437
|
+
const REG_DIST_PAGE_ENTRY = /pages\/.+\/index\.js$/;
|
|
2438
|
+
const REG_DIST_POSIX_SEP = /\\/g;
|
|
2408
2439
|
function emitDashboardEvents(handle, events) {
|
|
2409
2440
|
handle?.emitRuntimeEvents(events);
|
|
2410
2441
|
}
|
|
2411
|
-
function resolveWebHost(host) {
|
|
2412
|
-
if (host === void 0) return;
|
|
2413
|
-
if (typeof host === "boolean") return host;
|
|
2414
|
-
if (typeof host === "string") return host;
|
|
2415
|
-
return String(host);
|
|
2416
|
-
}
|
|
2417
|
-
const REG_DIST_PAGE_ENTRY = /pages\/.+\/index\.js$/;
|
|
2418
|
-
const REG_DIST_POSIX_SEP = /\\/g;
|
|
2419
2442
|
function hasAnalyzeData(result) {
|
|
2420
2443
|
return result.packages.length > 0 || result.modules.length > 0;
|
|
2421
2444
|
}
|
|
2422
|
-
function waitForServeShutdownSignal() {
|
|
2423
|
-
return new Promise((resolve) => {
|
|
2424
|
-
const onSignal = () => {
|
|
2425
|
-
process.off("SIGINT", onSignal);
|
|
2426
|
-
process.off("SIGTERM", onSignal);
|
|
2427
|
-
resolve();
|
|
2428
|
-
};
|
|
2429
|
-
process.on("SIGINT", onSignal);
|
|
2430
|
-
process.on("SIGTERM", onSignal);
|
|
2431
|
-
});
|
|
2432
|
-
}
|
|
2433
2445
|
async function collectOutputFiles(root) {
|
|
2434
2446
|
const entries = await fs$1.readdir(root, { withFileTypes: true });
|
|
2435
2447
|
const files = [];
|
|
@@ -2503,6 +2515,153 @@ async function analyzeUiFallback(ctx) {
|
|
|
2503
2515
|
})).filter((item) => item.root).sort((a, b) => a.root.localeCompare(b.root))
|
|
2504
2516
|
};
|
|
2505
2517
|
}
|
|
2518
|
+
function createAnalyzeController(options) {
|
|
2519
|
+
const { configFile, ctx, options: cliOptions, targets } = options;
|
|
2520
|
+
const { configService } = ctx;
|
|
2521
|
+
let analyzeRunId = 0;
|
|
2522
|
+
let analyzeHandle;
|
|
2523
|
+
const runAnalyze = async () => {
|
|
2524
|
+
const startedAt = Date.now();
|
|
2525
|
+
try {
|
|
2526
|
+
const result = await analyzeSubpackages(await createCompilerContext({
|
|
2527
|
+
key: `serve-ui-analyze:${process.pid}:${++analyzeRunId}`,
|
|
2528
|
+
cwd: configService.cwd,
|
|
2529
|
+
mode: configService.mode,
|
|
2530
|
+
isDev: false,
|
|
2531
|
+
configFile,
|
|
2532
|
+
inlineConfig: createInlineConfig(targets.mpPlatform),
|
|
2533
|
+
cliPlatform: targets.rawPlatform,
|
|
2534
|
+
projectConfigPath: cliOptions.projectConfig,
|
|
2535
|
+
syncSupportFiles: false
|
|
2536
|
+
}));
|
|
2537
|
+
if (hasAnalyzeData(result)) return {
|
|
2538
|
+
result,
|
|
2539
|
+
durationMs: Date.now() - startedAt,
|
|
2540
|
+
mode: "full"
|
|
2541
|
+
};
|
|
2542
|
+
} catch (error) {
|
|
2543
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2544
|
+
logger_default.warn(`[ui] 完整分析失败,已回退到 dist 文件扫描:${message}`);
|
|
2545
|
+
return {
|
|
2546
|
+
result: await analyzeUiFallback(ctx),
|
|
2547
|
+
durationMs: Date.now() - startedAt,
|
|
2548
|
+
mode: "fallback",
|
|
2549
|
+
fallbackReason: message
|
|
2550
|
+
};
|
|
2551
|
+
}
|
|
2552
|
+
return {
|
|
2553
|
+
result: await analyzeUiFallback(ctx),
|
|
2554
|
+
durationMs: Date.now() - startedAt,
|
|
2555
|
+
mode: "fallback",
|
|
2556
|
+
fallbackReason: "完整分析结果为空,已回退到 dist 文件扫描。"
|
|
2557
|
+
};
|
|
2558
|
+
};
|
|
2559
|
+
const triggerAnalyzeUpdate = async (reason = "watch") => {
|
|
2560
|
+
if (!analyzeHandle) return;
|
|
2561
|
+
emitDashboardEvents(analyzeHandle, [{
|
|
2562
|
+
kind: reason === "watch" ? "hmr" : "build",
|
|
2563
|
+
level: "info",
|
|
2564
|
+
title: reason === "watch" ? "analyze refresh started" : "initial analyze started",
|
|
2565
|
+
detail: reason === "watch" ? "检测到新的构建结束事件,开始刷新 analyze 面板。" : "开发态 UI 已启动,开始生成第一份 analyze 结果。",
|
|
2566
|
+
tags: reason === "watch" ? ["watch", "analyze"] : ["initial", "analyze"]
|
|
2567
|
+
}]);
|
|
2568
|
+
const next = await runAnalyze();
|
|
2569
|
+
if (next.mode === "fallback") emitDashboardEvents(analyzeHandle, [{
|
|
2570
|
+
kind: "diagnostic",
|
|
2571
|
+
level: "warning",
|
|
2572
|
+
title: "analyze fallback enabled",
|
|
2573
|
+
detail: next.fallbackReason ?? "完整分析不可用,已回退到 dist 文件扫描。",
|
|
2574
|
+
durationMs: next.durationMs,
|
|
2575
|
+
tags: ["analyze", "fallback"]
|
|
2576
|
+
}]);
|
|
2577
|
+
await analyzeHandle.update(next.result);
|
|
2578
|
+
emitDashboardEvents(analyzeHandle, [{
|
|
2579
|
+
kind: next.mode === "fallback" ? "diagnostic" : "build",
|
|
2580
|
+
level: next.mode === "fallback" ? "warning" : "success",
|
|
2581
|
+
title: reason === "watch" ? "analyze refresh completed" : "initial analyze completed",
|
|
2582
|
+
detail: next.mode === "fallback" ? `analyze 已回退到 dist 扫描,当前包含 ${next.result.packages.length} 个包。` : `analyze 已刷新完成,当前包含 ${next.result.packages.length} 个包与 ${next.result.modules.length} 个模块。`,
|
|
2583
|
+
durationMs: next.durationMs,
|
|
2584
|
+
tags: next.mode === "fallback" ? ["analyze", "fallback"] : ["analyze", reason === "watch" ? "refresh" : "initial"]
|
|
2585
|
+
}]);
|
|
2586
|
+
};
|
|
2587
|
+
const bindWatcher = (buildResult) => {
|
|
2588
|
+
let updating = false;
|
|
2589
|
+
if (analyzeHandle && buildResult && typeof buildResult.on === "function") buildResult.on("event", (event) => {
|
|
2590
|
+
if (event.code !== "END" || updating) return;
|
|
2591
|
+
updating = true;
|
|
2592
|
+
triggerAnalyzeUpdate("watch").finally(() => {
|
|
2593
|
+
updating = false;
|
|
2594
|
+
});
|
|
2595
|
+
});
|
|
2596
|
+
return { async runInitialUpdate() {
|
|
2597
|
+
if (analyzeHandle) {
|
|
2598
|
+
updating = true;
|
|
2599
|
+
await triggerAnalyzeUpdate("initial");
|
|
2600
|
+
updating = false;
|
|
2601
|
+
}
|
|
2602
|
+
} };
|
|
2603
|
+
};
|
|
2604
|
+
return {
|
|
2605
|
+
getHandle: () => analyzeHandle,
|
|
2606
|
+
async startDashboard(startDashboard) {
|
|
2607
|
+
const initialAnalyze = await runAnalyze();
|
|
2608
|
+
analyzeHandle = await startDashboard(initialAnalyze.result, {
|
|
2609
|
+
watch: true,
|
|
2610
|
+
cwd: configService.cwd,
|
|
2611
|
+
packageManagerAgent: configService.packageManager.agent,
|
|
2612
|
+
silentStartupLog: true
|
|
2613
|
+
}) ?? void 0;
|
|
2614
|
+
emitDashboardEvents(analyzeHandle, [{
|
|
2615
|
+
kind: "command",
|
|
2616
|
+
level: "success",
|
|
2617
|
+
title: "dev ui session ready",
|
|
2618
|
+
detail: `开发态分析面板已启动,当前包含 ${initialAnalyze.result.packages.length} 个包。`,
|
|
2619
|
+
durationMs: initialAnalyze.durationMs,
|
|
2620
|
+
tags: ["dev", "ui"]
|
|
2621
|
+
}]);
|
|
2622
|
+
if (initialAnalyze.mode === "fallback") emitDashboardEvents(analyzeHandle, [{
|
|
2623
|
+
kind: "diagnostic",
|
|
2624
|
+
level: "warning",
|
|
2625
|
+
title: "initial analyze fallback enabled",
|
|
2626
|
+
detail: initialAnalyze.fallbackReason ?? "完整分析不可用,已回退到 dist 文件扫描。",
|
|
2627
|
+
durationMs: initialAnalyze.durationMs,
|
|
2628
|
+
tags: [
|
|
2629
|
+
"analyze",
|
|
2630
|
+
"fallback",
|
|
2631
|
+
"initial"
|
|
2632
|
+
]
|
|
2633
|
+
}]);
|
|
2634
|
+
},
|
|
2635
|
+
bindWatcher,
|
|
2636
|
+
emitRuntimeEvents(events) {
|
|
2637
|
+
emitDashboardEvents(analyzeHandle, events);
|
|
2638
|
+
},
|
|
2639
|
+
waitForExit() {
|
|
2640
|
+
return analyzeHandle?.waitForExit();
|
|
2641
|
+
}
|
|
2642
|
+
};
|
|
2643
|
+
}
|
|
2644
|
+
//#endregion
|
|
2645
|
+
//#region src/cli/commands/serve/shared.ts
|
|
2646
|
+
function resolveWebHost(host) {
|
|
2647
|
+
if (host === void 0) return;
|
|
2648
|
+
if (typeof host === "boolean") return host;
|
|
2649
|
+
if (typeof host === "string") return host;
|
|
2650
|
+
return String(host);
|
|
2651
|
+
}
|
|
2652
|
+
function waitForServeShutdownSignal() {
|
|
2653
|
+
return new Promise((resolve) => {
|
|
2654
|
+
const onSignal = () => {
|
|
2655
|
+
process.off("SIGINT", onSignal);
|
|
2656
|
+
process.off("SIGTERM", onSignal);
|
|
2657
|
+
resolve();
|
|
2658
|
+
};
|
|
2659
|
+
process.on("SIGINT", onSignal);
|
|
2660
|
+
process.on("SIGTERM", onSignal);
|
|
2661
|
+
});
|
|
2662
|
+
}
|
|
2663
|
+
//#endregion
|
|
2664
|
+
//#region src/cli/commands/serve/index.ts
|
|
2506
2665
|
function registerServeCommand(cli) {
|
|
2507
2666
|
cli.command("[root]", "start dev server").alias("serve").alias("dev").option("--skipNpm", `[boolean] if skip npm build`).option("-o, --open", `[boolean] open ide`).option("-p, --platform <platform>", `[string] target platform (weapp | h5 | all)`).option("--project-config <path>", `[string] project config path (miniprogram only)`).option("--trust-project", "[boolean] auto trust Wechat DevTools project on open", { default: true }).option("--host [host]", `[string] web dev server host`).option("--ui", `[boolean] 启动调试 UI(当前提供分析视图)`, { default: false }).option("--analyze", `[boolean] 启动分包分析仪表盘 (实验特性)`, { default: false }).action(async (root, options) => {
|
|
2508
2667
|
filterDuplicateOptions(options);
|
|
@@ -2551,7 +2710,6 @@ function registerServeCommand(cli) {
|
|
|
2551
2710
|
logRuntimeTarget(targets, { resolvedConfigPlatform: configService.platform });
|
|
2552
2711
|
const enableAnalyze = Boolean(isUiEnabled(options) && targets.runMini);
|
|
2553
2712
|
let analyzeHandle;
|
|
2554
|
-
let analyzeRunId = 0;
|
|
2555
2713
|
const devHotkeysSession = targets.runMini ? startDevHotkeys({
|
|
2556
2714
|
cwd: configService.cwd,
|
|
2557
2715
|
mcpConfig: configService.weappViteConfig?.mcp,
|
|
@@ -2560,115 +2718,20 @@ function registerServeCommand(cli) {
|
|
|
2560
2718
|
silentStartupHint: true
|
|
2561
2719
|
}) : void 0;
|
|
2562
2720
|
try {
|
|
2563
|
-
const
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
mode: configService.mode,
|
|
2570
|
-
isDev: false,
|
|
2571
|
-
configFile,
|
|
2572
|
-
inlineConfig: createInlineConfig(targets.mpPlatform),
|
|
2573
|
-
cliPlatform: targets.rawPlatform,
|
|
2574
|
-
projectConfigPath: options.projectConfig,
|
|
2575
|
-
syncSupportFiles: false
|
|
2576
|
-
}));
|
|
2577
|
-
if (hasAnalyzeData(result)) return {
|
|
2578
|
-
result,
|
|
2579
|
-
durationMs: Date.now() - startedAt,
|
|
2580
|
-
mode: "full"
|
|
2581
|
-
};
|
|
2582
|
-
} catch (error) {
|
|
2583
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
2584
|
-
logger_default.warn(`[ui] 完整分析失败,已回退到 dist 文件扫描:${message}`);
|
|
2585
|
-
return {
|
|
2586
|
-
result: await analyzeUiFallback(ctx),
|
|
2587
|
-
durationMs: Date.now() - startedAt,
|
|
2588
|
-
mode: "fallback",
|
|
2589
|
-
fallbackReason: message
|
|
2590
|
-
};
|
|
2591
|
-
}
|
|
2592
|
-
return {
|
|
2593
|
-
result: await analyzeUiFallback(ctx),
|
|
2594
|
-
durationMs: Date.now() - startedAt,
|
|
2595
|
-
mode: "fallback",
|
|
2596
|
-
fallbackReason: "完整分析结果为空,已回退到 dist 文件扫描。"
|
|
2597
|
-
};
|
|
2598
|
-
};
|
|
2599
|
-
const triggerAnalyzeUpdate = async (reason = "watch") => {
|
|
2600
|
-
if (!analyzeHandle) return;
|
|
2601
|
-
emitDashboardEvents(analyzeHandle, [{
|
|
2602
|
-
kind: reason === "watch" ? "hmr" : "build",
|
|
2603
|
-
level: "info",
|
|
2604
|
-
title: reason === "watch" ? "analyze refresh started" : "initial analyze started",
|
|
2605
|
-
detail: reason === "watch" ? "检测到新的构建结束事件,开始刷新 analyze 面板。" : "开发态 UI 已启动,开始生成第一份 analyze 结果。",
|
|
2606
|
-
tags: reason === "watch" ? ["watch", "analyze"] : ["initial", "analyze"]
|
|
2607
|
-
}]);
|
|
2608
|
-
const next = await runAnalyze();
|
|
2609
|
-
if (next.mode === "fallback") emitDashboardEvents(analyzeHandle, [{
|
|
2610
|
-
kind: "diagnostic",
|
|
2611
|
-
level: "warning",
|
|
2612
|
-
title: "analyze fallback enabled",
|
|
2613
|
-
detail: next.fallbackReason ?? "完整分析不可用,已回退到 dist 文件扫描。",
|
|
2614
|
-
durationMs: next.durationMs,
|
|
2615
|
-
tags: ["analyze", "fallback"]
|
|
2616
|
-
}]);
|
|
2617
|
-
await analyzeHandle.update(next.result);
|
|
2618
|
-
emitDashboardEvents(analyzeHandle, [{
|
|
2619
|
-
kind: next.mode === "fallback" ? "diagnostic" : "build",
|
|
2620
|
-
level: next.mode === "fallback" ? "warning" : "success",
|
|
2621
|
-
title: reason === "watch" ? "analyze refresh completed" : "initial analyze completed",
|
|
2622
|
-
detail: next.mode === "fallback" ? `analyze 已回退到 dist 扫描,当前包含 ${next.result.packages.length} 个包。` : `analyze 已刷新完成,当前包含 ${next.result.packages.length} 个包与 ${next.result.modules.length} 个模块。`,
|
|
2623
|
-
durationMs: next.durationMs,
|
|
2624
|
-
tags: next.mode === "fallback" ? ["analyze", "fallback"] : ["analyze", reason === "watch" ? "refresh" : "initial"]
|
|
2625
|
-
}]);
|
|
2626
|
-
};
|
|
2721
|
+
const analyzeController = createAnalyzeController({
|
|
2722
|
+
configFile,
|
|
2723
|
+
ctx,
|
|
2724
|
+
options,
|
|
2725
|
+
targets
|
|
2726
|
+
});
|
|
2627
2727
|
if (targets.runMini) {
|
|
2628
2728
|
const miniBuildStartedAt = Date.now();
|
|
2629
2729
|
const buildResult = await buildService.build(options);
|
|
2630
2730
|
logger_default.success(`小程序初次构建完成,耗时:${formatDuration(Date.now() - miniBuildStartedAt)}`);
|
|
2631
2731
|
if (enableAnalyze) {
|
|
2632
|
-
|
|
2633
|
-
analyzeHandle =
|
|
2634
|
-
|
|
2635
|
-
cwd: configService.cwd,
|
|
2636
|
-
packageManagerAgent: configService.packageManager.agent,
|
|
2637
|
-
silentStartupLog: true
|
|
2638
|
-
}) ?? void 0;
|
|
2639
|
-
emitDashboardEvents(analyzeHandle, [{
|
|
2640
|
-
kind: "command",
|
|
2641
|
-
level: "success",
|
|
2642
|
-
title: "dev ui session ready",
|
|
2643
|
-
detail: `开发态分析面板已启动,当前包含 ${initialAnalyze.result.packages.length} 个包。`,
|
|
2644
|
-
durationMs: initialAnalyze.durationMs,
|
|
2645
|
-
tags: ["dev", "ui"]
|
|
2646
|
-
}]);
|
|
2647
|
-
if (initialAnalyze.mode === "fallback") emitDashboardEvents(analyzeHandle, [{
|
|
2648
|
-
kind: "diagnostic",
|
|
2649
|
-
level: "warning",
|
|
2650
|
-
title: "initial analyze fallback enabled",
|
|
2651
|
-
detail: initialAnalyze.fallbackReason ?? "完整分析不可用,已回退到 dist 文件扫描。",
|
|
2652
|
-
durationMs: initialAnalyze.durationMs,
|
|
2653
|
-
tags: [
|
|
2654
|
-
"analyze",
|
|
2655
|
-
"fallback",
|
|
2656
|
-
"initial"
|
|
2657
|
-
]
|
|
2658
|
-
}]);
|
|
2659
|
-
let updating = false;
|
|
2660
|
-
if (analyzeHandle && buildResult && typeof buildResult.on === "function") buildResult.on("event", (event) => {
|
|
2661
|
-
if (event.code !== "END" || updating) return;
|
|
2662
|
-
updating = true;
|
|
2663
|
-
triggerAnalyzeUpdate("watch").finally(() => {
|
|
2664
|
-
updating = false;
|
|
2665
|
-
});
|
|
2666
|
-
});
|
|
2667
|
-
if (analyzeHandle) {
|
|
2668
|
-
updating = true;
|
|
2669
|
-
await triggerAnalyzeUpdate("initial");
|
|
2670
|
-
updating = false;
|
|
2671
|
-
}
|
|
2732
|
+
await analyzeController.startDashboard(startAnalyzeDashboard);
|
|
2733
|
+
analyzeHandle = analyzeController.getHandle();
|
|
2734
|
+
await analyzeController.bindWatcher(buildResult).runInitialUpdate();
|
|
2672
2735
|
}
|
|
2673
2736
|
}
|
|
2674
2737
|
let webServer;
|
|
@@ -2677,7 +2740,7 @@ function registerServeCommand(cli) {
|
|
|
2677
2740
|
try {
|
|
2678
2741
|
webServer = await webService?.startDevServer();
|
|
2679
2742
|
logger_default.success(`Web 开发服务启动完成,耗时:${formatDuration(Date.now() - webServerStartedAt)}`);
|
|
2680
|
-
|
|
2743
|
+
analyzeController.emitRuntimeEvents([{
|
|
2681
2744
|
kind: "system",
|
|
2682
2745
|
level: "success",
|
|
2683
2746
|
title: "web dev server started",
|
|
@@ -2686,7 +2749,7 @@ function registerServeCommand(cli) {
|
|
|
2686
2749
|
tags: ["dev", "web"]
|
|
2687
2750
|
}]);
|
|
2688
2751
|
} catch (error) {
|
|
2689
|
-
|
|
2752
|
+
analyzeController.emitRuntimeEvents([{
|
|
2690
2753
|
kind: "diagnostic",
|
|
2691
2754
|
level: "error",
|
|
2692
2755
|
title: "web dev server failed",
|
|
@@ -2706,7 +2769,7 @@ function registerServeCommand(cli) {
|
|
|
2706
2769
|
devHotkeysSession?.restore();
|
|
2707
2770
|
} else if (targets.runWeb) logBuildAppFinish(configService, webServer, { skipMini: true });
|
|
2708
2771
|
if (options.open && targets.runMini) {
|
|
2709
|
-
|
|
2772
|
+
analyzeController.emitRuntimeEvents([{
|
|
2710
2773
|
kind: "command",
|
|
2711
2774
|
level: "info",
|
|
2712
2775
|
title: "opening ide",
|
|
@@ -2721,7 +2784,7 @@ function registerServeCommand(cli) {
|
|
|
2721
2784
|
})) await openIde(configService.platform, resolveIdeProjectRoot(configService.mpDistRoot, configService.cwd), { trustProject: options.trustProject });
|
|
2722
2785
|
devHotkeysSession?.restore();
|
|
2723
2786
|
}
|
|
2724
|
-
if (analyzeHandle) await
|
|
2787
|
+
if (analyzeHandle) await analyzeController.waitForExit();
|
|
2725
2788
|
else if (targets.runMini || targets.runWeb) await waitForServeShutdownSignal();
|
|
2726
2789
|
} finally {
|
|
2727
2790
|
devHotkeysSession?.close();
|