81 lines
1.8 KiB
JavaScript
81 lines
1.8 KiB
JavaScript
#!/usr/bin/env node
|
|
import { spawn } from "node:child_process";
|
|
import { existsSync } from "node:fs";
|
|
import path from "node:path";
|
|
|
|
const BUN_CMD = (() => {
|
|
if (process.env.BUN_BIN && existsSync(process.env.BUN_BIN)) {
|
|
return process.env.BUN_BIN;
|
|
}
|
|
const npmExec = process.env.npm_execpath;
|
|
if (npmExec?.toLowerCase().includes("bun")) {
|
|
return npmExec;
|
|
}
|
|
if (process.env.BUN_INSTALL) {
|
|
const candidate = path.join(
|
|
process.env.BUN_INSTALL,
|
|
"bin",
|
|
process.platform === "win32" ? "bun.exe" : "bun",
|
|
);
|
|
if (existsSync(candidate)) {
|
|
return candidate;
|
|
}
|
|
}
|
|
return "bun";
|
|
})();
|
|
|
|
const commands = [
|
|
{ name: "worker", cmd: BUN_CMD, args: ["run", "dev:worker"] },
|
|
{ name: "ui", cmd: BUN_CMD, args: ["run", "dev:ui"] },
|
|
];
|
|
|
|
const children = new Map();
|
|
let shuttingDown = false;
|
|
|
|
const shutdown = (code = 0) => {
|
|
if (shuttingDown) {
|
|
return;
|
|
}
|
|
shuttingDown = true;
|
|
for (const child of children.values()) {
|
|
if (!child.killed) {
|
|
child.kill("SIGINT");
|
|
}
|
|
}
|
|
process.exit(code);
|
|
};
|
|
|
|
for (const command of commands) {
|
|
const child = spawn(command.cmd, command.args, { stdio: "inherit" });
|
|
children.set(command.name, child);
|
|
child.on("error", (error) => {
|
|
if (error.code === "ENOENT") {
|
|
console.error(
|
|
"❌ 未找到 Bun,请确认已安装并配置 PATH,或设置 BUN_BIN 指向 bun 可执行文件。",
|
|
);
|
|
shutdown(1);
|
|
return;
|
|
}
|
|
console.error(`❌ 启动 ${command.name} 失败: ${error.message}`);
|
|
shutdown(1);
|
|
});
|
|
child.on("exit", (code) => {
|
|
if (shuttingDown) {
|
|
return;
|
|
}
|
|
if (code && code !== 0) {
|
|
shutdown(code);
|
|
return;
|
|
}
|
|
const allExited = Array.from(children.values()).every(
|
|
(item) => item.exitCode !== null,
|
|
);
|
|
if (allExited) {
|
|
shutdown(0);
|
|
}
|
|
});
|
|
}
|
|
|
|
process.on("SIGINT", () => shutdown(0));
|
|
process.on("SIGTERM", () => shutdown(0));
|