import { constants, brotliCompress as brotliCompressCallback, gzip as gzipCallback } from "node:zlib"; import { promisify } from "node:util"; import { readFile, readdir, stat, unlink, writeFile } from "node:fs/promises"; import path from "node:path"; const brotliCompress = promisify(brotliCompressCallback); const gzip = promisify(gzipCallback); const COMPRESSIBLE_EXTENSIONS = new Set([".css", ".html", ".js", ".json", ".mjs", ".svg", ".txt", ".webmanifest", ".xml"]); const MINIMUM_INPUT_BYTES = 1_024; const MAX_COMPRESSION_WORKERS = 4; export async function precompressWebAssets(rootDirectory) { const files = await collectCompressibleFiles(rootDirectory); let nextIndex = 0; const report = { considered: files.length, brotliWritten: 0, gzipWritten: 0 }; await Promise.all( Array.from({ length: Math.min(MAX_COMPRESSION_WORKERS, files.length) }, async () => { while (nextIndex < files.length) { const filePath = files[nextIndex++]; const input = await readFile(filePath); const [brotli, gzipped] = await Promise.all([ brotliCompress(input, { params: { [constants.BROTLI_PARAM_QUALITY]: 7, [constants.BROTLI_PARAM_MODE]: constants.BROTLI_MODE_TEXT, }, }), gzip(input, { level: 9 }), ]); if (brotli.length < input.length) { await writeFile(`${filePath}.br`, brotli); report.brotliWritten += 1; } if (gzipped.length < input.length) { await writeFile(`${filePath}.gz`, gzipped); report.gzipWritten += 1; } } }) ); return report; } /** * React Router can emit an unreferenced `server-build-*.css` copy of the root * stylesheet into the public client directory. Keeping and precompressing the * duplicate adds image bytes and build CPU without serving a request. Delete * it only when another byte-identical stylesheet exists and no emitted JS, * HTML, or JSON asset references its filename. */ export async function pruneUnreferencedDuplicateCss(rootDirectory) { let entries; try { entries = await readdir(rootDirectory, { withFileTypes: true }); } catch (error) { if (error?.code === "ENOENT") return { removed: 0, bytesRemoved: 0 }; throw error; } const cssEntries = entries.filter((entry) => entry.isFile() && entry.name.endsWith(".css")); const candidates = cssEntries.filter((entry) => entry.name.startsWith("server-build-")); if (candidates.length === 0) return { removed: 0, bytesRemoved: 0 }; const referenceEntries = entries.filter( (entry) => entry.isFile() && [".html", ".js", ".json", ".mjs"].includes(path.extname(entry.name).toLowerCase()), ); const referenceSources = await Promise.all(referenceEntries.map((entry) => readFile(path.join(rootDirectory, entry.name), "utf8"))); const cssContents = new Map( await Promise.all(cssEntries.map(async (entry) => [entry.name, await readFile(path.join(rootDirectory, entry.name))])), ); let removed = 0; let bytesRemoved = 0; for (const candidate of candidates) { if (referenceSources.some((source) => source.includes(candidate.name))) continue; const candidateContents = cssContents.get(candidate.name); const duplicateExists = cssEntries.some( (entry) => entry.name !== candidate.name && candidateContents?.equals(cssContents.get(entry.name)), ); if (!duplicateExists || !candidateContents) continue; await unlink(path.join(rootDirectory, candidate.name)); removed += 1; bytesRemoved += candidateContents.length; } return { removed, bytesRemoved }; } async function collectCompressibleFiles(rootDirectory) { const files = []; await visit(rootDirectory, files); return files; } async function visit(directory, files) { let entries; try { entries = await readdir(directory, { withFileTypes: true }); } catch (error) { if (error?.code === "ENOENT") return; throw error; } for (const entry of entries) { const fullPath = path.join(directory, entry.name); if (entry.isDirectory()) { await visit(fullPath, files); } else if ( entry.isFile() && !entry.name.endsWith(".br") && !entry.name.endsWith(".gz") && COMPRESSIBLE_EXTENSIONS.has(path.extname(entry.name).toLowerCase()) ) { const fileStat = await stat(fullPath); if (fileStat.size >= MINIMUM_INPUT_BYTES) { files.push(fullPath); } } } }