Files

67 lines
2.2 KiB
JavaScript

#!/usr/bin/env node
// Run the TypeScript type-check gate (`tsc`, noEmit) in parallel with the Vite
// bundle instead of sequentially (`tsc && vite build`).
//
// Vite/esbuild strips types itself and never consumes tsc's output, so tsc is a
// pure *gate*: running it alongside the bundle makes wall-clock max(tsc, vite)
// rather than tsc + vite. The build still fails on a type error because we exit
// non-zero if EITHER job fails — the exit code is the gate, not the presence of
// build artifacts (CI keys off the exit code, and a failed build's artifacts
// are discarded).
//
// Any extra args are forwarded to `vite build` (e.g. `--mode development`).
// Env vars (e.g. VITE_OPENHUMAN_TARGET set via cross-env) are inherited by both
// children. `shell: true` resolves the `tsc`/`vite` shims from node_modules/.bin
// on every platform, including the `.cmd` wrappers on Windows.
import { spawn } from 'node:child_process';
const viteArgs = process.argv.slice(2);
const jobs = [
{ name: 'tsc', cmd: 'tsc', args: [] },
{ name: 'vite', cmd: 'vite', args: ['build', ...viteArgs] },
];
const active = new Map();
let firstFailure = null;
function stopSiblings(failedName) {
for (const [name, child] of active) {
if (name !== failedName && !child.killed) {
child.kill();
}
}
}
function run({ name, cmd, args }) {
return new Promise(resolve => {
const child = spawn(cmd, args, { stdio: 'inherit', shell: true });
active.set(name, child);
child.on('exit', (code, signal) => {
active.delete(name);
const exitCode = code ?? (signal ? 1 : 0);
if (exitCode !== 0 && firstFailure === null) {
firstFailure = name;
stopSiblings(name);
}
resolve({ name, code: exitCode });
});
child.on('error', err => {
active.delete(name);
console.error(`[build-parallel] failed to start ${name}: ${err.message}`);
if (firstFailure === null) {
firstFailure = name;
stopSiblings(name);
}
resolve({ name, code: 1 });
});
});
}
const results = await Promise.all(jobs.map(run));
const failed = results.filter(r => r.code !== 0);
if (failed.length > 0) {
console.error(`[build-parallel] failed: ${failed.map(f => f.name).join(', ')}`);
process.exit(1);
}