Next.js使用react-pdf时出现PDFDataRangeTransport导出错误
Next.js 中使用 react-pdf 渲染PDF时的
PDFDataRangeTransport 导出错误解决 问题详情
在Next.js项目里用react-pdf渲染PDF,触发如下错误:
SyntaxError: Named export 'PDFDataRangeTransport' not found. The requested module 'pdfjs-dist' is a CommonJS module, which may not support all module.exports as named exports。
错误提示明确CommonJS模块需用默认导入,示例:
import pkg from 'pdfjs-dist'; const { PDFDataRangeTransport } = pkg;
当前组件代码:
import {pdfjs} from 'react-pdf'; import {Document, Page} from 'react-pdf'; import { useState } from 'react'; // 补充遗漏的React导入 export const CaseFile = (props: { caseId: any, doctors: Array<any>, stateTracker: any }) => { const [records, setRecords] = useState([]) const [caseDetails, setCaseDetails] = useState<any>() const [auditEntries, setAuditEntries] = useState<Array<any>>([]) const [numPages, setNumPages] = useState(null); function onDocumentLoadSuccess({numPages: nextNumPages}) { setNumPages(nextNumPages); } pdfjs.GlobalWorkerOptions.workerSrc = new URL( 'pdfjs-dist/build/pdf.worker.min.js', import.meta.url, ).toString(); function getDischargeSummaryView() { return <div className="p-4"> <Document file="/api/s3/download/?file=something.pdf" onLoadSuccess={onDocumentLoadSuccess}> {Array.apply(null, Array(numPages)) .map((x, i) => i + 1) .map((page, i) => <Page key={i} pageNumber={page} renderTextLayer={false} renderAnnotationLayer={false}/>)} </Document> </div> } return ( <> {getDischargeSummaryView()} </> ) }
已配置的next.config.js:
webpack(config, options) { config.module.rules.push({ test: /\.node/, use: 'raw-loader', }, { test: /\.mp3$/, use: { loader: 'file-loader', }, }); return config; },
特殊现象:分页加载时必现错误,但先不渲染Document组件,等页面完全加载后再添加,就能正常显示。
解决步骤
1. 修正模块导入方式
pdfjs-dist是CommonJS模块,ES模块环境下无法直接使用命名导入,调整导入逻辑:
// 替换原react-pdf导入 import pdfjs from 'pdfjs-dist'; import { Document, Page } from 'react-pdf'; // 或者从react-pdf统一导出: // import reactPdf from 'react-pdf'; // const { pdfjs, Document, Page } = reactPdf;
2. 配置Webpack兼容CommonJS模块
Next.js默认不对node_modules中的CommonJS模块做转译,需要在next.config.js中添加规则处理pdfjs-dist:
/** @type {import('next').NextConfig} */ const nextConfig = { webpack(config, options) { // 保留原有规则 config.module.rules.push( { test: /\.node/, use: 'raw-loader' }, { test: /\.mp3$/, use: { loader: 'file-loader' } } ); // 别名指向pdfjs-dist的ES兼容版本 config.resolve.alias['pdfjs-dist'] = 'pdfjs-dist/build/pdf'; // 对pdfjs-dist进行转译 config.module.rules.push({ test: /node_modules\/pdfjs-dist\/.*/, use: options.defaultLoaders.babel, }); return config; }, }; module.exports = nextConfig;
3. 动态加载组件避免SSR冲突
react-pdf的部分API无法在服务端运行,用Next.js的dynamic导入禁用SSR:
import dynamic from 'next/dynamic'; import { useState, useEffect } from 'react'; // 动态导入Document和Page,禁用服务端渲染 const Document = dynamic(() => import('react-pdf').then(m => m.Document), { ssr: false }); const Page = dynamic(() => import('react-pdf').then(m => m.Page), { ssr: false }); export const CaseFile = (props: { caseId: any, doctors: Array<any>, stateTracker: any }) => { // ... 原有状态定义 // 仅在客户端初始化pdfjs worker useEffect(() => { import('pdfjs-dist').then(pdfjs => { pdfjs.GlobalWorkerOptions.workerSrc = new URL( 'pdfjs-dist/build/pdf.worker.min.js', import.meta.url ).toString(); }); }, []); function getDischargeSummaryView() { // 初始numPages为null,避免渲染错误 if (!numPages) return <div>加载PDF中...</div>; return <div className="p-4"> <Document file="/api/s3/download/?file=something.pdf" onLoadSuccess={onDocumentLoadSuccess} > {Array.from({ length: numPages }, (_, idx) => idx + 1) .map(page => ( <Page key={page} pageNumber={page} renderTextLayer={false} renderAnnotationLayer={false} /> ))} </Document> </div> } return <>{getDischargeSummaryView()}</>; }
4. 修复初始渲染逻辑
原代码中numPages初始为null,直接用Array(numPages)会导致异常,添加判断后避免不必要的渲染错误。
核心原因
pdfjs-dist作为CommonJS模块,在ES模块环境下的导出机制不兼容命名导入;- Next.js的服务端渲染(SSR)会执行客户端API,引发运行时错误;
- 初始渲染时
numPages为null,导致数组生成逻辑异常。
内容的提问来源于stack exchange,提问作者Shekhar
相关产品推荐
相关产品推荐

