import { gzipSync } from 'node:zlib'; import { readdirSync, readFileSync } from 'node:fs'; import { basename, resolve } from 'node:path'; const root = resolve(import.meta.dirname, '../..'); const dist = resolve(root, 'dist'); const html = readFileSync(resolve(dist, 'index.html'), 'utf8'); const entryMatch = html.match(/]+src="([^"]+\.js)"/); if (!entryMatch) throw new Error('Unable to locate the Vite entry script in dist/index.html'); const assets = resolve(dist, 'assets'); const files = readdirSync(assets).filter((file) => file.endsWith('.js')); const sizes = files.map((file) => ({ file, gzip: gzipSync(readFileSync(resolve(assets, file))).length })); const entryName = basename(entryMatch[1]); const entry = sizes.find((item) => item.file === entryName); if (!entry) throw new Error(`Entry asset ${entryName} was not found`); const entryBudget = Number(process.env.BUNDLE_ENTRY_GZIP_BUDGET ?? 250 * 1024); // ECharts core + the three chart types used by the platform currently settle at ~182 KiB. // Keep a narrow calibrated ceiling so future chart imports cannot silently restore the full bundle. const chunkBudget = Number(process.env.BUNDLE_CHUNK_GZIP_BUDGET ?? 190 * 1024); const oversized = sizes.filter((item) => item.file !== entryName && item.gzip > chunkBudget); console.log(`entry ${entry.file}: ${(entry.gzip / 1024).toFixed(2)} KiB gzip (budget ${(entryBudget / 1024).toFixed(0)} KiB)`); for (const item of sizes.toSorted((a, b) => b.gzip - a.gzip).slice(0, 10)) { console.log(`${item.file}: ${(item.gzip / 1024).toFixed(2)} KiB gzip`); } if (entry.gzip > entryBudget || oversized.length) { if (oversized.length) console.error(`Oversized async chunks: ${oversized.map((item) => item.file).join(', ')}`); process.exit(1); }