import { readFile, writeFile } from "node:fs/promises"; import { evaluateBundleBudget } from "../src/application/policies/performance-budgets.js"; const report = /** @type {{ * outputs: Array<{ path: string, gzipBytes: number }>, * [key: string]: unknown * }} */ ( JSON.parse(await readFile("artifacts/performance/bundle.json", "utf8")) ); const viteManifest = /** @type {Record} */ ( JSON.parse(await readFile("dist/.vite/manifest.json", "utf8")) ); const budgets = /** @type {{ initialJsGzipBytes: number, lazyChunkGzipBytes: number }} */ ( JSON.parse(await readFile("config/performance/budgets.json", "utf8")).bundle ); const outputByPath = new Map( report.outputs.map((output) => [output.path.replace(/^dist\//, ""), output]), ); const initialFiles = new Set( Object.values(viteManifest) .filter((entry) => entry.isEntry) .map((entry) => entry.file), ); const lazyFiles = new Set( Object.values(viteManifest) .filter((entry) => !entry.isEntry && entry.file.endsWith(".js")) .map((entry) => entry.file), ); const initialJsGzipBytes = [...initialFiles].reduce( (total, file) => total + (outputByPath.get(file)?.gzipBytes ?? 0), 0, ); const lazyChunks = [...lazyFiles].map((file) => ({ path: file, gzipBytes: outputByPath.get(file)?.gzipBytes ?? 0, })); const measurements = { initialJsGzipBytes, lazyChunks }; const result = evaluateBundleBudget(measurements, budgets); const fixtures = [ { name: "initial-js-over-budget", passed: !evaluateBundleBudget( { initialJsGzipBytes: budgets.initialJsGzipBytes + 1, lazyChunks: [], }, budgets, ).passed, }, { name: "lazy-chunk-over-budget", passed: !evaluateBundleBudget( { initialJsGzipBytes: 0, lazyChunks: [ { path: "fixture.js", gzipBytes: budgets.lazyChunkGzipBytes + 1, }, ], }, budgets, ).passed, }, ]; const passed = result.passed && fixtures.every((fixture) => fixture.passed); const completedReport = { ...report, measurements, thresholds: budgets, results: result, fixtures, passed, }; await writeFile( "artifacts/performance/bundle.json", `${JSON.stringify(completedReport, null, 2)}\n`, ); if (!passed) { process.stderr.write("Bundle budget exceeded.\n"); process.exit(1); } process.stdout.write( `Bundle budget: PASS (initial JS ${initialJsGzipBytes} / ${budgets.initialJsGzipBytes} gzip bytes)\n`, );