Pdf Processor
The Vite + <base href> Trap That Silently Breaks Production Builds
TLDR
Using standard<script type="module" src="../src/app.js"> inside subfolder HTML documents containing <base href="/tools/pdf-processor/"> causes production 404 errors because browsers resolve src URLs relative to the <base href> (/src/app.js) rather than the HTML file's disk directory. Converting script tags to inline module imports (<script type="module">import '../src/app.js';</script>) forces Rollup to resolve entry points at build time.
| Script Import Form | Browser <base href> Resolution | Production Build Behavior |
|---|---|---|
<script src="../src/app.js"> | Resolves to /src/app.js at runtime | 404 Silent Failure |
<script>import '../src/app.js';</script> | Resolved by Rollup at build time | 100% Bundled & Resolved |
Technical three-layer deployment architecture
1. Inline module import pattern
Replace staticsrc script attributes with inline ES module import statements:
<!-- Subdirectory HTML Entry: editor/index.html -->
<head>
<base href="/tools/pdf-processor/">
<!-- Safe: Rollup resolves relative import at build time before base href applies -->
<script type="module">
import '../src/app.js';
</script>
</head>
2. Multi-Page rollup input configuration
Define all subfolder entry HTML files explicitly invite.config.js:
// vite.config.js multi-page entry configuration
export default defineConfig({
build: {
rollupOptions: {
input: {
main: 'index.html',
editor: 'editor/index.html',
visualDiff: 'visual-diff/index.html',
compare: 'compare/index.html'
}
}
}
});
3. Build & CI pipeline verification
Ensure build scripts invoke Vite compilation before copying dist assets:#!/usr/bin/env bash
build.sh - Production build sequence
(cd tools/pdf-processor && npm ci --prefer-offline && npm run build)
cp -r tools/pdf-processor/dist dist/tools/pdf-processor
Rule of thumb: Use inline ES module imports (import '../src/app.js') inside HTML files that define a<base href>to ensure build-time Rollup resolution.
Read this post in the full Engineering Journal →