/** * Build script: copy src → dist, minify JS/CSS, inline critical CSS (Beasties). * Run with: pnpm build */ import { rmSync, mkdirSync, readFileSync, writeFileSync, cpSync, readdirSync, } from 'fs'; import { join, dirname, extname } from 'path'; import { fileURLToPath } from 'url'; import Beasties from 'beasties'; import { minify as minifyJs } from 'terser'; import CleanCSS from 'clean-css'; const __dirname = dirname(fileURLToPath(import.meta.url)); const root = join(__dirname, '..'); const srcDir = join(root, 'src'); const distDir = join(root, 'dist'); function getFiles(dir, files = []) { const entries = readdirSync(dir, { withFileTypes: true }); for (const e of entries) { const full = join(dir, e.name); if (e.isDirectory()) getFiles(full, files); else files.push(full); } return files; } async function main() { // 1. Clean and copy src → dist rmSync(distDir, { recursive: true, force: true }); mkdirSync(distDir, { recursive: true }); cpSync(srcDir, distDir, { recursive: true }); const distFiles = getFiles(distDir); // 2. Minify JS const jsFiles = distFiles.filter((f) => extname(f) === '.js'); for (const f of jsFiles) { const code = readFileSync(f, 'utf8'); const result = await minifyJs(code, { format: { comments: false } }); if (result.code) writeFileSync(f, result.code); } // 3. Minify CSS const cleanCss = new CleanCSS({ level: 2 }); const cssFiles = distFiles.filter((f) => extname(f) === '.css'); for (const f of cssFiles) { const code = readFileSync(f, 'utf8'); const result = cleanCss.minify(code); if (!result.errors.length) writeFileSync(f, result.styles); } // 4. Inline critical CSS with Beasties for all HTML files (no browser; works in CI) const htmlFiles = distFiles.filter((f) => extname(f) === '.html'); const beasties = new Beasties({ path: distDir, preload: 'default', logLevel: 'warn', }); for (const htmlFile of htmlFiles) { const html = readFileSync(htmlFile, 'utf8'); const inlined = await beasties.process(html); writeFileSync(htmlFile, inlined); } console.log('Build complete: dist/'); } main().catch((err) => { console.error(err); process.exit(1); });