lct-hack/frontend/scripts/precompress-assets.mjs

39 lines
1.4 KiB
JavaScript
Raw Normal View History

import { readdir, readFile, stat, utimes, writeFile } from "node:fs/promises";
import { gzip } from "node:zlib";
import { promisify } from "node:util";
const gzipAsync = promisify(gzip);
const assetDirectory = new URL("../dist/assets/", import.meta.url);
const compressedExtensions = /\.(?:js|css|json|svg)$/i;
const minimumBytes = 1024;
let compressedCount = 0;
let sourceBytes = 0;
let gzipBytes = 0;
async function compressAssets(directory) {
for (const entry of await readdir(directory, { withFileTypes: true })) {
const path = new URL(`${entry.name}${entry.isDirectory() ? "/" : ""}`, directory);
if (entry.isDirectory()) {
await compressAssets(path);
continue;
}
if (!compressedExtensions.test(entry.name)) continue;
const info = await stat(path);
if (info.size < minimumBytes) continue;
const source = await readFile(path);
const compressed = await gzipAsync(source, { level: 9 });
const compressedPath = new URL(`${entry.name}.gz`, directory);
await writeFile(compressedPath, compressed);
// Nginx gzip_static can safely pair the sidecar with its source file.
await utimes(compressedPath, info.atime, info.mtime);
compressedCount += 1;
sourceBytes += source.byteLength;
gzipBytes += compressed.byteLength;
}
}
await compressAssets(assetDirectory);
console.log(
`Precompressed ${compressedCount} assets: ${sourceBytes} -> ${gzipBytes} bytes`,
);