VOOZH about

URL: https://dev.to/bairescodeai/vite-predevprebuild-chaining-scripts-without-losing-your-mind-4j01

⇱ Vite predev/prebuild: chaining scripts without losing your mind - DEV Community


A project I'm working on needs 3 things to happen before dev/build:

  1. Hash legal content (license, terms) to detect changes.
  2. Split a huge GeoJSON file into per-region chunks.
  3. Generate static SEO landing pages from a metadata JSON. npm's pre- scripts hook into dev and build automatically. 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.