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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 18:32:22