100 lines
1.7 KiB
JavaScript
100 lines
1.7 KiB
JavaScript
|
|
import { execFileSync, spawn } from "node:child_process";
|
||
|
|
import { existsSync } from "node:fs";
|
||
|
|
|
||
|
|
const isWindows = process.platform === "win32";
|
||
|
|
|
||
|
|
function detectPackageManager() {
|
||
|
|
const userAgent = process.env.npm_config_user_agent ?? "";
|
||
|
|
|
||
|
|
if (userAgent.startsWith("pnpm/")) {
|
||
|
|
return "pnpm";
|
||
|
|
}
|
||
|
|
|
||
|
|
if (userAgent.startsWith("yarn/")) {
|
||
|
|
return "yarn";
|
||
|
|
}
|
||
|
|
|
||
|
|
if (userAgent.startsWith("npm/")) {
|
||
|
|
return "npm";
|
||
|
|
}
|
||
|
|
|
||
|
|
if (existsSync("pnpm-lock.yaml")) {
|
||
|
|
return "pnpm";
|
||
|
|
}
|
||
|
|
|
||
|
|
if (existsSync("yarn.lock")) {
|
||
|
|
return "yarn";
|
||
|
|
}
|
||
|
|
|
||
|
|
return "npm";
|
||
|
|
}
|
||
|
|
|
||
|
|
const packageManager = detectPackageManager();
|
||
|
|
const commands = [
|
||
|
|
`${packageManager} run dev:server`,
|
||
|
|
`${packageManager} run dev`,
|
||
|
|
];
|
||
|
|
|
||
|
|
function startCommand(command) {
|
||
|
|
if (isWindows) {
|
||
|
|
return spawn("cmd.exe", ["/d", "/s", "/c", command], {
|
||
|
|
cwd: process.cwd(),
|
||
|
|
stdio: "inherit",
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
return spawn(command, {
|
||
|
|
cwd: process.cwd(),
|
||
|
|
stdio: "inherit",
|
||
|
|
shell: true,
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
const children = commands.map(startCommand);
|
||
|
|
let shuttingDown = false;
|
||
|
|
|
||
|
|
function stopChild(child) {
|
||
|
|
if (child.exitCode !== null || child.killed) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (isWindows) {
|
||
|
|
try {
|
||
|
|
execFileSync("taskkill", ["/pid", String(child.pid), "/t", "/f"], {
|
||
|
|
stdio: "ignore",
|
||
|
|
});
|
||
|
|
} catch {
|
||
|
|
}
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
try {
|
||
|
|
child.kill("SIGTERM");
|
||
|
|
} catch {
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
function shutdown(code = 0) {
|
||
|
|
if (shuttingDown) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
shuttingDown = true;
|
||
|
|
children.forEach(stopChild);
|
||
|
|
process.exit(code);
|
||
|
|
}
|
||
|
|
|
||
|
|
process.on("SIGINT", () => shutdown(0));
|
||
|
|
process.on("SIGTERM", () => shutdown(0));
|
||
|
|
|
||
|
|
children.forEach((child) => {
|
||
|
|
child.on("error", () => shutdown(1));
|
||
|
|
child.on("exit", (code) => {
|
||
|
|
if (shuttingDown) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
shutdown(code ?? 0);
|
||
|
|
});
|
||
|
|
});
|