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

基于craco+TypeScript的React项目集成react-pdf报错求助

问题:React+TypeScript+Craco项目集成react-pdf报错

我使用Craco构建React+TypeScript项目,尝试集成react-pdf来展示PDF文件,但出现报错(报错截图:报错截图)。

现有配置

craco.config.js

module.exports = {
  plugins: [
    {
      plugin: CracoLessPlugin,
      options: {
        lessLoaderOptions: {
          lessOptions: {
            modifyVars: { '@primary-color': '#1c48f2' },
            modules: true,
            javascriptEnabled: true
          }
        },
      }
    },
    { plugin: CracoTerserOverridePlugin }
  ],
  webpack: {
    options: {
      presets: [
        "@babel/preset-env",
        "@babel/preset-react"
      ],
      plugins: [
          [
            "@babel/plugin-proposal-class-properties",
            "@babel/plugin-syntax-class-properties"
          ]
      ],
    },
    plugins: process.env.NODE_ENV === 'production' ? [
      ...
    }),
  ] : [],
  }
};

tsconfig.json

{
  "compilerOptions": {
    "baseUrl": "src",
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx"
  },
  "include": [
    "src"
  ]
}

我尝试调整配置项的位置,但问题仍未解决,推测需要添加其他配置,希望得到解决方案。


解决方案

1. 确保依赖安装完整

首先确认已安装react-pdf及相关依赖:

npm install react-pdf process
# 或
yarn add react-pdf process

2. 更新craco.config.js配置

react-pdf需要webpack处理PDF文件、配置worker加载,同时你的项目使用TypeScript,需补充babel的TypeScript预设。更新后的配置如下:

const CracoLessPlugin = require('craco-less');
const CracoTerserOverridePlugin = require('craco-terser-override');
const { ProvidePlugin } = require('webpack');

module.exports = {
  plugins: [
    {
      plugin: CracoLessPlugin,
      options: {
        lessLoaderOptions: {
          lessOptions: {
            modifyVars: { '@primary-color': '#1c48f2' },
            modules: true,
            javascriptEnabled: true
          }
        },
      }
    },
    { plugin: CracoTerserOverridePlugin }
  ],
  webpack: {
    plugins: [
      // 注入process对象,解决react-pdf依赖问题
      new ProvidePlugin({
        process: 'process/browser',
      }),
      ...(process.env.NODE_ENV === 'production' ? [
        // 保留你的生产环境原有插件
      ] : [])
    ],
    configure: (webpackConfig) => {
      // 添加PDF文件的loader配置
      webpackConfig.module.rules.push({
        test: /\.pdf$/,
        use: [
          {
            loader: 'file-loader',
            options: {
              name: '[name].[ext]',
              outputPath: 'static/pdfs/',
            },
          },
        ],
      });

      // 为babel添加TypeScript预设
      const babelRule = webpackConfig.module.rules.find(rule => 
        rule.oneOf?.some(subRule => subRule.loader?.includes('babel-loader'))
      );
      if (babelRule) {
        babelRule.oneOf.forEach(subRule => {
          if (subRule.loader?.includes('babel-loader')) {
            subRule.options.presets.push('@babel/preset-typescript');
          }
        });
      }

      // 配置react-pdf的worker别名,避免加载错误
      webpackConfig.resolve.alias = {
        ...webpackConfig.resolve.alias,
        'pdfjs-dist/build/pdf.worker.entry': 'pdfjs-dist/build/pdf.worker.entry.js',
      };

      return webpackConfig;
    },
  },
};

3. 修复tsconfig.json类型配置(可选)

如果遇到类型提示错误,在tsconfig.json的compilerOptions中添加:

"types": ["react-pdf"]

4. 组件使用示例

import { useState } from 'react';
import { Document, Page } from 'react-pdf';
import samplePdf from './assets/sample.pdf'; // 导入本地PDF文件

const PDFViewer = () => {
  const [numPages, setNumPages] = useState<number>(0);
  const [currentPage, setCurrentPage] = useState<number>(1);

  const handleDocumentLoad = ({ numPages }: { numPages: number }) => {
    setNumPages(numPages);
  };

  return (
    <div className="pdf-viewer">
      <Document file={samplePdf} onLoadSuccess={handleDocumentLoad}>
        <Page pageNumber={currentPage} />
      </Document>
      <div className="page-controls">
        <button 
          disabled={currentPage === 1} 
          onClick={() => setCurrentPage(prev => prev - 1)}
        >
          上一页
        </button>
        <span>第 {currentPage} 页 / 共 {numPages} 页</span>
        <button 
          disabled={currentPage === numPages} 
          onClick={() => setCurrentPage(prev => prev + 1)}
        >
          下一页
        </button>
      </div>
    </div>
  );
};

export default PDFViewer;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 04:05:54