weapp-vite 6.15.13 → 6.15.14
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/README.md +40 -0
- package/dist/auto-import-components/resolvers.mjs +2 -0
- package/dist/auto-routes.mjs +1 -1
- package/dist/cli.mjs +556 -220
- package/dist/{config-DzoHnvv-.d.mts → config-DdiGMnVs.d.mts} +12 -7
- package/dist/config.d.mts +1 -1
- package/dist/config.mjs +3 -3
- package/dist/{createContext-CBnOZ_FN.mjs → createContext-BcX4FNt9.mjs} +336 -14235
- package/dist/docs/README.md +40 -0
- package/dist/{file-CycxGM0E.mjs → file-BR4Z0ErL.mjs} +1 -1
- package/dist/file-DzNGraHL.mjs +2 -0
- package/dist/getInstance-CyAuPueV.mjs +2 -0
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +4 -4
- package/dist/json.d.mts +1 -1
- package/dist/json.mjs +1 -1
- package/dist/mcp.d.mts +1 -1
- package/dist/types.d.mts +1 -1
- package/package.json +13 -13
- package/dist/file-BbtjekFm.mjs +0 -2
- package/dist/getInstance-BN1eXe7O.mjs +0 -2
- /package/dist/{config-B2xtjEug.mjs → config-DJjSbpNX.mjs} +0 -0
- /package/dist/{json-wnfVS9jE.mjs → json-D0HkutE0.mjs} +0 -0
- /package/dist/{pluginHost-BzPJL4F-.mjs → pluginHost-SJdl15d3.mjs} +0 -0
package/dist/cli.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
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-BcX4FNt9.mjs";
|
|
2
2
|
import { r as logger_default, t as colors } from "./logger-CgxdNjvb.mjs";
|
|
3
|
-
import { h as VERSION } from "./file-
|
|
3
|
+
import { h as VERSION } from "./file-BR4Z0ErL.mjs";
|
|
4
4
|
import { a as resolveWeappMcpConfig, o as startWeappViteMcpServer } from "./mcp-DRlj32v4.mjs";
|
|
5
5
|
import { createRequire } from "node:module";
|
|
6
6
|
import path, { posix } from "pathe";
|
|
@@ -15,14 +15,13 @@ import { execFile } from "node:child_process";
|
|
|
15
15
|
import { Buffer } from "node:buffer";
|
|
16
16
|
import { cac } from "cac";
|
|
17
17
|
import { resolveCommand } from "package-manager-detector/commands";
|
|
18
|
+
import { RETRY_CANCEL_KEYS, RETRY_CONFIRM_KEYS, bootstrapWechatDevtoolsSettings, buildWechatIdeNpm, clearWechatIdeCache, clearWechatIdeCacheByAutomator, closeSharedMiniProgram, closeWechatIdeProject, compileWechatIdeByAutomator, connectOpenedAutomator, createSharedInputSession, dispatchWechatCliCommand, formatAutomatorLoginError, getConfig, getWechatIdeTestAccounts, getWechatIdeTicket, getWechatIdeToolInfo, isAutomatorLoginError, isWeappIdeTopLevelCommand, isWechatIdeLoginRequiredError, launchAutomator, openWechatIdeProjectByHttp, parse, promptRetryKeypress, promptWechatIdeLoginRetry, quitWechatIde, refreshWechatIdeTicket, resetWechatIdeFileUtilsByHttp, runRetryableCommand, runWechatIdeEngineBuild, runWithSuspendedSharedInput, setWechatIdeTicket, startForwardConsole, takeScreenshot } from "weapp-ide-cli";
|
|
18
19
|
import { promisify } from "node:util";
|
|
19
|
-
import { bootstrapWechatDevtoolsSettings, closeSharedMiniProgram, connectOpenedAutomator, formatAutomatorLoginError, formatRetryHotkeyPrompt, formatWechatIdeLoginRequiredError, getConfig, isAutomatorLoginError, isWeappIdeTopLevelCommand, isWechatIdeLoginRequiredError, launchAutomator, parse, startForwardConsole, takeScreenshot, waitForRetryKeypress } from "weapp-ide-cli";
|
|
20
20
|
import { generateJs, generateJson, generateWxml, generateWxss } from "@weapp-core/schematics";
|
|
21
21
|
import { determineAgent } from "@vercel/detect-agent";
|
|
22
22
|
import { initConfig } from "@weapp-core/init";
|
|
23
23
|
import { createInterface } from "node:readline/promises";
|
|
24
24
|
import { clearTimeout, setTimeout as setTimeout$1 } from "node:timers";
|
|
25
|
-
import { emitKeypressEvents } from "node:readline";
|
|
26
25
|
//#region src/analyze/subpackages/classifier.ts
|
|
27
26
|
const VIRTUAL_MODULE_INDICATOR = "\0";
|
|
28
27
|
const VIRTUAL_PREFIX = `${SHARED_CHUNK_VIRTUAL_PREFIX}/`;
|
|
@@ -952,42 +951,133 @@ function logBuildPackageSizeReport(options) {
|
|
|
952
951
|
}
|
|
953
952
|
}
|
|
954
953
|
//#endregion
|
|
955
|
-
//#region src/cli/openIde.ts
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
954
|
+
//#region src/cli/openIde/execute.ts
|
|
955
|
+
function readArgOption(argv, ...names) {
|
|
956
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
957
|
+
const current = argv[index];
|
|
958
|
+
if (!names.includes(current)) continue;
|
|
959
|
+
const next = argv[index + 1];
|
|
960
|
+
if (typeof next === "string" && !next.startsWith("-")) return next;
|
|
961
|
+
}
|
|
960
962
|
}
|
|
961
|
-
async function
|
|
962
|
-
(
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
963
|
+
async function tryExecuteWechatIdeCliCommandByAutomator(argv, projectPath) {
|
|
964
|
+
if (!projectPath) return false;
|
|
965
|
+
const command = argv[0];
|
|
966
|
+
if (!command) return false;
|
|
967
|
+
if (command === "compile") {
|
|
968
|
+
await compileWechatIdeByAutomator({ projectPath });
|
|
969
|
+
return true;
|
|
970
|
+
}
|
|
971
|
+
if (command === "cache") {
|
|
972
|
+
const cleanType = readArgOption(argv, "--clean", "-c");
|
|
973
|
+
if (cleanType !== "compile" && cleanType !== "all") return false;
|
|
974
|
+
await clearWechatIdeCacheByAutomator({
|
|
975
|
+
clean: cleanType,
|
|
976
|
+
projectPath
|
|
977
|
+
});
|
|
978
|
+
return true;
|
|
979
|
+
}
|
|
980
|
+
return false;
|
|
981
|
+
}
|
|
982
|
+
async function tryExecuteWechatIdeCliCommandByHttp(argv, projectPath) {
|
|
983
|
+
const command = argv[0];
|
|
984
|
+
if (!command) return false;
|
|
985
|
+
if (command === "compile") {
|
|
986
|
+
if (!projectPath) return false;
|
|
987
|
+
await openWechatIdeProjectByHttp(projectPath);
|
|
988
|
+
return true;
|
|
989
|
+
}
|
|
990
|
+
if (command === "reset-fileutils") {
|
|
991
|
+
if (!projectPath) return false;
|
|
992
|
+
await resetWechatIdeFileUtilsByHttp(projectPath);
|
|
993
|
+
return true;
|
|
994
|
+
}
|
|
995
|
+
if (command === "engine" && argv[1] === "build") {
|
|
996
|
+
const engineProjectPath = argv[2] || projectPath;
|
|
997
|
+
if (!engineProjectPath) return false;
|
|
998
|
+
await runWechatIdeEngineBuild(engineProjectPath, { logPath: readArgOption(argv, "--logPath", "-l") });
|
|
999
|
+
return true;
|
|
1000
|
+
}
|
|
1001
|
+
return false;
|
|
1002
|
+
}
|
|
1003
|
+
async function tryExecuteWechatIdeCliCommandByHelper(argv) {
|
|
1004
|
+
const command = argv[0];
|
|
1005
|
+
if (!command) return false;
|
|
1006
|
+
if (command === "close") {
|
|
1007
|
+
await closeWechatIdeProject();
|
|
1008
|
+
return true;
|
|
1009
|
+
}
|
|
1010
|
+
if (command === "quit") {
|
|
1011
|
+
await quitWechatIde();
|
|
1012
|
+
return true;
|
|
1013
|
+
}
|
|
1014
|
+
if (command === "cache") {
|
|
1015
|
+
const cleanType = readArgOption(argv, "--clean", "-c");
|
|
1016
|
+
if (!cleanType) return false;
|
|
1017
|
+
await clearWechatIdeCache({ clean: cleanType });
|
|
1018
|
+
return true;
|
|
1019
|
+
}
|
|
1020
|
+
return false;
|
|
966
1021
|
}
|
|
967
1022
|
/**
|
|
968
|
-
* @description
|
|
1023
|
+
* @description 统一执行 weapp-ide-cli 命令,并在登录失效时复用同一套重试交互。
|
|
969
1024
|
*/
|
|
970
|
-
async function
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
logger_default.error(error);
|
|
978
|
-
return;
|
|
1025
|
+
async function executeWechatIdeCliCommand(argv, options = {}) {
|
|
1026
|
+
const { automatorMode = "prefer", cancelLevel = "warn", httpMode = "prefer", onNonLoginError, onRetry, projectPath } = options;
|
|
1027
|
+
await runWithSuspendedSharedInput(async () => {
|
|
1028
|
+
try {
|
|
1029
|
+
if (await tryExecuteWechatIdeCliCommandByHttp(argv, projectPath)) return;
|
|
1030
|
+
} catch (error) {
|
|
1031
|
+
if (httpMode === "require") throw error;
|
|
979
1032
|
}
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
logger_default.warn("已取消重试。完成登录后请重新执行当前命令。");
|
|
985
|
-
retrying = false;
|
|
986
|
-
continue;
|
|
1033
|
+
try {
|
|
1034
|
+
if (await tryExecuteWechatIdeCliCommandByAutomator(argv, projectPath)) return;
|
|
1035
|
+
} catch (error) {
|
|
1036
|
+
if (automatorMode === "require") throw error;
|
|
987
1037
|
}
|
|
988
|
-
|
|
989
|
-
|
|
1038
|
+
try {
|
|
1039
|
+
if (await tryExecuteWechatIdeCliCommandByHelper(argv)) return;
|
|
1040
|
+
} catch (error) {
|
|
1041
|
+
if (onNonLoginError) {
|
|
1042
|
+
onNonLoginError(error);
|
|
1043
|
+
return;
|
|
1044
|
+
}
|
|
1045
|
+
throw error;
|
|
1046
|
+
}
|
|
1047
|
+
await runRetryableCommand({
|
|
1048
|
+
createCancelError: () => /* @__PURE__ */ new Error("cancelled"),
|
|
1049
|
+
execute: async () => {
|
|
1050
|
+
try {
|
|
1051
|
+
await parse(argv);
|
|
1052
|
+
return null;
|
|
1053
|
+
} catch (error) {
|
|
1054
|
+
if (!isWechatIdeLoginRequiredError(error)) {
|
|
1055
|
+
if (onNonLoginError) {
|
|
1056
|
+
onNonLoginError(error);
|
|
1057
|
+
return null;
|
|
1058
|
+
}
|
|
1059
|
+
throw error;
|
|
1060
|
+
}
|
|
1061
|
+
return error;
|
|
1062
|
+
}
|
|
1063
|
+
},
|
|
1064
|
+
isRetryableResult: (result) => result !== null,
|
|
1065
|
+
onCancel: () => {},
|
|
1066
|
+
onRetry: () => {
|
|
1067
|
+
onRetry?.();
|
|
1068
|
+
},
|
|
1069
|
+
promptRetry: async (error) => await promptWechatIdeLoginRetry({
|
|
1070
|
+
cancelLevel,
|
|
1071
|
+
error,
|
|
1072
|
+
logger: logger_default
|
|
1073
|
+
}),
|
|
1074
|
+
shouldRetry: (action) => action === "retry"
|
|
1075
|
+
});
|
|
1076
|
+
});
|
|
990
1077
|
}
|
|
1078
|
+
//#endregion
|
|
1079
|
+
//#region src/cli/openIde/close.ts
|
|
1080
|
+
const execFileAsync = promisify(execFile);
|
|
991
1081
|
async function closeIdeByAppleScript() {
|
|
992
1082
|
if (process.platform !== "darwin") return false;
|
|
993
1083
|
const appName = process.env.WEAPP_DEVTOOLS_APP_NAME || "wechatwebdevtools";
|
|
@@ -1009,29 +1099,21 @@ async function closeIdeByProcessKill(cliPath) {
|
|
|
1009
1099
|
}
|
|
1010
1100
|
}
|
|
1011
1101
|
/**
|
|
1012
|
-
* @description
|
|
1013
|
-
*/
|
|
1014
|
-
function resolveIdeProjectPath(mpDistRoot) {
|
|
1015
|
-
if (!mpDistRoot || !mpDistRoot.trim()) return;
|
|
1016
|
-
const parent = path.dirname(mpDistRoot);
|
|
1017
|
-
if (!parent || parent === "." || parent === "/") return;
|
|
1018
|
-
return parent;
|
|
1019
|
-
}
|
|
1020
|
-
/**
|
|
1021
|
-
* @description 结合 mpDistRoot 与配置根目录解析最终 IDE 项目目录。
|
|
1102
|
+
* @description 关闭微信开发者工具,并在 CLI 不可用时回退到系统级关闭。
|
|
1022
1103
|
*/
|
|
1023
|
-
function
|
|
1024
|
-
return resolveIdeProjectPath(mpDistRoot) ?? cwd;
|
|
1025
|
-
}
|
|
1026
|
-
async function closeIde() {
|
|
1104
|
+
async function closeIde$1() {
|
|
1027
1105
|
const config = await getConfig();
|
|
1028
1106
|
const cliPath = config.cliPath?.trim() ? config.cliPath : null;
|
|
1029
1107
|
try {
|
|
1030
|
-
await
|
|
1108
|
+
await closeWechatIdeProject();
|
|
1031
1109
|
return true;
|
|
1032
1110
|
} catch (error) {
|
|
1033
1111
|
if (isWechatIdeLoginRequiredError(error)) try {
|
|
1034
|
-
await
|
|
1112
|
+
await executeWechatIdeCliCommand(["close"], {
|
|
1113
|
+
cancelLevel: "warn",
|
|
1114
|
+
onNonLoginError: (retryError) => logger_default.error(retryError),
|
|
1115
|
+
onRetry: () => logger_default.info("正在重试连接微信开发者工具...")
|
|
1116
|
+
});
|
|
1035
1117
|
return true;
|
|
1036
1118
|
} catch (retryError) {
|
|
1037
1119
|
logger_default.error(retryError);
|
|
@@ -1051,25 +1133,36 @@ async function closeIde() {
|
|
|
1051
1133
|
return false;
|
|
1052
1134
|
}
|
|
1053
1135
|
}
|
|
1136
|
+
//#endregion
|
|
1137
|
+
//#region src/cli/openIde/reuse.ts
|
|
1054
1138
|
function formatReuseOpenedWechatIdePrompt() {
|
|
1055
1139
|
return `目标项目已在微信开发者工具中打开,已跳过重复打开。按 ${colors.bold(colors.green("r"))} 关闭当前窗口后重新打开。`;
|
|
1056
1140
|
}
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1141
|
+
async function openWechatIdeByAutomator(projectPath) {
|
|
1142
|
+
(await launchAutomator({
|
|
1143
|
+
projectPath,
|
|
1144
|
+
trustProject: true
|
|
1145
|
+
})).disconnect();
|
|
1146
|
+
}
|
|
1147
|
+
async function connectOpenedProject(projectPath) {
|
|
1062
1148
|
try {
|
|
1063
|
-
|
|
1149
|
+
return await connectOpenedAutomator({
|
|
1064
1150
|
projectPath,
|
|
1065
1151
|
timeout: 3e3
|
|
1066
1152
|
});
|
|
1067
1153
|
} catch {
|
|
1068
1154
|
return null;
|
|
1069
1155
|
}
|
|
1156
|
+
}
|
|
1157
|
+
/**
|
|
1158
|
+
* @description 若当前项目已在微信开发者工具中打开且自动化可连通,则直接复用现有会话,避免重复拉起 IDE。
|
|
1159
|
+
*/
|
|
1160
|
+
async function tryReuseOpenedWechatIde(projectPath, closeIde) {
|
|
1161
|
+
const miniProgram = await connectOpenedProject(projectPath);
|
|
1162
|
+
if (!miniProgram) return null;
|
|
1070
1163
|
miniProgram.disconnect();
|
|
1071
1164
|
logger_default.info(formatReuseOpenedWechatIdePrompt());
|
|
1072
|
-
if (await
|
|
1165
|
+
if (await promptRetryKeypress({ logger: logger_default }) !== "retry") return {
|
|
1073
1166
|
reopened: false,
|
|
1074
1167
|
reused: true
|
|
1075
1168
|
};
|
|
@@ -1081,22 +1174,70 @@ async function tryReuseOpenedWechatIde(projectPath) {
|
|
|
1081
1174
|
reused: false
|
|
1082
1175
|
};
|
|
1083
1176
|
}
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
});
|
|
1091
|
-
} catch {
|
|
1092
|
-
return false;
|
|
1093
|
-
}
|
|
1177
|
+
/**
|
|
1178
|
+
* @description 对已打开的目标项目执行强制重开,以刷新最新构建产物。
|
|
1179
|
+
*/
|
|
1180
|
+
async function reopenOpenedWechatIde(projectPath, closeIde) {
|
|
1181
|
+
const miniProgram = await connectOpenedProject(projectPath);
|
|
1182
|
+
if (!miniProgram) return false;
|
|
1094
1183
|
miniProgram.disconnect();
|
|
1095
1184
|
logger_default.info("目标项目已在微信开发者工具中打开,当前命令将主动重开以刷新最新构建产物。");
|
|
1096
1185
|
if (!await closeIde()) logger_default.warn("关闭当前微信开发者工具失败,仍继续尝试重新打开目标项目。");
|
|
1097
1186
|
await openWechatIdeByAutomator(projectPath);
|
|
1098
1187
|
return true;
|
|
1099
1188
|
}
|
|
1189
|
+
//#endregion
|
|
1190
|
+
//#region src/cli/openIde/index.ts
|
|
1191
|
+
function shouldLogAutomatorFallbackError() {
|
|
1192
|
+
const flag = process.env.WEAPP_VITE_DEBUG_AUTOMATOR_OPEN;
|
|
1193
|
+
return flag === "1" || flag === "true";
|
|
1194
|
+
}
|
|
1195
|
+
/**
|
|
1196
|
+
* @description 执行 IDE 打开流程,并在登录失效时允许按键重试。
|
|
1197
|
+
*/
|
|
1198
|
+
async function runWechatIdeOpenWithRetry(argv) {
|
|
1199
|
+
await executeWechatIdeCliCommand(argv, {
|
|
1200
|
+
cancelLevel: "warn",
|
|
1201
|
+
onNonLoginError: (error) => logger_default.error(error),
|
|
1202
|
+
onRetry: () => {
|
|
1203
|
+
logger_default.info(colors.bold(colors.green("正在重试连接微信开发者工具...")));
|
|
1204
|
+
}
|
|
1205
|
+
});
|
|
1206
|
+
}
|
|
1207
|
+
/**
|
|
1208
|
+
* @description 根据 mpDistRoot 推导 IDE 项目目录(目录内应包含 project/mini 配置)
|
|
1209
|
+
*/
|
|
1210
|
+
function resolveIdeProjectPath(mpDistRoot) {
|
|
1211
|
+
if (!mpDistRoot || !mpDistRoot.trim()) return;
|
|
1212
|
+
const parent = path.dirname(mpDistRoot);
|
|
1213
|
+
if (!parent || parent === "." || parent === "/") return;
|
|
1214
|
+
return parent;
|
|
1215
|
+
}
|
|
1216
|
+
/**
|
|
1217
|
+
* @description 结合 mpDistRoot 与配置根目录解析最终 IDE 项目目录。
|
|
1218
|
+
*/
|
|
1219
|
+
function resolveIdeProjectRoot(mpDistRoot, cwd) {
|
|
1220
|
+
return resolveIdeProjectPath(mpDistRoot) ?? cwd;
|
|
1221
|
+
}
|
|
1222
|
+
async function closeIde() {
|
|
1223
|
+
return await closeIde$1();
|
|
1224
|
+
}
|
|
1225
|
+
async function tryOpenWechatIdeByAutomator(projectPath, options) {
|
|
1226
|
+
if (options.reuseOpenedProject === false) {
|
|
1227
|
+
if (await reopenOpenedWechatIde(projectPath, closeIde)) return true;
|
|
1228
|
+
}
|
|
1229
|
+
const reuseResult = await tryReuseOpenedWechatIde(projectPath, closeIde);
|
|
1230
|
+
if (reuseResult?.reused || reuseResult?.reopened) return true;
|
|
1231
|
+
await openWechatIdeByAutomator(projectPath);
|
|
1232
|
+
return true;
|
|
1233
|
+
}
|
|
1234
|
+
function createIdeOpenArgv(platform, projectPath, options = {}) {
|
|
1235
|
+
const argv = ["open", "-p"];
|
|
1236
|
+
if (projectPath) argv.push(projectPath);
|
|
1237
|
+
if (platform === "weapp" && options.trustProject !== false) argv.push("--trust-project");
|
|
1238
|
+
if (platform && shouldPassPlatformArgToIdeOpen(platform)) argv.push("--platform", platform);
|
|
1239
|
+
return argv;
|
|
1240
|
+
}
|
|
1100
1241
|
async function openIde(platform, projectPath, options = {}) {
|
|
1101
1242
|
let bootstrapResult;
|
|
1102
1243
|
if (platform === "weapp" && projectPath) try {
|
|
@@ -1110,13 +1251,7 @@ async function openIde(platform, projectPath, options = {}) {
|
|
|
1110
1251
|
}
|
|
1111
1252
|
if (platform === "weapp" && projectPath && bootstrapResult?.servicePortEnabled === false) logger_default.warn("检测到微信开发者工具服务端口当前处于关闭状态,已保留用户设置并回退到普通 open 流程。");
|
|
1112
1253
|
if (platform === "weapp" && projectPath && options.trustProject !== false && bootstrapResult?.servicePortEnabled !== false) try {
|
|
1113
|
-
if (
|
|
1114
|
-
if (await reopenOpenedWechatIde(projectPath)) return;
|
|
1115
|
-
}
|
|
1116
|
-
const reuseResult = await tryReuseOpenedWechatIde(projectPath);
|
|
1117
|
-
if (reuseResult?.reused || reuseResult?.reopened) return;
|
|
1118
|
-
await openWechatIdeByAutomator(projectPath);
|
|
1119
|
-
return;
|
|
1254
|
+
if (await tryOpenWechatIdeByAutomator(projectPath, options)) return;
|
|
1120
1255
|
} catch (error) {
|
|
1121
1256
|
if (isAutomatorLoginError(error)) {
|
|
1122
1257
|
logger_default.error("检测到微信开发者工具登录状态失效,请先登录后重试。");
|
|
@@ -1125,11 +1260,7 @@ async function openIde(platform, projectPath, options = {}) {
|
|
|
1125
1260
|
logger_default.warn("通过 automator 启动微信开发者工具并自动信任项目失败,回退到普通 open 流程。");
|
|
1126
1261
|
if (shouldLogAutomatorFallbackError()) logger_default.error(error);
|
|
1127
1262
|
}
|
|
1128
|
-
|
|
1129
|
-
if (projectPath) argv.push(projectPath);
|
|
1130
|
-
if (platform === "weapp" && options.trustProject !== false) argv.push("--trust-project");
|
|
1131
|
-
if (platform && shouldPassPlatformArgToIdeOpen(platform)) argv.push("--platform", platform);
|
|
1132
|
-
await runWechatIdeOpenWithRetry(argv);
|
|
1263
|
+
await runWechatIdeOpenWithRetry(createIdeOpenArgv(platform, projectPath, options));
|
|
1133
1264
|
}
|
|
1134
1265
|
/**
|
|
1135
1266
|
* @description 解析 IDE 相关命令所需的平台、项目目录与配置上下文。
|
|
@@ -1608,11 +1739,15 @@ async function waitForTermination(cleanup) {
|
|
|
1608
1739
|
}
|
|
1609
1740
|
});
|
|
1610
1741
|
}
|
|
1742
|
+
function formatIdeOutput(data, options) {
|
|
1743
|
+
if (options.json) return JSON.stringify(data, null, 2);
|
|
1744
|
+
return JSON.stringify(data, null, 2);
|
|
1745
|
+
}
|
|
1611
1746
|
/**
|
|
1612
1747
|
* @description 执行 ide 子命令。
|
|
1613
1748
|
*/
|
|
1614
1749
|
async function runIdeCommand(action, root, options) {
|
|
1615
|
-
if (action !== "logs" && action !== "setup") throw new Error(`未知 ide 子命令: ${action ?? "(empty)"}`);
|
|
1750
|
+
if (action !== "logs" && action !== "setup" && action !== "info" && action !== "test-accounts" && action !== "ticket" && action !== "ticket:set" && action !== "ticket:refresh") throw new Error(`未知 ide 子命令: ${action ?? "(empty)"}`);
|
|
1616
1751
|
filterDuplicateOptions(options);
|
|
1617
1752
|
const configFile = resolveConfigFile(options);
|
|
1618
1753
|
const targets = resolveRuntimeTargets(options);
|
|
@@ -1634,6 +1769,35 @@ async function runIdeCommand(action, root, options) {
|
|
|
1634
1769
|
return;
|
|
1635
1770
|
}
|
|
1636
1771
|
if (options.open) await openIde(resolved.platform, resolved.projectPath, { trustProject: options.trustProject });
|
|
1772
|
+
if (action === "info") {
|
|
1773
|
+
const result = await getWechatIdeToolInfo({ projectPath: resolved.projectPath });
|
|
1774
|
+
logger_default.info(formatIdeOutput(result, options));
|
|
1775
|
+
return;
|
|
1776
|
+
}
|
|
1777
|
+
if (action === "test-accounts") {
|
|
1778
|
+
const result = await getWechatIdeTestAccounts({ projectPath: resolved.projectPath });
|
|
1779
|
+
logger_default.info(formatIdeOutput(result, options));
|
|
1780
|
+
return;
|
|
1781
|
+
}
|
|
1782
|
+
if (action === "ticket") {
|
|
1783
|
+
const result = await getWechatIdeTicket({ projectPath: resolved.projectPath });
|
|
1784
|
+
logger_default.info(formatIdeOutput(result, options));
|
|
1785
|
+
return;
|
|
1786
|
+
}
|
|
1787
|
+
if (action === "ticket:set") {
|
|
1788
|
+
if (!options.ticket) throw new Error("`weapp-vite ide ticket:set` 需要提供 --ticket。");
|
|
1789
|
+
await setWechatIdeTicket({
|
|
1790
|
+
projectPath: resolved.projectPath,
|
|
1791
|
+
ticket: options.ticket
|
|
1792
|
+
});
|
|
1793
|
+
logger_default.info(`已设置微信开发者工具 ticket:${options.ticket}`);
|
|
1794
|
+
return;
|
|
1795
|
+
}
|
|
1796
|
+
if (action === "ticket:refresh") {
|
|
1797
|
+
await refreshWechatIdeTicket({ projectPath: resolved.projectPath });
|
|
1798
|
+
logger_default.info("已刷新微信开发者工具 ticket。");
|
|
1799
|
+
return;
|
|
1800
|
+
}
|
|
1637
1801
|
const forwardConsoleOptions = await resolveForwardConsoleOptions({
|
|
1638
1802
|
...resolved.weappViteConfig,
|
|
1639
1803
|
forwardConsole: resolved.weappViteConfig?.forwardConsole === false ? { enabled: true } : {
|
|
@@ -1657,7 +1821,7 @@ async function runIdeCommand(action, root, options) {
|
|
|
1657
1821
|
* @description 注册 IDE 相关子命令。
|
|
1658
1822
|
*/
|
|
1659
1823
|
function registerIdeCommand(cli) {
|
|
1660
|
-
cli.command("ide [action] [root]", "
|
|
1824
|
+
cli.command("ide [action] [root]", "run Wechat DevTools utility actions and log bridge commands").option("-o, --open", "[boolean] open ide before attaching log bridge").option("-p, --platform <platform>", "[string] target platform (weapp | h5)").option("--project-config <path>", "[string] project config path (miniprogram only)").option("--ticket <value>", "[string] ticket used by `ide ticket:set`").option("--trust-project", "[boolean] auto trust Wechat DevTools project on open", { default: true }).action(async (action, root, options) => {
|
|
1661
1825
|
await runIdeCommand(action, root, options);
|
|
1662
1826
|
});
|
|
1663
1827
|
}
|
|
@@ -1979,16 +2143,18 @@ async function resolveHttpUrl(options) {
|
|
|
1979
2143
|
}
|
|
1980
2144
|
async function confirmWrite() {
|
|
1981
2145
|
if (!process.stdin.isTTY || !process.stdout.isTTY) return false;
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
2146
|
+
return await runWithSuspendedSharedInput(async () => {
|
|
2147
|
+
const rl = createInterface({
|
|
2148
|
+
input: process.stdin,
|
|
2149
|
+
output: process.stdout
|
|
2150
|
+
});
|
|
2151
|
+
try {
|
|
2152
|
+
const normalized = (await rl.question("是否写入配置文件?(Y/n) ")).trim().toLowerCase();
|
|
2153
|
+
return normalized === "" || normalized === "y" || normalized === "yes";
|
|
2154
|
+
} finally {
|
|
2155
|
+
rl.close();
|
|
2156
|
+
}
|
|
1985
2157
|
});
|
|
1986
|
-
try {
|
|
1987
|
-
const normalized = (await rl.question("是否写入配置文件?(Y/n) ")).trim().toLowerCase();
|
|
1988
|
-
return normalized === "" || normalized === "y" || normalized === "yes";
|
|
1989
|
-
} finally {
|
|
1990
|
-
rl.close();
|
|
1991
|
-
}
|
|
1992
2158
|
}
|
|
1993
2159
|
function resolveClientTransport(transport) {
|
|
1994
2160
|
return transport === "http" ? "http" : "command";
|
|
@@ -2072,7 +2238,7 @@ function registerMcpCommand(cli) {
|
|
|
2072
2238
|
function registerNpmCommand(cli) {
|
|
2073
2239
|
cli.command("npm").alias("build:npm").alias("build-npm").action(async () => {
|
|
2074
2240
|
try {
|
|
2075
|
-
await
|
|
2241
|
+
await buildWechatIdeNpm({ projectPath: process.cwd() });
|
|
2076
2242
|
} catch (error) {
|
|
2077
2243
|
logger_default.error(error);
|
|
2078
2244
|
}
|
|
@@ -2114,6 +2280,7 @@ function registerPrepareCommand(cli) {
|
|
|
2114
2280
|
isDev: false,
|
|
2115
2281
|
mode: typeof options.mode === "string" ? options.mode : "development",
|
|
2116
2282
|
configFile: resolveConfigFile(options),
|
|
2283
|
+
configLoader: "native",
|
|
2117
2284
|
syncSupportFiles: false,
|
|
2118
2285
|
preloadAppEntry: false
|
|
2119
2286
|
}));
|
|
@@ -2124,8 +2291,208 @@ function registerPrepareCommand(cli) {
|
|
|
2124
2291
|
});
|
|
2125
2292
|
}
|
|
2126
2293
|
//#endregion
|
|
2294
|
+
//#region src/cli/devHotkeys/devtools.ts
|
|
2295
|
+
/**
|
|
2296
|
+
* @description 重置当前 DevTools automator 共享会话。
|
|
2297
|
+
*/
|
|
2298
|
+
async function runResetDevtoolsSessionAction(options) {
|
|
2299
|
+
logger_default.info("[dev action] 正在重置当前 DevTools 会话...");
|
|
2300
|
+
await closeSharedMiniProgram(options.projectPath);
|
|
2301
|
+
logger_default.success("[dev action] 当前 DevTools 会话已重置。");
|
|
2302
|
+
return "已重置当前 DevTools 会话";
|
|
2303
|
+
}
|
|
2304
|
+
/**
|
|
2305
|
+
* @description 重置共享会话并重开当前项目,以恢复 DevTools 状态。
|
|
2306
|
+
*/
|
|
2307
|
+
async function runResetAndReopenDevtoolsAction(options) {
|
|
2308
|
+
if (!options.openIde) {
|
|
2309
|
+
logger_default.warn("[dev action] 当前 dev 会话未提供重新打开微信开发者工具的能力。");
|
|
2310
|
+
return "重置并重开微信开发者工具不可用";
|
|
2311
|
+
}
|
|
2312
|
+
logger_default.info("[dev action] 正在重置当前 DevTools 会话并重开项目...");
|
|
2313
|
+
await closeSharedMiniProgram(options.projectPath);
|
|
2314
|
+
const summary = await options.openIde();
|
|
2315
|
+
logger_default.success("[dev action] 当前 DevTools 会话已重置,并已重新打开项目。");
|
|
2316
|
+
return summary ?? "已重置当前 DevTools 会话并重新打开项目";
|
|
2317
|
+
}
|
|
2318
|
+
/**
|
|
2319
|
+
* @description 手动触发一次当前小程序 dev 重新构建。
|
|
2320
|
+
*/
|
|
2321
|
+
async function runDevRebuildAction(options) {
|
|
2322
|
+
if (!options.rebuild) {
|
|
2323
|
+
logger_default.warn("[dev action] 当前 dev 会话未提供手动重新构建能力。");
|
|
2324
|
+
return "手动重新构建不可用";
|
|
2325
|
+
}
|
|
2326
|
+
logger_default.info("[dev action] 正在手动重新构建当前小程序产物...");
|
|
2327
|
+
const summary = await options.rebuild();
|
|
2328
|
+
logger_default.success("[dev action] 当前小程序产物已手动重新构建。");
|
|
2329
|
+
return summary ?? "已手动重新构建当前小程序产物";
|
|
2330
|
+
}
|
|
2331
|
+
/**
|
|
2332
|
+
* @description 重新打开当前微信开发者工具项目,并主动清理共享 automator 会话。
|
|
2333
|
+
*/
|
|
2334
|
+
async function runOpenIdeAction(options) {
|
|
2335
|
+
if (!options.openIde) {
|
|
2336
|
+
logger_default.warn("[dev action] 当前 dev 会话未提供重新打开微信开发者工具的能力。");
|
|
2337
|
+
return "重新打开微信开发者工具不可用";
|
|
2338
|
+
}
|
|
2339
|
+
logger_default.info(`[dev action] 正在重新打开微信开发者工具项目:${colors.cyan(options.projectPath)}`);
|
|
2340
|
+
await closeSharedMiniProgram(options.projectPath);
|
|
2341
|
+
const summary = await options.openIde();
|
|
2342
|
+
logger_default.success("[dev action] 微信开发者工具项目已重新打开。");
|
|
2343
|
+
return summary ?? "已重新打开微信开发者工具项目";
|
|
2344
|
+
}
|
|
2345
|
+
//#endregion
|
|
2346
|
+
//#region src/cli/devHotkeys/screenshot.ts
|
|
2347
|
+
const DEV_SCREENSHOT_DIR = ".weapp-vite/dev-screenshots";
|
|
2348
|
+
const DEFAULT_SCREENSHOT_TIMEOUT = 3e4;
|
|
2349
|
+
/**
|
|
2350
|
+
* @description 生成开发态截图输出路径。
|
|
2351
|
+
*/
|
|
2352
|
+
function resolveDevScreenshotOutputPath(cwd, now = /* @__PURE__ */ new Date()) {
|
|
2353
|
+
const stamp = now.toISOString().replace(/[:.]/g, "-");
|
|
2354
|
+
return path.join(cwd, DEV_SCREENSHOT_DIR, `screenshot-${stamp}.png`);
|
|
2355
|
+
}
|
|
2356
|
+
function formatLogPath(cwd, targetPath) {
|
|
2357
|
+
const relativePath = path.relative(cwd, targetPath);
|
|
2358
|
+
if (!relativePath || relativePath.startsWith("..")) return targetPath;
|
|
2359
|
+
return relativePath;
|
|
2360
|
+
}
|
|
2361
|
+
function formatResolvedScreenshotPath(cwd, fallbackPath, result) {
|
|
2362
|
+
return formatLogPath(cwd, result.path ?? fallbackPath);
|
|
2363
|
+
}
|
|
2364
|
+
/**
|
|
2365
|
+
* @description 执行当前页面截图并输出结果日志。
|
|
2366
|
+
*/
|
|
2367
|
+
async function runScreenshotAction(options) {
|
|
2368
|
+
const outputPath = resolveDevScreenshotOutputPath(options.cwd);
|
|
2369
|
+
await fs$2.mkdir(path.dirname(outputPath), { recursive: true });
|
|
2370
|
+
logger_default.info(`[dev action] 正在截图当前页面,输出到 ${colors.cyan(formatLogPath(options.cwd, outputPath))}`);
|
|
2371
|
+
const result = await takeScreenshot({
|
|
2372
|
+
fullPage: true,
|
|
2373
|
+
projectPath: options.projectPath,
|
|
2374
|
+
sharedSession: true,
|
|
2375
|
+
outputPath,
|
|
2376
|
+
timeout: DEFAULT_SCREENSHOT_TIMEOUT
|
|
2377
|
+
});
|
|
2378
|
+
const resolvedPath = formatResolvedScreenshotPath(options.cwd, outputPath, result);
|
|
2379
|
+
logger_default.success(`[dev action] 当前页面截图完成:${colors.cyan(resolvedPath)}`);
|
|
2380
|
+
return resolvedPath;
|
|
2381
|
+
}
|
|
2382
|
+
//#endregion
|
|
2383
|
+
//#region src/cli/devHotkeys/actions.ts
|
|
2384
|
+
const DEV_HOTKEY_GROUPS = [
|
|
2385
|
+
{
|
|
2386
|
+
key: "development",
|
|
2387
|
+
title: "开发动作"
|
|
2388
|
+
},
|
|
2389
|
+
{
|
|
2390
|
+
key: "devtools",
|
|
2391
|
+
title: "会话动作"
|
|
2392
|
+
},
|
|
2393
|
+
{
|
|
2394
|
+
key: "process",
|
|
2395
|
+
title: "进程控制"
|
|
2396
|
+
},
|
|
2397
|
+
{
|
|
2398
|
+
key: "help",
|
|
2399
|
+
title: "帮助"
|
|
2400
|
+
}
|
|
2401
|
+
];
|
|
2402
|
+
const DEV_HOTKEY_DEFINITIONS = [
|
|
2403
|
+
{
|
|
2404
|
+
description: "截图当前页面并保存到本地",
|
|
2405
|
+
group: "development",
|
|
2406
|
+
key: "s",
|
|
2407
|
+
label: "截图",
|
|
2408
|
+
pendingLabel: "正在截图当前页面",
|
|
2409
|
+
run: async ({ options }) => {
|
|
2410
|
+
return `截图已保存到 ${await runScreenshotAction(options)}`;
|
|
2411
|
+
}
|
|
2412
|
+
},
|
|
2413
|
+
{
|
|
2414
|
+
description: "手动重新构建当前小程序产物",
|
|
2415
|
+
group: "development",
|
|
2416
|
+
key: "r",
|
|
2417
|
+
label: "手动重新构建产物",
|
|
2418
|
+
pendingLabel: "正在手动重新构建当前小程序产物",
|
|
2419
|
+
run: async ({ options }) => {
|
|
2420
|
+
return await runDevRebuildAction(options);
|
|
2421
|
+
}
|
|
2422
|
+
},
|
|
2423
|
+
{
|
|
2424
|
+
description: "重置当前 DevTools automator 会话",
|
|
2425
|
+
group: "devtools",
|
|
2426
|
+
key: "c",
|
|
2427
|
+
label: "重置 DevTools 会话",
|
|
2428
|
+
pendingLabel: "正在重置当前 DevTools 会话",
|
|
2429
|
+
run: async ({ options }) => {
|
|
2430
|
+
return await runResetDevtoolsSessionAction(options);
|
|
2431
|
+
}
|
|
2432
|
+
},
|
|
2433
|
+
{
|
|
2434
|
+
description: "重置会话并重开当前微信开发者工具项目",
|
|
2435
|
+
group: "devtools",
|
|
2436
|
+
key: "C",
|
|
2437
|
+
label: "重置并重开项目",
|
|
2438
|
+
pendingLabel: "正在重置当前 DevTools 会话并重开项目",
|
|
2439
|
+
run: async ({ options }) => {
|
|
2440
|
+
return await runResetAndReopenDevtoolsAction(options);
|
|
2441
|
+
}
|
|
2442
|
+
},
|
|
2443
|
+
{
|
|
2444
|
+
description: "重新打开当前微信开发者工具项目",
|
|
2445
|
+
group: "devtools",
|
|
2446
|
+
key: "o",
|
|
2447
|
+
label: "重新打开微信开发者工具",
|
|
2448
|
+
pendingLabel: "正在重新打开微信开发者工具项目",
|
|
2449
|
+
run: async ({ options }) => {
|
|
2450
|
+
return await runOpenIdeAction(options);
|
|
2451
|
+
}
|
|
2452
|
+
},
|
|
2453
|
+
{
|
|
2454
|
+
description: "开关 MCP 服务",
|
|
2455
|
+
group: "devtools",
|
|
2456
|
+
key: "m",
|
|
2457
|
+
label: "MCP 切换",
|
|
2458
|
+
run: async ({ toggleMcp }) => {
|
|
2459
|
+
return await toggleMcp();
|
|
2460
|
+
}
|
|
2461
|
+
},
|
|
2462
|
+
{
|
|
2463
|
+
description: "退出当前 dev",
|
|
2464
|
+
group: "process",
|
|
2465
|
+
key: "q"
|
|
2466
|
+
},
|
|
2467
|
+
{
|
|
2468
|
+
description: "强制中断当前 dev",
|
|
2469
|
+
group: "process",
|
|
2470
|
+
key: "Ctrl+C"
|
|
2471
|
+
},
|
|
2472
|
+
{
|
|
2473
|
+
description: "暂时挂起当前 dev,恢复终端控制",
|
|
2474
|
+
group: "process",
|
|
2475
|
+
key: "Ctrl+Z"
|
|
2476
|
+
},
|
|
2477
|
+
{
|
|
2478
|
+
description: "重新显示这份帮助",
|
|
2479
|
+
group: "help",
|
|
2480
|
+
key: "h"
|
|
2481
|
+
}
|
|
2482
|
+
];
|
|
2483
|
+
function resolveDevHotkeyRowsByGroup() {
|
|
2484
|
+
return DEV_HOTKEY_GROUPS.map((group) => ({
|
|
2485
|
+
key: group.key,
|
|
2486
|
+
rows: DEV_HOTKEY_DEFINITIONS.filter((action) => action.group === group.key),
|
|
2487
|
+
title: group.title
|
|
2488
|
+
}));
|
|
2489
|
+
}
|
|
2490
|
+
function resolveRunnableHotkeyDefinition(input) {
|
|
2491
|
+
return DEV_HOTKEY_DEFINITIONS.find((action) => action.run && action.key === input);
|
|
2492
|
+
}
|
|
2493
|
+
//#endregion
|
|
2127
2494
|
//#region package.json
|
|
2128
|
-
var version = "6.15.
|
|
2495
|
+
var version = "6.15.14";
|
|
2129
2496
|
//#endregion
|
|
2130
2497
|
//#region src/cli/devHotkeys/format.ts
|
|
2131
2498
|
const FULLWIDTH_ASCII_START = 65281;
|
|
@@ -2143,55 +2510,45 @@ function formatFooterLine(state) {
|
|
|
2143
2510
|
if (state.currentAction) return `执行中 ${state.currentAction}`;
|
|
2144
2511
|
return "就绪 等待操作...";
|
|
2145
2512
|
}
|
|
2513
|
+
function formatHotkeyRows(rows) {
|
|
2514
|
+
const key = (value) => colors.bold(colors.green(value));
|
|
2515
|
+
const formattedRows = rows.map((row) => ({
|
|
2516
|
+
description: row.description,
|
|
2517
|
+
key: key(row.key)
|
|
2518
|
+
}));
|
|
2519
|
+
const keyColumnWidth = Math.max(...formattedRows.map((row) => row.key.length));
|
|
2520
|
+
return formattedRows.map(({ key, description }) => `按 ${key.padEnd(keyColumnWidth)} ${description}`);
|
|
2521
|
+
}
|
|
2522
|
+
function formatExtraHotkeyRows(rows) {
|
|
2523
|
+
const key = (value) => colors.bold(colors.green(value));
|
|
2524
|
+
const formattedRows = rows.map(([hotkey, description]) => ({
|
|
2525
|
+
description,
|
|
2526
|
+
key: key(hotkey)
|
|
2527
|
+
}));
|
|
2528
|
+
const keyColumnWidth = Math.max(...formattedRows.map((row) => row.key.length));
|
|
2529
|
+
return formattedRows.map(({ key, description }) => `按 ${key.padEnd(keyColumnWidth)} ${description}`);
|
|
2530
|
+
}
|
|
2146
2531
|
/**
|
|
2147
2532
|
* @description 生成带状态的开发态快捷键帮助文本。
|
|
2148
2533
|
*/
|
|
2149
2534
|
function formatDevHotkeyHelpWithState(state) {
|
|
2150
|
-
const
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
{
|
|
2160
|
-
key: key("q"),
|
|
2161
|
-
description: "退出当前 dev"
|
|
2162
|
-
},
|
|
2163
|
-
{
|
|
2164
|
-
key: key("Ctrl+C"),
|
|
2165
|
-
description: "强制中断当前 dev"
|
|
2166
|
-
},
|
|
2167
|
-
{
|
|
2168
|
-
key: key("Ctrl+Z"),
|
|
2169
|
-
description: "暂时挂起当前 dev,恢复终端控制"
|
|
2170
|
-
}
|
|
2535
|
+
const sections = resolveDevHotkeyRowsByGroup().filter((section) => section.rows.length > 0).flatMap((section) => [
|
|
2536
|
+
"",
|
|
2537
|
+
section.title,
|
|
2538
|
+
...formatHotkeyRows(section.rows)
|
|
2539
|
+
]);
|
|
2540
|
+
const retrySections = [
|
|
2541
|
+
"",
|
|
2542
|
+
"登录重试",
|
|
2543
|
+
...formatExtraHotkeyRows([[RETRY_CONFIRM_KEYS.join(" / "), "微信开发者工具登录失效后确认重试当前命令"], [RETRY_CANCEL_KEYS.join(" / "), "取消当前登录重试提示"]])
|
|
2171
2544
|
];
|
|
2172
|
-
const helpRows = [{
|
|
2173
|
-
key: key("h"),
|
|
2174
|
-
description: "重新显示这份帮助"
|
|
2175
|
-
}];
|
|
2176
|
-
const keyColumnWidth = Math.max(...[
|
|
2177
|
-
...actionRows,
|
|
2178
|
-
...processRows,
|
|
2179
|
-
...helpRows
|
|
2180
|
-
].map((row) => row.key.length));
|
|
2181
|
-
const formatRows = (rows) => rows.map(({ key, description }) => `按 ${key.padEnd(keyColumnWidth)} ${description}`);
|
|
2182
2545
|
return [
|
|
2183
2546
|
`${colors.bold(colors.green("DEV"))} weapp-vite v${version} ${state.projectLabel ?? "weapp"}`,
|
|
2547
|
+
...sections,
|
|
2548
|
+
...retrySections,
|
|
2184
2549
|
"",
|
|
2185
|
-
"
|
|
2186
|
-
...
|
|
2187
|
-
"",
|
|
2188
|
-
"进程控制",
|
|
2189
|
-
...formatRows(processRows),
|
|
2190
|
-
"",
|
|
2191
|
-
"帮助",
|
|
2192
|
-
...formatRows(helpRows),
|
|
2193
|
-
"",
|
|
2194
|
-
`当前状态:${state.currentAction ?? "等待操作"} / MCP ${formatMcpStatus(state)}`
|
|
2550
|
+
`当前状态:${state.currentAction ?? "等待操作"} / MCP ${formatMcpStatus(state)}`,
|
|
2551
|
+
...state.lastAction ? [`最近操作:${state.lastAction}`] : []
|
|
2195
2552
|
].join("\n");
|
|
2196
2553
|
}
|
|
2197
2554
|
/**
|
|
@@ -2200,6 +2557,7 @@ function formatDevHotkeyHelpWithState(state) {
|
|
|
2200
2557
|
function formatDevHotkeyHintWithState(state) {
|
|
2201
2558
|
const key = (value) => colors.bold(colors.green(value));
|
|
2202
2559
|
if (state.currentAction) return `${formatFooterLine(state)},按 ${key("h")} 显示帮助,按 ${key("q")} 退出`;
|
|
2560
|
+
if (state.lastAction) return `开发快捷键已就绪,最近操作:${state.lastAction},按 ${key("h")} 显示帮助,按 ${key("q")} 退出`;
|
|
2203
2561
|
return `开发快捷键已就绪,按 ${key("h")} 显示帮助,按 ${key("q")} 退出`;
|
|
2204
2562
|
}
|
|
2205
2563
|
function normalizeInputChar(input) {
|
|
@@ -2252,43 +2610,6 @@ function createToggleMcpAction(options) {
|
|
|
2252
2610
|
};
|
|
2253
2611
|
}
|
|
2254
2612
|
//#endregion
|
|
2255
|
-
//#region src/cli/devHotkeys/screenshot.ts
|
|
2256
|
-
const DEV_SCREENSHOT_DIR = ".weapp-vite/dev-screenshots";
|
|
2257
|
-
const DEFAULT_SCREENSHOT_TIMEOUT = 3e4;
|
|
2258
|
-
/**
|
|
2259
|
-
* @description 生成开发态截图输出路径。
|
|
2260
|
-
*/
|
|
2261
|
-
function resolveDevScreenshotOutputPath(cwd, now = /* @__PURE__ */ new Date()) {
|
|
2262
|
-
const stamp = now.toISOString().replace(/[:.]/g, "-");
|
|
2263
|
-
return path.join(cwd, DEV_SCREENSHOT_DIR, `screenshot-${stamp}.png`);
|
|
2264
|
-
}
|
|
2265
|
-
function formatLogPath(cwd, targetPath) {
|
|
2266
|
-
const relativePath = path.relative(cwd, targetPath);
|
|
2267
|
-
if (!relativePath || relativePath.startsWith("..")) return targetPath;
|
|
2268
|
-
return relativePath;
|
|
2269
|
-
}
|
|
2270
|
-
function formatResolvedScreenshotPath(cwd, fallbackPath, result) {
|
|
2271
|
-
return formatLogPath(cwd, result.path ?? fallbackPath);
|
|
2272
|
-
}
|
|
2273
|
-
/**
|
|
2274
|
-
* @description 执行当前页面截图并输出结果日志。
|
|
2275
|
-
*/
|
|
2276
|
-
async function runScreenshotAction(options) {
|
|
2277
|
-
const outputPath = resolveDevScreenshotOutputPath(options.cwd);
|
|
2278
|
-
await fs$2.mkdir(path.dirname(outputPath), { recursive: true });
|
|
2279
|
-
logger_default.info(`[dev action] 正在截图当前页面,输出到 ${colors.cyan(formatLogPath(options.cwd, outputPath))}`);
|
|
2280
|
-
const result = await takeScreenshot({
|
|
2281
|
-
fullPage: true,
|
|
2282
|
-
projectPath: options.projectPath,
|
|
2283
|
-
sharedSession: true,
|
|
2284
|
-
outputPath,
|
|
2285
|
-
timeout: DEFAULT_SCREENSHOT_TIMEOUT
|
|
2286
|
-
});
|
|
2287
|
-
const resolvedPath = formatResolvedScreenshotPath(options.cwd, outputPath, result);
|
|
2288
|
-
logger_default.success(`[dev action] 当前页面截图完成:${colors.cyan(resolvedPath)}`);
|
|
2289
|
-
return resolvedPath;
|
|
2290
|
-
}
|
|
2291
|
-
//#endregion
|
|
2292
2613
|
//#region src/cli/devHotkeys/index.ts
|
|
2293
2614
|
function forwardSigint() {
|
|
2294
2615
|
process.kill(process.pid, "SIGINT");
|
|
@@ -2301,10 +2622,6 @@ function forwardSigtstp() {
|
|
|
2301
2622
|
*/
|
|
2302
2623
|
function startDevHotkeys(options) {
|
|
2303
2624
|
if (options.platform !== "weapp" || !process.stdin.isTTY) return;
|
|
2304
|
-
emitKeypressEvents(process.stdin);
|
|
2305
|
-
const hasSetRawMode = typeof process.stdin.setRawMode === "function";
|
|
2306
|
-
if (hasSetRawMode) process.stdin.setRawMode(true);
|
|
2307
|
-
process.stdin.resume();
|
|
2308
2625
|
let closed = false;
|
|
2309
2626
|
let running = false;
|
|
2310
2627
|
let mcpHandle;
|
|
@@ -2323,27 +2640,20 @@ function startDevHotkeys(options) {
|
|
|
2323
2640
|
mcpRunning: Boolean(mcpHandle?.close),
|
|
2324
2641
|
projectLabel: resolveProjectLabel(options.cwd)
|
|
2325
2642
|
});
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
};
|
|
2335
|
-
const ensureTerminalActive = () => {
|
|
2336
|
-
if (closed) return;
|
|
2337
|
-
if (hasSetRawMode) process.stdin.setRawMode(true);
|
|
2338
|
-
process.stdin.resume();
|
|
2339
|
-
};
|
|
2643
|
+
let inputSession = createSharedInputSession({
|
|
2644
|
+
onData: (chunk) => {
|
|
2645
|
+
onData?.(chunk);
|
|
2646
|
+
},
|
|
2647
|
+
onKeypress: (str, key) => {
|
|
2648
|
+
onKeypress?.(str, key);
|
|
2649
|
+
}
|
|
2650
|
+
});
|
|
2340
2651
|
const close = () => {
|
|
2341
2652
|
if (closed) return;
|
|
2342
2653
|
closed = true;
|
|
2343
|
-
if (onData) process.stdin.off("data", onData);
|
|
2344
|
-
if (onKeypress) process.stdin.off("keypress", onKeypress);
|
|
2345
2654
|
if (onSigcont) process.off("SIGCONT", onSigcont);
|
|
2346
|
-
|
|
2655
|
+
inputSession?.close();
|
|
2656
|
+
inputSession = void 0;
|
|
2347
2657
|
if (mcpHandle?.close) mcpHandle.close().catch((error) => {
|
|
2348
2658
|
logger_default.warn(`[dev action] MCP 服务关闭失败:${error instanceof Error ? error.message : String(error)}`);
|
|
2349
2659
|
});
|
|
@@ -2358,24 +2668,18 @@ function startDevHotkeys(options) {
|
|
|
2358
2668
|
};
|
|
2359
2669
|
const printHelp = () => {
|
|
2360
2670
|
printPanel(formatDevHotkeyHelpWithState(getState()), true);
|
|
2361
|
-
ensureTerminalActive();
|
|
2362
2671
|
};
|
|
2363
2672
|
const printHint = () => {
|
|
2364
2673
|
printPanel(formatDevHotkeyHintWithState(getState()));
|
|
2365
|
-
ensureTerminalActive();
|
|
2366
2674
|
};
|
|
2367
2675
|
const restore = () => {
|
|
2368
2676
|
if (closed) return;
|
|
2369
|
-
|
|
2370
|
-
if (onKeypress) process.stdin.off("keypress", onKeypress);
|
|
2371
|
-
attachTerminal();
|
|
2372
|
-
if (onData) process.stdin.on("data", onData);
|
|
2373
|
-
if (onKeypress) process.stdin.on("keypress", onKeypress);
|
|
2677
|
+
inputSession?.resume();
|
|
2374
2678
|
printHint();
|
|
2375
2679
|
};
|
|
2376
2680
|
const suspend = () => {
|
|
2377
2681
|
lastRenderedPanel = "";
|
|
2378
|
-
|
|
2682
|
+
inputSession?.suspend();
|
|
2379
2683
|
forwardSigtstp();
|
|
2380
2684
|
};
|
|
2381
2685
|
const toggleMcp = createToggleMcpAction({
|
|
@@ -2386,6 +2690,9 @@ function startDevHotkeys(options) {
|
|
|
2386
2690
|
mcpHandle = handle;
|
|
2387
2691
|
}
|
|
2388
2692
|
});
|
|
2693
|
+
const resolvePendingLabel = (input) => {
|
|
2694
|
+
if (input === "m") return mcpHandle?.close ? "正在关闭 MCP 服务" : "正在启动 MCP 服务";
|
|
2695
|
+
};
|
|
2389
2696
|
const runAction = (label, pendingLabel, action) => {
|
|
2390
2697
|
if (running) {
|
|
2391
2698
|
const current = currentAction ?? "已有命令";
|
|
@@ -2427,14 +2734,12 @@ function startDevHotkeys(options) {
|
|
|
2427
2734
|
printHelp();
|
|
2428
2735
|
return;
|
|
2429
2736
|
}
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2737
|
+
const action = resolveRunnableHotkeyDefinition(normalizedInput) ?? resolveRunnableHotkeyDefinition(normalized);
|
|
2738
|
+
if (action?.run) runAction(action.label ?? action.description, resolvePendingLabel(normalized) ?? action.pendingLabel ?? `正在执行 ${action.description}`, async () => {
|
|
2739
|
+
return await action.run({
|
|
2740
|
+
options,
|
|
2741
|
+
toggleMcp
|
|
2433
2742
|
});
|
|
2434
|
-
return;
|
|
2435
|
-
}
|
|
2436
|
-
if (normalized === "m") runAction("MCP 切换", mcpHandle?.close ? "正在关闭 MCP 服务" : "正在启动 MCP 服务", async () => {
|
|
2437
|
-
return await toggleMcp();
|
|
2438
2743
|
});
|
|
2439
2744
|
};
|
|
2440
2745
|
const handleInputOnce = (input, source) => {
|
|
@@ -2454,7 +2759,6 @@ function startDevHotkeys(options) {
|
|
|
2454
2759
|
const text = typeof chunk === "string" ? chunk : Buffer.from(chunk).toString("utf8");
|
|
2455
2760
|
for (const char of text) handleInputOnce(char, "data");
|
|
2456
2761
|
};
|
|
2457
|
-
process.stdin.on("data", onData);
|
|
2458
2762
|
onKeypress = (str, key) => {
|
|
2459
2763
|
if (key?.ctrl && key.name === "c") {
|
|
2460
2764
|
handleInputOnce("", "keypress");
|
|
@@ -2466,7 +2770,6 @@ function startDevHotkeys(options) {
|
|
|
2466
2770
|
}
|
|
2467
2771
|
if (typeof str === "string" && str) handleInputOnce(str, "keypress");
|
|
2468
2772
|
};
|
|
2469
|
-
process.stdin.on("keypress", onKeypress);
|
|
2470
2773
|
onSigcont = () => {
|
|
2471
2774
|
restore();
|
|
2472
2775
|
};
|
|
@@ -2697,6 +3000,24 @@ function resolveWebHost(host) {
|
|
|
2697
3000
|
if (typeof host === "string") return host;
|
|
2698
3001
|
return String(host);
|
|
2699
3002
|
}
|
|
3003
|
+
/**
|
|
3004
|
+
* @description 为 serve 模式构造统一的小程序开发动作,供热键与命令复用。
|
|
3005
|
+
*/
|
|
3006
|
+
function createServeMiniProgramDevActions(options) {
|
|
3007
|
+
const projectPath = options.projectPath ?? options.fallbackProjectPath;
|
|
3008
|
+
return {
|
|
3009
|
+
projectPath,
|
|
3010
|
+
openIde: async () => {
|
|
3011
|
+
if (await options.tryReuseForwardConsole?.()) return "已通过控制台转发复用当前开发者工具会话";
|
|
3012
|
+
await options.openIde(projectPath);
|
|
3013
|
+
return "已重新打开微信开发者工具项目";
|
|
3014
|
+
},
|
|
3015
|
+
rebuild: async () => {
|
|
3016
|
+
await options.build();
|
|
3017
|
+
return "已手动重新构建当前小程序产物";
|
|
3018
|
+
}
|
|
3019
|
+
};
|
|
3020
|
+
}
|
|
2700
3021
|
function waitForServeShutdownSignal() {
|
|
2701
3022
|
return new Promise((resolve) => {
|
|
2702
3023
|
const onSignal = () => {
|
|
@@ -2758,11 +3079,34 @@ function registerServeCommand(cli) {
|
|
|
2758
3079
|
logRuntimeTarget(targets, { resolvedConfigPlatform: configService.platform });
|
|
2759
3080
|
const enableAnalyze = Boolean(isUiEnabled(options) && targets.runMini);
|
|
2760
3081
|
let analyzeHandle;
|
|
3082
|
+
const miniProgramDevActions = createServeMiniProgramDevActions({
|
|
3083
|
+
build: async () => {
|
|
3084
|
+
await buildService.build(options);
|
|
3085
|
+
},
|
|
3086
|
+
fallbackProjectPath: configService.cwd,
|
|
3087
|
+
openIde: async (projectPath) => {
|
|
3088
|
+
await openIde(configService.platform, projectPath, {
|
|
3089
|
+
reuseOpenedProject: false,
|
|
3090
|
+
trustProject: options.trustProject
|
|
3091
|
+
});
|
|
3092
|
+
},
|
|
3093
|
+
projectPath: resolveIdeProjectRoot(configService.mpDistRoot, configService.cwd),
|
|
3094
|
+
tryReuseForwardConsole: async () => {
|
|
3095
|
+
return await maybeStartForwardConsole({
|
|
3096
|
+
platform: configService.platform,
|
|
3097
|
+
mpDistRoot: configService.mpDistRoot,
|
|
3098
|
+
cwd: configService.cwd,
|
|
3099
|
+
weappViteConfig: configService.weappViteConfig
|
|
3100
|
+
});
|
|
3101
|
+
}
|
|
3102
|
+
});
|
|
2761
3103
|
const devHotkeysSession = targets.runMini ? startDevHotkeys({
|
|
2762
3104
|
cwd: configService.cwd,
|
|
2763
3105
|
mcpConfig: configService.weappViteConfig?.mcp,
|
|
3106
|
+
openIde: miniProgramDevActions.openIde,
|
|
2764
3107
|
platform: configService.platform,
|
|
2765
|
-
projectPath:
|
|
3108
|
+
projectPath: miniProgramDevActions.projectPath ?? configService.cwd,
|
|
3109
|
+
rebuild: miniProgramDevActions.rebuild,
|
|
2766
3110
|
silentStartupHint: true
|
|
2767
3111
|
}) : void 0;
|
|
2768
3112
|
try {
|
|
@@ -2824,15 +3168,7 @@ function registerServeCommand(cli) {
|
|
|
2824
3168
|
detail: "开发服务已就绪,准备打开 IDE 项目。",
|
|
2825
3169
|
tags: ["ide", "open"]
|
|
2826
3170
|
}]);
|
|
2827
|
-
|
|
2828
|
-
platform: configService.platform,
|
|
2829
|
-
mpDistRoot: configService.mpDistRoot,
|
|
2830
|
-
cwd: configService.cwd,
|
|
2831
|
-
weappViteConfig: configService.weappViteConfig
|
|
2832
|
-
})) await openIde(configService.platform, resolveIdeProjectRoot(configService.mpDistRoot, configService.cwd), {
|
|
2833
|
-
reuseOpenedProject: false,
|
|
2834
|
-
trustProject: options.trustProject
|
|
2835
|
-
});
|
|
3171
|
+
await miniProgramDevActions.openIde();
|
|
2836
3172
|
devHotkeysSession?.restore();
|
|
2837
3173
|
}
|
|
2838
3174
|
if (analyzeHandle) await analyzeController.waitForExit();
|
|
@@ -2904,18 +3240,18 @@ async function tryRunIdeCommand(argv) {
|
|
|
2904
3240
|
if (!command) return false;
|
|
2905
3241
|
if (command === "ide") {
|
|
2906
3242
|
if (argv[1] === "logs") return false;
|
|
2907
|
-
await
|
|
3243
|
+
if (!await dispatchWechatCliCommand(argv.slice(1))) await executeWechatIdeCliCommand(argv.slice(1));
|
|
2908
3244
|
return true;
|
|
2909
3245
|
}
|
|
2910
3246
|
if (command.startsWith("-")) return false;
|
|
2911
3247
|
if (command === "help") {
|
|
2912
3248
|
const target = argv[1];
|
|
2913
3249
|
if (!target || WEAPP_VITE_NATIVE_COMMANDS.has(target) || !isWeappIdeTopLevelCommand(target)) return false;
|
|
2914
|
-
await
|
|
3250
|
+
await executeWechatIdeCliCommand(argv);
|
|
2915
3251
|
return true;
|
|
2916
3252
|
}
|
|
2917
3253
|
if (WEAPP_VITE_NATIVE_COMMANDS.has(command) || !isWeappIdeTopLevelCommand(command)) return false;
|
|
2918
|
-
await
|
|
3254
|
+
if (!await dispatchWechatCliCommand(argv)) await executeWechatIdeCliCommand(argv);
|
|
2919
3255
|
return true;
|
|
2920
3256
|
}
|
|
2921
3257
|
//#endregion
|