基于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
相关产品推荐
相关产品推荐

