Files
bookhoard/vite.config.ts
john-okeefe bd7d71a284 build(vite): remove stale hashed chunks after each build
emptyOutDir is false because web/static also holds tracked assets,
so *-<hash>.js chunks from every previous build accumulated
indefinitely and leaked into Docker images via the build context
(the reader serves whichever chunk the import chain names, so the
orphans are pure confusion + bloat). A closeBundle plugin now
deletes any hashed chunk this build did not produce.
2026-08-14 16:06:27 -04:00

69 lines
1.9 KiB
TypeScript

import { defineConfig } from "vite";
import { cpSync, mkdirSync, readdirSync, rmSync } from "node:fs";
import { join } from "node:path";
const pdfjsAssets = () => ({
name: "pdfjs-assets",
closeBundle() {
const outDir = "web/static/vendor/pdfjs";
const srcDir =
"node_modules/@bookhoard/foliate-js/vendor/pdfjs";
mkdirSync(outDir, { recursive: true });
cpSync(join(srcDir, "standard_fonts"), join(outDir, "standard_fonts"), {
recursive: true,
});
cpSync(join(srcDir, "cmaps"), join(outDir, "cmaps"), { recursive: true });
},
});
// emptyOutDir must stay false (web/static also holds tracked assets),
// so hashed chunks from previous builds would otherwise accumulate
// forever and leak into Docker images via the build context. Remove
// any *-<hash>.js(.map) that this build did not produce.
const cleanStaleChunks = () => {
const produced = new Set<string>();
return {
name: "clean-stale-chunks",
generateBundle(_options, bundle) {
for (const fileName of Object.keys(bundle)) produced.add(fileName);
},
closeBundle() {
const outDir = "web/static";
const chunkRe = /-[A-Za-z0-9_-]{8}\.js(\.map)?$/;
for (const f of readdirSync(outDir)) {
if (chunkRe.test(f) && !produced.has(f)) {
rmSync(join(outDir, f));
}
}
},
};
};
export default defineConfig({
resolve: {
alias: {
"@": "/web/src",
"foliate-js": "/node_modules/@bookhoard/foliate-js",
},
},
base: "/static/",
plugins: [pdfjsAssets(), cleanStaleChunks()],
build: {
outDir: "web/static",
emptyOutDir: false,
assetsDir: "",
rollupOptions: {
input: {
main: "web/src/main.ts",
reader: "web/src/reader/reader.ts",
},
output: {
entryFileNames: "[name].js",
},
},
target: "esnext",
sourcemap: true,
minify: "esbuild",
},
});