Next.js集成pdfjs-dist遇webpack加载器配置错误求助
Next.js集成pdfjs-dist时的Webpack加载器错误
错误信息
./node_modules/pdfjs-dist/webpack.js Module parse failed: Unexpected token (22:43) You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders | if (typeof window !== "undefined" && "Worker" in window) { | pdfjs.GlobalWorkerOptions.workerPort = new Worker( > new URL("./build/pdf.worker.js", import.meta.url) | ); | }
当前导入方式
import pdfjsLib from 'pdfjs-dist/webpack' import { getDocument, PDFWorker } from 'pdfjs-dist';
环境背景
- 在React 18.x项目中可正常运行,但Next.js项目打包阶段报错
- 已尝试配置
next-transpile-modules处理pdfjs-dist,也在next.config.js中添加了加载器规则,但问题未解决
当前next.config.js配置
const withImages = require("next-images"); const withPlugins = require("next-compose-plugins"); const withTM = require('next-transpile-modules')(['pdfjs-dist'],{ resolveSymlinks: false, debug: true, }); module.exports = withPlugins([withImages],[withTM], { module: { async rewrites() { return [ { source: "/colleges-campus-plments/test", destination: "/employer", }, ]; }, rules: [ { test: /\.(png|jpe?g|gif|svg|woff2?|eot|ttf|otf|pdf)(\?.*)?$/i, include: /node_modules\/pdfjs-dist/, use: { loader: 'url-loader', options: { limit: 8192, fallback: 'file-loader', publicPath: '/_next/static/', outputPath: 'static/', name: '[name]-[hash].[ext]', esModule: false } } } ], }, async headers() { return [ { source: "/(.*).(jpg|jpeg|png|gif|svg|webp|jfif)", headers: [ { key: "Cache-Control", value: "public,max-age=31536000,immutable", }, ], }, { source: "/_next/image(.*)", headers: [ { key: "Cache-Control", value: "public,max-age=31536000,immutable", }, ], }, ]; }, images: { domains: ["logo.clearbit.com", "s3.ap-south-1.amazonaws.com"], }, webpack: (config, { isServer }) => { config.module.rules.push({ test: /\.(png|jpe?g|gif|svg|woff2?|eot|ttf|otf|pdf)(\?.*)?$/i, include: /node_modules\/pdfjs-dist/, use: { loader: 'url-loader', options: { limit: 8192, fallback: 'file-loader', publicPath: '/_next/static/', outputPath: 'static/', name: '[name]-[hash].[ext]', esModule: false } } }); return config; }, });
解决方案
1. 调整导入方式,规避webpack入口文件问题
放弃使用pdfjs-dist/webpack入口,直接导入核心库并手动配置Worker路径:
import * as pdfjsLib from 'pdfjs-dist'; import pdfjsWorker from 'pdfjs-dist/build/pdf.worker.entry'; pdfjsLib.GlobalWorkerOptions.workerSrc = pdfjsWorker;
2. 修正next.config.js的配置错误
- 移除顶层无效的
module字段:Next.js不识别顶层module配置,webpack规则需放在webpack函数内 - 将
rewrites移至顶层配置:之前把rewrites嵌套在module里是错误的,会导致配置失效 - 优化webpack规则,添加Worker文件处理逻辑
修改后的next.config.js:
const withImages = require("next-images"); const withPlugins = require("next-compose-plugins"); const withTM = require('next-transpile-modules')(['pdfjs-dist'], { resolveSymlinks: false, debug: true, }); module.exports = withPlugins([withImages, withTM], { // 修正rewrites位置,移至顶层 async rewrites() { return [ { source: "/colleges-campus-plments/test", destination: "/employer", }, ]; }, async headers() { return [ { source: "/(.*).(jpg|jpeg|png|gif|svg|webp|jfif)", headers: [ { key: "Cache-Control", value: "public,max-age=31536000,immutable", }, ], }, { source: "/_next/image(.*)", headers: [ { key: "Cache-Control", value: "public,max-age=31536000,immutable", }, ], }, ]; }, images: { domains: ["logo.clearbit.com", "s3.ap-south-1.amazonaws.com"], }, webpack: (config, { isServer }) => { // 处理pdfjs-dist的静态资源 config.module.rules.push({ test: /\.(png|jpe?g|gif|svg|woff2?|eot|ttf|otf)$/i, include: /node_modules\/pdfjs-dist/, type: 'asset/resource', generator: { filename: 'static/[name]-[hash].[ext]' } }); // 处理Worker文件,禁用ES模块格式 config.module.rules.push({ test: /pdf\.worker\.entry\.js$/, include: /node_modules\/pdfjs-dist/, loader: 'worker-loader', options: { filename: '[name].[hash].js', esModule: false } }); return config; }, });
3. 安装缺失依赖
确保安装worker-loader用于处理Worker文件:
npm install worker-loader --save-dev # 或使用yarn yarn add worker-loader --dev
4. 客户端组件使用示例
在Next.js组件中用useEffect确保代码在浏览器环境执行(Worker无法在服务端运行):
import { useEffect, useRef } from 'react'; import * as pdfjsLib from 'pdfjs-dist'; import pdfjsWorker from 'pdfjs-dist/build/pdf.worker.entry'; export default function PDFViewer() { const canvasRef = useRef(null); useEffect(() => { pdfjsLib.GlobalWorkerOptions.workerSrc = pdfjsWorker; async function loadPDF() { // 替换为你的PDF文件路径 const pdf = await pdfjsLib.getDocument('/sample.pdf').promise; const page = await pdf.getPage(1); const viewport = page.getViewport({ scale: 1.5 }); const canvas = canvasRef.current; const context = canvas.getContext('2d'); canvas.height = viewport.height; canvas.width = viewport.width; await page.render({ canvasContext: context, viewport: viewport }).promise; } loadPDF(); }, []); return <canvas ref={canvasRef} />; }
内容的提问来源于stack exchange,提问作者Prabha Shanker
相关产品推荐
相关产品推荐

