import { readFile, writeFile } from "node:fs/promises"; import { evaluateBundleBudget } from "../src/application/policies/performance-budgets.js"; import { classifyViteJavascript } from "./lib/classify-vite-bundle.mjs"; 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 classification = classifyViteJavascript(viteManifest); const initialJsGzipBytes = classification.initialFiles.reduce( (total, file) => total + (outputByPath.get(file)?.gzipBytes ?? 0), 0, ); const lazyChunks = classification.lazyFiles.map((file) => ({ path: file, gzipBytes: outputByPath.get(file)?.gzipBytes ?? 0, })); const missingOutputs = [ ...classification.initialFiles, ...classification.lazyFiles, ].filter((file) => !outputByPath.has(file)); 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) && classification.missingImports.length === 0 && missingOutputs.length === 0; const completedReport = { ...report, measurements, classification, missingOutputs, 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 or manifest integrity failed: ${[ ...classification.missingImports, ...missingOutputs, ].join(", ")}\n`, ); process.exit(1); } process.stdout.write( `Bundle budget: PASS (initial JS ${initialJsGzipBytes} / ${budgets.initialJsGzipBytes} gzip bytes)\n`, );