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.
69 lines
1.9 KiB
TypeScript
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",
|
|
},
|
|
});
|