Files
flights_web/scripts/ci/bundle-size-gate.mjs

89 lines
2.2 KiB
JavaScript

/**
* Bundle-size gate for CI.
*
* Finds all .js files in dist/remote/static/js/, measures their gzip size,
* reports per-file and total, and fails if total exceeds the budget.
*
* Budgets:
* - Total remote bundle: <= 2000 kB gzip
*/
import { readFileSync, readdirSync, statSync } from "node:fs";
import { join } from "node:path";
import { gzipSync } from "node:zlib";
const BUDGET_TOTAL_KB = 2000;
const JS_DIR = "dist/remote/static/js";
function collectJsFiles(dir) {
const results = [];
let entries;
try {
entries = readdirSync(dir);
} catch {
return results;
}
for (const entry of entries) {
const full = join(dir, entry);
const stat = statSync(full, { throwIfNoEntry: false });
if (!stat) continue;
if (stat.isDirectory()) {
results.push(...collectJsFiles(full));
} else if (entry.endsWith(".js")) {
results.push(full);
}
}
return results;
}
const files = collectJsFiles(JS_DIR);
if (files.length === 0) {
console.error(`No .js files found in ${JS_DIR}. Did the build run?`);
process.exit(1);
}
let totalGzip = 0;
const rows = [];
for (const file of files) {
const raw = readFileSync(file);
const gzipped = gzipSync(raw);
const gzipKB = gzipped.length / 1024;
totalGzip += gzipKB;
rows.push({ file: file.replace("dist/remote/", ""), rawKB: (raw.length / 1024).toFixed(1), gzipKB: gzipKB.toFixed(1) });
}
rows.sort((a, b) => parseFloat(b.gzipKB) - parseFloat(a.gzipKB));
console.log("\n--- Bundle Size Report ---\n");
console.log(
"File".padEnd(60) +
"Raw (kB)".padStart(12) +
"Gzip (kB)".padStart(12)
);
console.log("-".repeat(84));
for (const r of rows) {
console.log(
r.file.padEnd(60) +
r.rawKB.padStart(12) +
r.gzipKB.padStart(12)
);
}
console.log("-".repeat(84));
console.log(
"TOTAL".padEnd(60) +
"".padStart(12) +
totalGzip.toFixed(1).padStart(12)
);
console.log(`\nBudget: ${BUDGET_TOTAL_KB} kB gzip`);
if (totalGzip > BUDGET_TOTAL_KB) {
console.error(`\nFAILED: Total gzip size ${totalGzip.toFixed(1)} kB exceeds budget of ${BUDGET_TOTAL_KB} kB`);
process.exit(1);
} else {
console.log(`\nPASSED: ${totalGzip.toFixed(1)} kB / ${BUDGET_TOTAL_KB} kB budget`);
}