Generate asset versions during Docker builds
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
import { createHash } from "node:crypto";
|
||||
import { readFile, writeFile, readdir } from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
|
||||
const PLACEHOLDER = "__ASSET_VERSION__";
|
||||
const root = path.resolve(process.argv[2] || process.cwd());
|
||||
const assetRoots = ["public", "shared"];
|
||||
|
||||
async function walk(directory) {
|
||||
const entries = await readdir(directory, { withFileTypes: true });
|
||||
const files = await Promise.all(
|
||||
entries.map((entry) => {
|
||||
const target = path.join(directory, entry.name);
|
||||
return entry.isDirectory() ? walk(target) : target;
|
||||
}),
|
||||
);
|
||||
return files.flat().sort();
|
||||
}
|
||||
|
||||
const files = (
|
||||
await Promise.all(assetRoots.map((directory) => walk(path.join(root, directory))))
|
||||
).flat();
|
||||
const sources = await Promise.all(files.map((file) => readFile(file, "utf8")));
|
||||
const version = createHash("sha256")
|
||||
.update(files.map((file, index) => `${path.relative(root, file)}\0${sources[index]}`).join("\0"))
|
||||
.digest("hex")
|
||||
.slice(0, 16);
|
||||
let replacements = 0;
|
||||
await Promise.all(
|
||||
files.map(async (file, index) => {
|
||||
const source = sources[index];
|
||||
const count = source.split(PLACEHOLDER).length - 1;
|
||||
if (!count) return;
|
||||
replacements += count;
|
||||
await writeFile(file, source.replaceAll(PLACEHOLDER, version));
|
||||
}),
|
||||
);
|
||||
if (!replacements) throw new Error(`No ${PLACEHOLDER} markers found under ${assetRoots.join(", ")}.`);
|
||||
console.log(`Stamped ${replacements} asset references with version ${version}.`);
|
||||
Reference in New Issue
Block a user