57 lines
1.6 KiB
JavaScript
57 lines
1.6 KiB
JavaScript
/**
|
||
* 并行启动:FastAPI(8000) + Vite(5173) —— Web 开发
|
||
* 无论从仓库根还是 apps/* 调用,都以本脚本所在仓库为 cwd。
|
||
*/
|
||
import { spawn, spawnSync } from 'node:child_process';
|
||
import path from 'node:path';
|
||
import process from 'node:process';
|
||
import { fileURLToPath } from 'node:url';
|
||
|
||
const isWin = process.platform === 'win32';
|
||
const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
||
const kids = [];
|
||
|
||
function run(label, command, args, env = {}) {
|
||
const child = spawn(command, args, {
|
||
cwd: repoRoot,
|
||
env: {
|
||
...process.env,
|
||
APS_MODE: 'web',
|
||
APS_AUTH_PROVIDER: process.env.APS_AUTH_PROVIDER || 'jms',
|
||
...env,
|
||
},
|
||
stdio: 'inherit',
|
||
shell: isWin,
|
||
});
|
||
child.on('exit', (code) => {
|
||
console.log(`[${label}] exit ${code}`);
|
||
shutdown(code ?? 1);
|
||
});
|
||
kids.push(child);
|
||
return child;
|
||
}
|
||
|
||
function shutdown(code = 0) {
|
||
for (const c of kids) {
|
||
if (!Number.isInteger(c.pid) || c.pid <= 0) continue;
|
||
if (isWin) {
|
||
spawnSync('taskkill.exe', ['/pid', String(c.pid), '/T', '/F'], {
|
||
stdio: 'ignore',
|
||
windowsHide: true,
|
||
});
|
||
continue;
|
||
}
|
||
try { c.kill(); } catch { /* ignore */ }
|
||
}
|
||
process.exit(code);
|
||
}
|
||
|
||
process.on('SIGINT', () => shutdown(0));
|
||
process.on('SIGTERM', () => shutdown(0));
|
||
|
||
const py = process.env.PYTHON || (isWin ? 'python' : 'python3');
|
||
run('api', py, ['-m', 'uvicorn', 'server.main:app', '--reload', '--port', '8000']);
|
||
run('web', isWin ? 'npm.cmd' : 'npm', ['run', 'dev', '--prefix', 'apps/web']);
|
||
|
||
console.log(`\nAPS Web 开发(cwd=${repoRoot}):API :8000 UI :5173\n`);
|