// bankai inspect — what did the build produce, and how big is it on the // wire? Reads the manifest + dist and prints raw/gzip/brotli sizes. import { readFile, readdir, stat } from 'node:fs/promises' import { join, resolve, relative } from 'node:path' export default async function inspect ({ outDir = 'dist' }) { outDir = resolve(outDir) const meta = JSON.parse(await readFile(join(outDir, 'bankai.json'), 'utf8')) const rows = [] await walk(outDir, rows, outDir) rows.sort((a, b) => b.raw - a.raw) console.log(`\nbankai build — ${meta.title} (${meta.builtAt})\n`) console.log(' ' + 'file'.padEnd(44) + 'raw'.padStart(10) + 'gzip'.padStart(10) + 'brotli'.padStart(10)) let totals = { raw: 0, gz: 0, br: 0 } for (const row of rows) { totals.raw += row.raw totals.gz += row.gz || 0 totals.br += row.br || 0 console.log(' ' + row.file.padEnd(44) + kb(row.raw) + kb(row.gz) + kb(row.br)) } console.log(' ' + 'total'.padEnd(44) + kb(totals.raw) + kb(totals.gz) + kb(totals.br) + '\n') return rows } async function walk (dir, rows, root) { for (const name of await readdir(dir)) { if (name === '.vite') continue const path = join(dir, name) const info = await stat(path) if (info.isDirectory()) { await walk(path, rows, root) continue } if (name.endsWith('.br') || name.endsWith('.gz')) continue const row = { file: relative(root, path), raw: info.size, gz: null, br: null } row.gz = await sizeOf(path + '.gz') row.br = await sizeOf(path + '.br') rows.push(row) } } async function sizeOf (path) { try { return (await stat(path)).size } catch (e) { return null } } function kb (bytes) { if (bytes === null) return '—'.padStart(10) return (bytes < 1024 ? bytes + ' B' : (bytes / 1024).toFixed(1) + ' kB').padStart(10) }