You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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)会导致异常,添加判断后避免不必要的渲染错误。


核心原因

  1. pdfjs-dist作为CommonJS模块,在ES模块环境下的导出机制不兼容命名导入;
  2. Next.js的服务端渲染(SSR)会执行客户端API,引发运行时错误;
  3. 初始渲染时numPages为null,导致数组生成逻辑异常。

内容的提问来源于stack exchange,提问作者Shekhar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 02:12:35