weapp-vite 6.17.2 → 6.17.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.
Files changed (2) hide show
  1. package/dist/cli.mjs +130 -23
  2. package/package.json +8 -8
package/dist/cli.mjs CHANGED
@@ -23,7 +23,7 @@ import { generateJs, generateJson, generateWxml, generateWxss } from "@weapp-cor
23
23
  import { determineAgent } from "@vercel/detect-agent";
24
24
  import { initConfig } from "@weapp-core/init";
25
25
  import { createInterface } from "node:readline/promises";
26
- import { clearTimeout, setTimeout as setTimeout$1 } from "node:timers";
26
+ import { clearTimeout as clearTimeout$1, setTimeout as setTimeout$1 } from "node:timers";
27
27
  import net from "node:net";
28
28
  //#region src/cli/runtime.ts
29
29
  function logRuntimeTarget(targets, options = {}) {
@@ -277,12 +277,28 @@ function logWechatIdeServicePortDisabledHint(projectPath) {
277
277
  }
278
278
  //#endregion
279
279
  //#region src/cli/openIde/reuse.ts
280
+ const OPENED_PROJECT_HEALTH_CHECK_TIMEOUT = 3e3;
280
281
  function formatReuseOpenedWechatIdePrompt() {
281
- return `目标项目已在微信开发者工具中打开,已跳过重复打开。按 ${colors.bold(colors.green("r"))} 关闭当前窗口后重新打开。`;
282
+ return `目标项目已在微信开发者工具中打开,已跳过重复打开。按 ${RETRY_CONFIRM_KEYS.map((key) => colors.bold(colors.green(key))).join(" / ")} 关闭当前窗口后重新打开。`;
282
283
  }
283
284
  function disconnectMiniProgram(miniProgram) {
284
285
  miniProgram.disconnect();
285
286
  }
287
+ function withTimeout(task, timeoutMs) {
288
+ let timer;
289
+ const timeout = new Promise((_, reject) => {
290
+ timer = setTimeout(() => {
291
+ reject(/* @__PURE__ */ new Error(`opened automator health check timed out after ${timeoutMs}ms`));
292
+ }, timeoutMs);
293
+ });
294
+ return Promise.race([task, timeout]).finally(() => {
295
+ if (timer) clearTimeout(timer);
296
+ });
297
+ }
298
+ async function verifyOpenedProjectHealth(miniProgram) {
299
+ if (typeof miniProgram.screenshot !== "function") return;
300
+ await withTimeout(miniProgram.screenshot({ timeout: OPENED_PROJECT_HEALTH_CHECK_TIMEOUT }), OPENED_PROJECT_HEALTH_CHECK_TIMEOUT);
301
+ }
286
302
  async function openWechatIdeByAutomator(projectPath) {
287
303
  disconnectMiniProgram(await launchAutomator({
288
304
  persistAsDefaultSession: true,
@@ -293,13 +309,17 @@ async function openWechatIdeByAutomator(projectPath) {
293
309
  }));
294
310
  }
295
311
  async function connectOpenedProject(projectPath) {
312
+ let miniProgram = null;
296
313
  try {
297
- return await connectOpenedAutomator({
314
+ miniProgram = await connectOpenedAutomator({
298
315
  projectPath,
299
316
  port: resolveProjectAutomatorPort(projectPath),
300
317
  timeout: 3e3
301
318
  });
319
+ await verifyOpenedProjectHealth(miniProgram);
320
+ return miniProgram;
302
321
  } catch {
322
+ if (miniProgram) disconnectMiniProgram(miniProgram);
303
323
  return null;
304
324
  }
305
325
  }
@@ -444,6 +464,32 @@ async function prepareOpenedWechatIdeAutomatorSession(projectPath, options) {
444
464
  };
445
465
  }
446
466
  }
467
+ async function connectOpenedWechatIdeAutomatorSession(projectPath) {
468
+ try {
469
+ (await connectOpenedAutomator({
470
+ projectPath,
471
+ port: resolveProjectAutomatorPort(projectPath),
472
+ timeout: PREPARE_AUTOMATOR_SESSION_TIMEOUT
473
+ })).disconnect?.();
474
+ return { ok: true };
475
+ } catch (error) {
476
+ logger_default.warn("连接当前项目的微信开发者工具自动化会话失败,截图、MCP 或 IDE 联动命令首次运行时将重新连接。");
477
+ logWechatIdeRecoveryHint({
478
+ projectPath,
479
+ reason: "当前项目已完成打开流程,但尚未连接到可复用的自动化会话。"
480
+ });
481
+ if (shouldLogAutomatorFallbackError()) logger_default.error(error);
482
+ return {
483
+ ok: false,
484
+ reason: "automator-session-failed",
485
+ error
486
+ };
487
+ }
488
+ }
489
+ async function prepareWechatIdeAutomatorSession(projectPath, options) {
490
+ if (options.prepareAutomatorSession === "connect-opened") return await connectOpenedWechatIdeAutomatorSession(projectPath);
491
+ return await prepareOpenedWechatIdeAutomatorSession(projectPath, options);
492
+ }
447
493
  async function stabilizeOpenedWechatIdeProject(projectPath, servicePortEnabled, options = {}) {
448
494
  if (servicePortEnabled === false) return {
449
495
  ok: false,
@@ -478,7 +524,7 @@ async function stabilizeOpenedWechatIdeProject(projectPath, servicePortEnabled,
478
524
  if (!isWechatIdeEngineBuildEndpointMissingError(error)) throw error;
479
525
  logger_default.warn("当前微信开发者工具不支持自动 engine build 刷新,已跳过该步骤;如模拟器显示旧状态,可在开发者工具内手动编译。");
480
526
  }
481
- if (options.useAutomatorOpen !== false) try {
527
+ if (options.useAutomatorOpen !== false && options.skipAutomatorCompile !== true) try {
482
528
  await executeWechatIdeCliCommand(appendLoginRetryArgv(["compile"], options), {
483
529
  automatorMode: "require",
484
530
  httpMode: "skip",
@@ -572,7 +618,7 @@ async function openIde(platform, projectPath, options = {}) {
572
618
  if (!await closeIde()) logger_default.warn("关闭当前微信开发者工具失败,仍继续尝试打开目标项目。");
573
619
  }
574
620
  await runWechatIdeOpenWithRetry(createIdeOpenArgv(platform, projectPath, normalizedOptions));
575
- if (platform === "weapp" && projectPath && normalizedOptions.prepareAutomatorSession) await prepareOpenedWechatIdeAutomatorSession(projectPath, normalizedOptions);
621
+ if (platform === "weapp" && projectPath && normalizedOptions.prepareAutomatorSession) await prepareWechatIdeAutomatorSession(projectPath, normalizedOptions);
576
622
  if (platform === "weapp" && projectPath && !normalizedOptions.skipPostOpenHealthCheck) await verifyAndRecoverOpenedWechatIdeProject(platform, projectPath, bootstrapResult?.servicePortEnabled, normalizedOptions);
577
623
  }
578
624
  /**
@@ -2861,6 +2907,7 @@ const DEFAULT_FORWARD_CONSOLE_LEVELS = [
2861
2907
  "error"
2862
2908
  ];
2863
2909
  let activeForwardConsoleSession;
2910
+ let activeForwardConsoleBridgeOptions;
2864
2911
  const FORWARD_CONSOLE_RETRY_DELAY_MS = 1e3;
2865
2912
  const FORWARD_CONSOLE_RETRY_TIMES = 5;
2866
2913
  async function detectAgent() {
@@ -2975,6 +3022,31 @@ async function startForwardConsoleBridge(options) {
2975
3022
  });
2976
3023
  }
2977
3024
  /**
3025
+ * @description 暂停当前 DevTools 日志桥,并返回恢复函数。
3026
+ */
3027
+ async function pauseActiveForwardConsole() {
3028
+ const session = activeForwardConsoleSession;
3029
+ const bridgeOptions = activeForwardConsoleBridgeOptions;
3030
+ if (!session || !bridgeOptions) return;
3031
+ activeForwardConsoleSession = void 0;
3032
+ activeForwardConsoleBridgeOptions = void 0;
3033
+ await session.close();
3034
+ return async () => {
3035
+ if (activeForwardConsoleSession) return true;
3036
+ try {
3037
+ activeForwardConsoleSession = await startForwardConsoleBridge(bridgeOptions);
3038
+ activeForwardConsoleBridgeOptions = bridgeOptions;
3039
+ return true;
3040
+ } catch (error) {
3041
+ activeForwardConsoleSession = void 0;
3042
+ activeForwardConsoleBridgeOptions = void 0;
3043
+ const message = error instanceof Error ? error.message : String(error);
3044
+ logger_default.warn(`[forwardConsole] 恢复失败:${message}`);
3045
+ return false;
3046
+ }
3047
+ };
3048
+ }
3049
+ /**
2978
3050
  * @description 在 weapp 开发态按需启动控制台转发。
2979
3051
  */
2980
3052
  async function maybeStartForwardConsole(options) {
@@ -2996,10 +3068,12 @@ async function maybeStartForwardConsole(options) {
2996
3068
  };
2997
3069
  try {
2998
3070
  activeForwardConsoleSession = await startForwardConsoleBridge(bridgeOptions);
3071
+ activeForwardConsoleBridgeOptions = bridgeOptions;
2999
3072
  return true;
3000
3073
  } catch (error) {
3001
3074
  if (!isDevtoolsPortNotReadyError(error)) {
3002
3075
  activeForwardConsoleSession = void 0;
3076
+ activeForwardConsoleBridgeOptions = void 0;
3003
3077
  const message = error instanceof Error ? error.message : String(error);
3004
3078
  logger_default.warn(`[forwardConsole] 启动失败,回退到普通 IDE 打开流程:${message}`);
3005
3079
  return false;
@@ -3010,9 +3084,15 @@ async function maybeStartForwardConsole(options) {
3010
3084
  openedOnly: true,
3011
3085
  port: void 0
3012
3086
  });
3087
+ activeForwardConsoleBridgeOptions = {
3088
+ ...bridgeOptions,
3089
+ openedOnly: true,
3090
+ port: void 0
3091
+ };
3013
3092
  return true;
3014
3093
  } catch (fallbackError) {
3015
3094
  activeForwardConsoleSession = void 0;
3095
+ activeForwardConsoleBridgeOptions = void 0;
3016
3096
  const message = fallbackError instanceof Error ? fallbackError.message : String(fallbackError);
3017
3097
  logger_default.warn(`[forwardConsole] 启动失败,回退到普通 IDE 打开流程:${message}`);
3018
3098
  return false;
@@ -3365,7 +3445,7 @@ async function probeHttpEndpoint(url) {
3365
3445
  } catch {
3366
3446
  return false;
3367
3447
  } finally {
3368
- clearTimeout(timer);
3448
+ clearTimeout$1(timer);
3369
3449
  controller.abort();
3370
3450
  }
3371
3451
  }
@@ -3876,7 +3956,7 @@ async function runOpenIdeAction(options) {
3876
3956
  //#endregion
3877
3957
  //#region src/cli/devHotkeys/screenshot.ts
3878
3958
  const DEV_SCREENSHOT_DIR = ".weapp-vite/dev-screenshots";
3879
- const DEFAULT_SCREENSHOT_TIMEOUT = 3e4;
3959
+ const DEFAULT_SCREENSHOT_TIMEOUT = 12e4;
3880
3960
  /**
3881
3961
  * @description 生成开发态截图输出路径。
3882
3962
  */
@@ -3892,24 +3972,42 @@ function formatLogPath(cwd, targetPath) {
3892
3972
  function formatResolvedScreenshotPath(cwd, fallbackPath, result) {
3893
3973
  return formatLogPath(cwd, result.path ?? fallbackPath);
3894
3974
  }
3975
+ async function resolveDefaultScreenshotPage(cwd) {
3976
+ try {
3977
+ const raw = await fs$2.readFile(path.join(cwd, "app.json"), "utf8");
3978
+ const appJson = JSON.parse(raw);
3979
+ const [firstPage] = Array.isArray(appJson.pages) ? appJson.pages : [];
3980
+ return typeof firstPage === "string" && firstPage.trim() ? firstPage : void 0;
3981
+ } catch {
3982
+ return;
3983
+ }
3984
+ }
3895
3985
  /**
3896
3986
  * @description 执行当前页面截图并输出结果日志。
3897
3987
  */
3898
3988
  async function runScreenshotAction(options) {
3899
3989
  const outputPath = resolveDevScreenshotOutputPath(options.cwd);
3900
3990
  await fs$2.mkdir(path.dirname(outputPath), { recursive: true });
3991
+ const page = await resolveDefaultScreenshotPage(options.cwd);
3901
3992
  logger_default.info(`[dev action] 正在截图当前页面,输出到 ${colors.cyan(formatLogPath(options.cwd, outputPath))}`);
3902
- const result = await takeScreenshot({
3903
- fullPage: true,
3904
- projectPath: options.projectPath,
3905
- preserveProjectRoot: true,
3906
- sharedSession: true,
3907
- outputPath,
3908
- timeout: DEFAULT_SCREENSHOT_TIMEOUT
3909
- });
3910
- const resolvedPath = formatResolvedScreenshotPath(options.cwd, outputPath, result);
3911
- logger_default.success(`[dev action] 当前页面截图完成:${colors.cyan(resolvedPath)}`);
3912
- return resolvedPath;
3993
+ const resumeForwardConsole = await pauseActiveForwardConsole();
3994
+ try {
3995
+ const result = await takeScreenshot({
3996
+ projectPath: options.projectPath,
3997
+ fullPage: true,
3998
+ ...page ? { page } : {},
3999
+ preserveProjectRoot: true,
4000
+ port: resolveProjectAutomatorPort(options.projectPath),
4001
+ retryWithFreshSession: false,
4002
+ outputPath,
4003
+ timeout: DEFAULT_SCREENSHOT_TIMEOUT
4004
+ });
4005
+ const resolvedPath = formatResolvedScreenshotPath(options.cwd, outputPath, result);
4006
+ logger_default.success(`[dev action] 当前页面截图完成:${colors.cyan(resolvedPath)}`);
4007
+ return resolvedPath;
4008
+ } finally {
4009
+ await resumeForwardConsole?.();
4010
+ }
3913
4011
  }
3914
4012
  //#endregion
3915
4013
  //#region src/cli/devHotkeys/actions.ts
@@ -4024,7 +4122,7 @@ function resolveRunnableHotkeyDefinition(input) {
4024
4122
  }
4025
4123
  //#endregion
4026
4124
  //#region package.json
4027
- var version = "6.17.2";
4125
+ var version = "6.17.3";
4028
4126
  //#endregion
4029
4127
  //#region src/cli/devHotkeys/format.ts
4030
4128
  const FULLWIDTH_ASCII_START = 65281;
@@ -4640,6 +4738,12 @@ function createAnalyzeController(options) {
4640
4738
  }
4641
4739
  //#endregion
4642
4740
  //#region src/cli/commands/serve/shared.ts
4741
+ function startBackgroundForwardConsoleReuse(tryReuseForwardConsole) {
4742
+ if (!tryReuseForwardConsole) return;
4743
+ try {
4744
+ tryReuseForwardConsole().catch(() => {});
4745
+ } catch {}
4746
+ }
4643
4747
  function resolveWebHost(host) {
4644
4748
  if (host === void 0) return;
4645
4749
  if (typeof host === "boolean") return host;
@@ -4656,7 +4760,7 @@ function createServeMiniProgramDevActions(options) {
4656
4760
  openIde: async (openOptions = {}) => {
4657
4761
  if (!openOptions.forceOpen && await options.tryReuseForwardConsole?.()) return "已通过控制台转发复用当前开发者工具会话";
4658
4762
  await options.openIde(projectPath, openOptions);
4659
- await options.tryReuseForwardConsole?.();
4763
+ startBackgroundForwardConsoleReuse(options.tryReuseForwardConsole);
4660
4764
  return openOptions.forceReopen ? "已重新打开微信开发者工具项目" : "已打开或复用微信开发者工具项目";
4661
4765
  },
4662
4766
  rebuild: async () => {
@@ -4724,6 +4828,7 @@ function registerServeCommand(cli) {
4724
4828
  configFile,
4725
4829
  inlineConfig,
4726
4830
  cliPlatform: targets.rawPlatform,
4831
+ preloadAppEntry: false,
4727
4832
  projectConfigPath: options.projectConfig
4728
4833
  });
4729
4834
  const { buildService, configService, webService } = ctx;
@@ -4738,16 +4843,18 @@ function registerServeCommand(cli) {
4738
4843
  },
4739
4844
  fallbackProjectPath: configService.cwd,
4740
4845
  openIde: async (projectPath, openOptions) => {
4846
+ const forceReopen = openOptions?.forceReopen === true;
4741
4847
  await openIde(configService.platform, projectPath, {
4742
4848
  loginRetry: options.loginRetry,
4743
4849
  loginRetryTimeout: options.loginRetryTimeout,
4744
4850
  nonInteractive: options.nonInteractive,
4745
4851
  openRecovery: false,
4746
- prepareAutomatorSession: true,
4747
- reuseOpenedProject: !openOptions?.forceReopen,
4852
+ prepareAutomatorSession: forceReopen ? true : "connect-opened",
4853
+ reuseOpenedProject: !forceReopen,
4854
+ skipAutomatorCompile: !forceReopen,
4748
4855
  skipPostOpenHealthCheck: true,
4749
4856
  trustProject: options.trustProject,
4750
- useAutomatorOpen: true
4857
+ useAutomatorOpen: forceReopen
4751
4858
  });
4752
4859
  writePostOpenSeparator();
4753
4860
  },
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "weapp-vite",
3
3
  "type": "module",
4
- "version": "6.17.2",
4
+ "version": "6.17.3",
5
5
  "description": "weapp-vite 一个现代化的小程序打包工具",
6
6
  "author": "ice breaker <1324318532@qq.com>",
7
7
  "license": "MIT",
@@ -111,30 +111,30 @@
111
111
  "pathe": "^2.0.3",
112
112
  "picomatch": "^4.0.4",
113
113
  "postcss": "^8.5.15",
114
- "rolldown": "1.1.2",
114
+ "rolldown": "1.1.3",
115
115
  "rolldown-plugin-dts": "0.26.0",
116
116
  "semver": "^7.8.5",
117
117
  "typescript": "^6.0.3",
118
- "vite": "8.0.16",
118
+ "vite": "8.1.0",
119
119
  "vite-tsconfig-paths": "^6.1.1",
120
120
  "vue": "^3.5.38",
121
121
  "vue-tsc": "^3.3.5",
122
+ "@weapp-core/constants": "0.1.12",
122
123
  "@weapp-core/init": "6.0.11",
123
124
  "@weapp-core/logger": "3.1.1",
124
125
  "@weapp-core/schematics": "6.0.4",
125
- "@weapp-core/constants": "0.1.12",
126
126
  "@weapp-core/shared": "3.0.5",
127
- "@weapp-vite/ast": "6.17.2",
127
+ "@weapp-vite/ast": "6.17.3",
128
128
  "@weapp-vite/mcp": "1.4.6",
129
- "@weapp-vite/volar": "2.1.0",
130
129
  "@weapp-vite/miniprogram-automator": "1.2.5",
130
+ "@weapp-vite/volar": "2.1.0",
131
131
  "@weapp-vite/web": "1.3.33",
132
132
  "@wevu/api": "0.2.11",
133
133
  "@wevu/web-apis": "1.2.25",
134
134
  "rolldown-require": "2.0.19",
135
135
  "vite-plugin-performance": "2.0.1",
136
- "weapp-ide-cli": "5.4.9",
137
- "wevu": "6.17.2"
136
+ "weapp-ide-cli": "5.4.10",
137
+ "wevu": "6.17.3"
138
138
  },
139
139
  "publishConfig": {
140
140
  "access": "public",