Fix déroulant PDF en production : polyfills DOMMatrix + worker pdfjs
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
pdfjs-dist en Node.js pur (hors Vite) nécessite : - DOMMatrix, Path2D, ImageData polyfills (pas de DOM en Node) - pdf.worker.mjs copié dans le build (traceInclude dans nitro config) Testé : 61 entrées retournées en mode production. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -45,4 +45,12 @@ export default defineNuxtConfig({
|
||||
},
|
||||
},
|
||||
|
||||
nitro: {
|
||||
externals: {
|
||||
traceInclude: [
|
||||
'node_modules/pdfjs-dist/legacy/build/pdf.worker.mjs',
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
})
|
||||
|
||||
@@ -1,28 +1,63 @@
|
||||
import { join } from 'node:path'
|
||||
import { readFileSync, existsSync } from 'node:fs'
|
||||
|
||||
// Polyfills nécessaires pour pdfjs-dist en Node.js pur (pas de DOM)
|
||||
// On n'a besoin que du parsing, pas du rendu
|
||||
if (typeof globalThis.DOMMatrix === 'undefined') {
|
||||
// @ts-expect-error polyfill minimal pour pdfjs
|
||||
globalThis.DOMMatrix = class DOMMatrix {
|
||||
constructor() { return Object.assign(this, { a: 1, b: 0, c: 0, d: 1, e: 0, f: 0 }) }
|
||||
isIdentity = true
|
||||
translate() { return new DOMMatrix() }
|
||||
scale() { return new DOMMatrix() }
|
||||
inverse() { return new DOMMatrix() }
|
||||
multiply() { return new DOMMatrix() }
|
||||
}
|
||||
}
|
||||
if (typeof globalThis.Path2D === 'undefined') {
|
||||
// @ts-expect-error polyfill stub
|
||||
globalThis.Path2D = class Path2D { constructor() {} }
|
||||
}
|
||||
if (typeof globalThis.ImageData === 'undefined') {
|
||||
// @ts-expect-error polyfill stub
|
||||
globalThis.ImageData = class ImageData { constructor(w: number, h: number) { this.width = w; this.height = h; this.data = new Uint8ClampedArray(w * h * 4) } }
|
||||
}
|
||||
|
||||
export default defineEventHandler(async () => {
|
||||
const config = await readYaml('bookplayer.config.yml')
|
||||
const pdfFile = config?.book?.pdfFile || '/pdf/une-economie-du-don.pdf'
|
||||
|
||||
// En dev : public/, en prod : .output/public/
|
||||
// Résolution du chemin PDF : dev (public/) et prod (.output/public/)
|
||||
const cwd = process.cwd()
|
||||
const candidates = [
|
||||
join(cwd, 'public', pdfFile),
|
||||
join(cwd, '.output', 'public', pdfFile),
|
||||
]
|
||||
const pdfPath = candidates.find(p => existsSync(p))
|
||||
if (!pdfPath) return []
|
||||
|
||||
if (!pdfPath) {
|
||||
console.warn('[pdf-outline] PDF non trouvé. cwd:', cwd, 'candidats:', candidates)
|
||||
return []
|
||||
}
|
||||
|
||||
let data: Uint8Array
|
||||
try {
|
||||
data = new Uint8Array(readFileSync(pdfPath))
|
||||
} catch {
|
||||
} catch (err) {
|
||||
console.warn('[pdf-outline] Erreur lecture PDF:', err)
|
||||
return []
|
||||
}
|
||||
|
||||
const pdfjsLib = await import('pdfjs-dist/legacy/build/pdf.mjs')
|
||||
const doc = await pdfjsLib.getDocument({ data, useSystemFonts: true }).promise
|
||||
|
||||
let doc
|
||||
try {
|
||||
doc = await pdfjsLib.getDocument({ data, useSystemFonts: true }).promise
|
||||
} catch (err) {
|
||||
console.warn('[pdf-outline] Erreur getDocument:', err)
|
||||
return []
|
||||
}
|
||||
|
||||
const outline = await doc.getOutline()
|
||||
|
||||
if (!outline || outline.length === 0) {
|
||||
|
||||
Reference in New Issue
Block a user