Il contesto
Il lettore di prove degli anni precedenti di baccalaureat.sn si basa su @react-pdf-viewer, montato come isola React in una pagina Twig. Ricostruendo la feature, ho incontrato tre bug distinti che si mascheravano a vicenda — ogni correzione rivelava la successiva. Racconto nell'ordine della diagnosi.
Bug 1 — Il viewer che rifiuta di avviarsi: versioni pdfjs-dist
Primo sintomo, fin dal montaggio: errore di worker e viewer vuoto. La causa era nel package.json: @react-pdf-viewer/core dichiara un intervallo rigido di versioni compatibili di pdfjs-dist, e npm aveva risolto una versione più recente di quella supportata dalla lib.
npm ls pdfjs-dist
# └── pdfjs-dist@3.11.174 ← installé
# @react-pdf-viewer/core requiert ^2.16.105 || ^3.0.279 (API compatible)
pdf.js rompe regolarmente la sua API interna tra versioni minori — l'intervallo dichiarato dal viewer non è decorativo. Correzione: fissare una versione testata e compatibile.
npm install pdfjs-dist@3.4.120 --save-exact
Il --save-exact è volontario: niente ^ che lascerebbe npm ri-derivare verso una versione incompatibile al prossimo install.
Bug 2 — Perfetto in locale, morto in prod: il worker su CDN
Viewer funzionante in locale... e pagina bianca in produzione. La differenza: il worker pdf.js era caricato da unpkg.
// AVANT : dépendance runtime à un CDN externe
const WORKER_URL = 'https://unpkg.com/pdfjs-dist@3.4.120/build/pdf.worker.min.js';
In prod, tra la Content-Security-Policy del sito e gli imprevisti del CDN, il worker non si caricava — e senza worker, pdf.js non renderizza nulla. La soluzione robusta: servire il worker da soli, dai propri asset, con Vite che risolve l'URL al build:
// APRÈS : le worker est un asset local, hashé et servi par mon propre domaine
import workerUrl from 'pdfjs-dist/build/pdf.worker.min.js?url';
<Worker workerUrl={workerUrl}>
<Viewer fileUrl={pdfUrl} />
</Worker>
Il suffisso ?url chiede a Vite di trattare il file come asset e di restituirne l'URL finale. Niente più CDN di terze parti nel giro: stessa origine, stessa cache, stessa politica di sicurezza del resto del sito.
Bug 3 — Una sola pagina visibile, documento sfalsato: l'overflow del parent
Ultimo bug, il più subdolo: il PDF finalmente si visualizza, ma una sola pagina, impossibile scorrere, e il documento appariva sfalsato nella sua cornice. Nessun errore in console. Il colpevole non era nel viewer — era nel mio CSS:
/* AVANT : le conteneur de la page, écrit des semaines plus tôt */
.lecteur-container {
overflow: hidden; /* posé « pour la propreté » du layout */
height: 80vh;
}
@react-pdf-viewer gestisce il proprio contenitore di scroll virtuale: renderizza le pagine man mano che si scorre. Un overflow: hidden su un parent interrompe questo meccanismo — il viewer crede che nulla scorra, quindi non renderizza mai le pagine successive. Correzione: rimuovere ogni overflow: hidden dagli antenati del viewer e dargli un'altezza esplicita, poi lasciargli gestire il proprio scroll interno.
/* APRÈS : le viewer est seul maître de son défilement */
.lecteur-container {
height: 80vh;
/* plus d'overflow: hidden ici ni sur aucun parent du viewer */
}
Cosa mi porto via
- Gli intervalli di versioni di
pdfjs-distdichiarati da @react-pdf-viewer sono rigidi per buone ragioni — fissare con--save-exactevita regressioni silenziose. - Un worker caricato da un CDN di terze parti è una dipendenza runtime nascosta: in prod, CSP e disponibilità del CDN diventano i VOSTRI problemi. L'import Vite
?urlriporta tutto in locale. - Quando un componente a scroll virtuale renderizza solo una parte del suo contenuto senza errori, cercare un
overflow: hiddentra i suoi antenati prima di sospettare la lib. - Tre bug annidati = correggere nell'ordine in cui si rivelano, uno alla volta, validando ogni passo — mai tutti e tre in parallelo.