





















@@ -4,6 +4,7 @@ import fs from "node:fs";
44import { createRequire } from "node:module";
55import path from "node:path";
66import { fileURLToPath } from "node:url";
7+import { resolvePnpmRunner } from "./pnpm-runner.mjs";
78import { buildCmdExeCommandLine } from "./windows-cmd-helpers.mjs";
89910const here = path.dirname(fileURLToPath(import.meta.url));
@@ -17,42 +18,6 @@ function usage() {
1718process.stderr.write("Usage: node scripts/ui.js <install|dev|build|test> [...args]\n");
1819}
192020-function which(cmd) {
21-try {
22-const key = process.platform === "win32" ? "Path" : "PATH";
23-const paths = (process.env[key] ?? process.env.PATH ?? "")
24-.split(path.delimiter)
25-.filter(Boolean);
26-const extensions =
27-process.platform === "win32"
28- ? (process.env.PATHEXT ?? ".EXE;.CMD;.BAT;.COM").split(";").filter(Boolean)
29- : [""];
30-for (const entry of paths) {
31-for (const ext of extensions) {
32-const candidate = path.join(entry, process.platform === "win32" ? `${cmd}${ext}` : cmd);
33-try {
34-if (fs.existsSync(candidate)) {
35-return candidate;
36-}
37-} catch {
38-// ignore
39-}
40-}
41-}
42-} catch {
43-// ignore
44-}
45-return null;
46-}
47-48-function resolveRunner() {
49-const pnpm = which("pnpm");
50-if (pnpm) {
51-return { cmd: pnpm, kind: "pnpm" };
52-}
53-return null;
54-}
55-5621export function shouldUseCmdExeForCommand(cmd, platform = process.platform) {
5722if (platform !== "win32") {
5823return false;
@@ -89,19 +54,42 @@ export function resolveSpawnCall(cmd, args, envOverride, params = {}) {
8954};
9055}
915692-function run(cmd, args) {
93-const { command, args: spawnArgs, options } = resolveSpawnCall(cmd, args);
57+export function resolvePnpmSpawnCall(pnpmArgs, envOverride, params = {}) {
58+const env = envOverride ?? process.env;
59+const platform = params.platform ?? process.platform;
60+const runner = resolvePnpmRunner({
61+ pnpmArgs,
62+nodeExecPath: params.nodeExecPath ?? process.execPath,
63+npmExecPath: params.npmExecPath ?? env.npm_execpath,
64+comSpec: params.comSpec ?? env.ComSpec,
65+ platform,
66+});
67+return {
68+command: runner.command,
69+args: runner.args,
70+options: {
71+cwd: params.cwd ?? uiDir,
72+stdio: "inherit",
73+ env,
74+shell: runner.shell,
75+windowsVerbatimArguments: runner.windowsVerbatimArguments,
76+},
77+};
78+}
79+80+function runSpawnCall(spawnCall, label) {
81+const { command, args: spawnArgs, options } = spawnCall;
9482let child;
9583try {
9684child = spawn(command, spawnArgs, options);
9785} catch (err) {
98-console.error(`Failed to launch ${cmd}:`, err);
86+console.error(`Failed to launch ${label}:`, err);
9987process.exit(1);
10088return;
10189}
1029010391child.on("error", (err) => {
104-console.error(`Failed to launch ${cmd}:`, err);
92+console.error(`Failed to launch ${label}:`, err);
10593process.exit(1);
10694});
10795child.on("exit", (code) => {
@@ -111,13 +99,21 @@ function run(cmd, args) {
11199});
112100}
113101114-function runSync(cmd, args, envOverride) {
115-const { command, args: spawnArgs, options } = resolveSpawnCall(cmd, args, envOverride);
102+function run(cmd, args) {
103+runSpawnCall(resolveSpawnCall(cmd, args), cmd);
104+}
105+106+function runPnpm(args, envOverride) {
107+runSpawnCall(resolvePnpmSpawnCall(args, envOverride), "pnpm");
108+}
109+110+function runSpawnCallSync(spawnCall, label) {
111+const { command, args: spawnArgs, options } = spawnCall;
116112let result;
117113try {
118114result = spawnSync(command, spawnArgs, options);
119115} catch (err) {
120-console.error(`Failed to launch ${cmd}:`, err);
116+console.error(`Failed to launch ${label}:`, err);
121117process.exit(1);
122118return;
123119}
@@ -129,6 +125,10 @@ function runSync(cmd, args, envOverride) {
129125}
130126}
131127128+function runPnpmSync(args, envOverride) {
129+runSpawnCallSync(resolvePnpmSpawnCall(args, envOverride), "pnpm");
130+}
131+132132function depsInstalled(kind) {
133133try {
134134const require = createRequire(path.join(uiDir, "package.json"));
@@ -179,24 +179,18 @@ export function main(argv = process.argv.slice(2)) {
179179return;
180180}
181181182-const runner = resolveRunner();
183-if (!runner) {
184-process.stderr.write("Missing UI runner: install pnpm, then retry.\n");
185-process.exit(1);
186-}
187-188182if (action === "install") {
189-run(runner.cmd, ["install", ...rest]);
183+runPnpm(["install", ...rest]);
190184return;
191185}
192186193187if (!depsInstalled(action === "test" ? "test" : "build")) {
194188const installEnv = process.env;
195189const installArgs = ["install"];
196-runSync(runner.cmd, installArgs, installEnv);
190+runPnpmSync(installArgs, installEnv);
197191}
198192199-run(runner.cmd, ["run", script, ...rest]);
193+runPnpm(["run", script, ...rest]);
200194}
201195202196export function resolveDirectExecutionPath(entry, realpath = fs.realpathSync.native) {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。