#!/usr/bin/env node /** * Build-time precompress for web/dist: write sibling .br / .gz variants. * Zero npm deps — uses Node zlib (available in node:22-bookworm web-builder). */ import fs from 'node:fs'; import path from 'node:path'; import { brotliCompressSync, constants as zlibConstants, gzipSync } from 'node:zlib'; import { fileURLToPath } from 'node:url'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const distDir = path.resolve(__dirname, '..', 'dist'); const MIN_BYTES = 1024; const COMPRESS_EXT = new Set(['.js', '.css', '.html', '.svg', '.json', '.txt', '.xml', '.map']); const SKIP_EXT = new Set(['.woff', '.woff2', '.png', '.jpg', '.jpeg', '.gif', '.webp', '.ico', '.br', '.gz']); function walk(dir, out = []) { for (const ent of fs.readdirSync(dir, { withFileTypes: true })) { const full = path.join(dir, ent.name); if (ent.isDirectory()) walk(full, out); else out.push(full); } return out; } function shouldCompress(filePath) { const ext = path.extname(filePath).toLowerCase(); if (SKIP_EXT.has(ext)) return false; if (!COMPRESS_EXT.has(ext)) return false; const st = fs.statSync(filePath); return st.size >= MIN_BYTES; } function writeIfSmaller(sourcePath, variantPath, buf, label, originalSize) { if (buf.length >= originalSize) { if (fs.existsSync(variantPath)) fs.unlinkSync(variantPath); return null; } fs.writeFileSync(variantPath, buf); const pct = ((1 - buf.length / originalSize) * 100).toFixed(1); console.log( ` ${label.padEnd(4)} ${path.relative(distDir, sourcePath)} ${originalSize} → ${buf.length} (−${pct}%)`, ); return buf.length; } if (!fs.existsSync(distDir)) { console.error(`precompress: missing ${distDir}; run vite build first`); process.exit(1); } const files = walk(distDir).filter(shouldCompress); console.log(`precompress: ${files.length} candidate(s) under ${distDir}`); let brCount = 0; let gzCount = 0; for (const file of files) { const raw = fs.readFileSync(file); const br = brotliCompressSync(raw, { params: { [zlibConstants.BROTLI_PARAM_QUALITY]: 11, [zlibConstants.BROTLI_PARAM_SIZE_HINT]: raw.length, }, }); const gz = gzipSync(raw, { level: 9 }); if (writeIfSmaller(file, `${file}.br`, br, 'br', raw.length) != null) brCount += 1; if (writeIfSmaller(file, `${file}.gz`, gz, 'gzip', raw.length) != null) gzCount += 1; } console.log(`precompress: wrote ${brCount} .br and ${gzCount} .gz`);