A project I'm working on needs 3 things to happen before dev/build:
- Hash legal content (license, terms) to detect changes.
- Split a huge GeoJSON file into per-region chunks.
- Generate static SEO landing pages from a metadata JSON.
npm's
pre-scripts hook intodevandbuildautomatically. But chaining 3+ steps gets messy fast. ## What I tried first
json
{
"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"
}
}
Works. Two problems:
Duplication: predev and prebuild are identical. Add a 4th step and you change two places.
Hard to debug: if step 2 fails, the error reaches you but the chain stops without context.
The cleaner pattern
Single orchestrator script that runs them in order with logging:
// 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)`);
}
Then package.json:
{
"scripts": {
"predev": "node scripts/prebuild.js",
"prebuild": "node scripts/prebuild.js",
"dev": "vite",
"build": "vite build"
}
}
Add a 4th step? One line in the orchestrator. Want to skip a step in dev? Filter STEPS by env var. Want timing per step? Already in the log.
Bonus: parallel steps
If two steps are independent (don't write to the same file), run them in parallel:
await Promise.all([
runStep('hash', '...'),
runStep('split', '...'),
]);
await runStep('gen-landings', '...');
Cuts predev time roughly in half on my project.
Small refactor, much less friction every time I add a build step.
Top comments (0)