Vite predev/prebuild: chaining scripts without losing your mind
Source: Dev.to
What I tried first
{
"scripts": {
"predev": "node scripts/hash.js && node scripts/split.js && node scripts/gen.js",
"prebuild": "node scripts/hash.js && node scripts/split.js && node scripts/gen.js",
"dev": "vite",
"build": "vite build"
}
}
Problems
- Duplication –
predevandprebuildare identical; adding a fourth step requires editing both entries. - Hard to debug – if a middle step fails, the chain stops without giving context about which step failed.
The cleaner pattern
Create a single orchestrator script that runs each step sequentially and logs progress.
// scripts/prebuild.js
import { spawnSync } from 'node:child_process';
const STEPS = [
['hash-legal', 'scripts/hash-legal-content.cjs'],
['split-geojson', 'scripts/split_parcelas_by_sm.cjs'],
['gen-landings', 'scripts/generate_landings.js'],
];
for (const [name, file] of STEPS) {
console.log(`▶ ${name}`);
const start = Date.now();
const res = spawnSync('node', [file], { stdio: 'inherit' });
if (res.status !== 0) {
console.error(`✗ ${name} failed (exit ${res.status})`);
process.exit(res.status);
}
console.log(`✓ ${name} (${Date.now() - start}ms)`);
}
Update package.json to use the orchestrator for both hooks:
{
"scripts": {
"predev": "node scripts/prebuild.js",
"prebuild": "node scripts/prebuild.js",
"dev": "vite",
"build": "vite build"
}
}
- Adding a fourth step? Just add another entry to
STEPS. - Want to skip a step during development? Filter
STEPSbased on an environment variable. - Need timing per step? The script already logs it.
Bonus: parallel steps
If two steps are independent (they don’t write to the same files), they can be run in parallel to cut down overall time:
// Example snippet inside scripts/prebuild.js
async function runStep(name, file) {
console.log(`▶ ${name}`);
const start = Date.now();
const { status } = await import('child_process').then(cp =>
cp.spawn('node', [file], { stdio: 'inherit' })
);
if (status !== 0) {
console.error(`✗ ${name} failed (exit ${status})`);
process.exit(status);
}
console.log(`✓ ${name} (${Date.now() - start}ms)`);
}
// Parallel execution
await Promise.all([
runStep('hash', 'scripts/hash-legal-content.cjs'),
runStep('split', 'scripts/split_parcelas_by_sm.cjs')
]);
await runStep('gen-landings', 'scripts/generate_landings.js');
Running independent steps concurrently roughly halves the predev time in the author’s project, while keeping the workflow simple and maintainable.