Files
saas_frontend/scripts/check-bundle-size.mjs
T

73 lines
2.0 KiB
JavaScript
Raw Normal View History

2026-08-31 20:05:33 -04:00
#!/usr/bin/env node
import fs from "node:fs";
import path from "node:path";
import zlib from "node:zlib";
const BUDGET_KB = 550;
const DIST = path.join(process.cwd(), "dist");
const reportOnly = process.argv.includes("--report");
if (!fs.existsSync(DIST)) {
console.error("No dist/ — run `npm run build` first.");
process.exit(1);
}
const html = fs.readFileSync(path.join(DIST, "index.html"), "utf8");
const assets = [
...html.matchAll(/(?:src|href)="\/?(assets\/[^"]+\.(?:js|css))"/g),
].map((match) => match[1]);
if (assets.length === 0) {
console.error("Found no assets in dist/index.html — has the build changed?");
process.exit(1);
}
let raw = 0;
let gzipped = 0;
const rows = [];
for (const asset of [...new Set(assets)]) {
const file = path.join(DIST, asset);
if (!fs.existsSync(file)) continue;
const contents = fs.readFileSync(file);
const gz = zlib.gzipSync(contents).length;
raw += contents.length;
gzipped += gz;
rows.push({ asset, kb: contents.length / 1024, gzipKb: gz / 1024 });
}
rows.sort((a, b) => b.kb - a.kb);
console.log("First paint:");
for (const row of rows) {
console.log(
` ${row.asset.padEnd(44)} ${row.kb.toFixed(1).padStart(8)} kB` +
` (gzip ${row.gzipKb.toFixed(1)} kB)`
);
}
const totalKb = raw / 1024;
console.log(
` ${"total".padEnd(44)} ${totalKb.toFixed(1).padStart(8)} kB` +
` (gzip ${(gzipped / 1024).toFixed(1)} kB)`
);
if (reportOnly) process.exit(0);
if (totalKb > BUDGET_KB) {
console.error(
`\nFirst paint is ${totalKb.toFixed(1)} kB, over the ${BUDGET_KB} kB budget.\n\n` +
"Something large has entered the initial payload. Usually that is a\n" +
"dependency imported by a shared component rather than by the screen that\n" +
"needs it — check the largest chunk above.\n\n" +
"If the growth is deliberate, raise BUDGET_KB in this file and say what\n" +
"grew, so the next person can tell a decision from a drift."
);
process.exit(1);
}
console.log(`\nWithin budget (${BUDGET_KB} kB).`);