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 *-.js(.map) that this build did not produce. const cleanStaleChunks = () => { const produced = new Set(); 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", }, });