A framework-agnostic, universal document renderer with optional chunked loading
polyrender.wisp.place/
1import { defineConfig, type Plugin } from 'vite'
2
3/**
4 * The core library's `requirePeerDep` does `import(moduleName)` where
5 * `moduleName` is a variable — Vite cannot statically analyze that, so the
6 * import fails at runtime in the browser.
7 *
8 * This plugin rewrites the variable import into a lookup of static `import()`
9 * calls that Vite CAN resolve and pre-bundle.
10 */
11function resolvePeerDeps(): Plugin {
12 const peerDeps = [
13 'pdfjs-dist',
14 'epubjs',
15 'docx-preview',
16 'papaparse',
17 'highlight.js',
18 'jszip',
19 'xlsx',
20 'node-unrar-js',
21 '@jsquash/jxl',
22 'utif',
23 ]
24
25 // Build a code snippet that maps module names → static imports.
26 // highlight.js needs `.default` unwrapping for ESM compatibility.
27 const cases = peerDeps
28 .map((d) => ` case '${d}': return import('${d}').then(m => m.default || m);`)
29 .join('\n')
30
31 // 7z-wasm's default ESM build imports Node's 'module' built-in, so we
32 // redirect to its UMD build which is browser-safe.
33 const sevenZipCase = ` case '7z-wasm': return import('7z-wasm/7zz.umd.js').then(m => m.default || m);`
34
35 const replacement = [
36 '(async (name) => { switch(name) {',
37 cases,
38 sevenZipCase,
39 ' default: throw new Error(`Unknown peer dep: ${name}`);',
40 ' }})(moduleName)',
41 ].join('\n')
42
43 return {
44 name: 'resolve-polyrender-peer-deps',
45 enforce: 'pre',
46 transform(code: string, id: string) {
47 // Only transform the @polyrender/core bundle
48 if (!id.includes('packages/core')) return
49 if (!code.includes('moduleName')) return
50
51 // Replace `await import(moduleName)` or `await import(\n moduleName\n)`
52 const result = code.replace(
53 /await\s+import\(\s*(?:\/\*.*?\*\/\s*)?moduleName\s*\)/g,
54 `await ${replacement}`,
55 )
56
57 if (result !== code) return result
58 },
59 }
60}
61
62export default defineConfig({
63 plugins: [resolvePeerDeps()],
64 // @jsquash/jxl ships a Web Worker whose internal format is "iife".
65 // Forcing workers to ES module format prevents the Rollup error:
66 // "Invalid value 'iife' for option 'worker.format' — UMD and IIFE output
67 // formats are not supported for code-splitting builds."
68 worker: {
69 format: 'es',
70 },
71 optimizeDeps: {
72 include: [
73 'pdfjs-dist',
74 'epubjs',
75 'docx-preview',
76 'papaparse',
77 'highlight.js',
78 'jszip',
79 'xlsx',
80 'node-unrar-js',
81 '7z-wasm/7zz.umd.js',
82 '@jsquash/jxl',
83 'utif',
84 ],
85 },
86})