Vercel部署Express服务后pdf-to-png-converter模块报错求助
问题场景
本地运行正常的PDF转PNG Express服务,部署到Vercel后报错:
Setting up fake worker failed: "Cannot find module '/var/task/node_modules/pdfjs-dist/legacy/build/pdf.worker.mjs' imported from /var/task/node_modules/pdfjs-dist/legacy/build/pdf.mjs"
核心代码如下:
转换函数:
import { pdfToPng } from "pdf-to-png-converter"; const convertPdfToImg = async (filePath: string, output: string) => { const pngPage = await pdfToPng(filePath, { viewportScale: 2.0, outputFileMask: "buffer", outputFolder: output, }); return pngPage; }; export default convertPdfToImg;
调用代码:
const pdfBuffer = req.file.buffer; const tempDir = path.join("/tmp", "temp"); if (!fs.existsSync(tempDir)) { fs.mkdirSync(tempDir, { recursive: true }); } const pdfFilePath = path.join(tempDir, `${req.file.originalname}.pdf`); fs.writeFileSync(pdfFilePath, pdfBuffer); const content = await convertPdfToImg(pdfFilePath, tempDir);
解决方案
方案1:手动指定pdfjs-worker路径
pdf-to-png-converter依赖pdfjs-dist,在Vercel的Serverless环境中,pdfjs无法自动解析worker路径,需手动配置:
修改转换函数代码:
import { pdfToPng } from "pdf-to-png-converter"; import * as pdfjsLib from 'pdfjs-dist/legacy/build/pdf.mjs'; import pdfjsWorker from 'pdfjs-dist/legacy/build/pdf.worker.mjs'; // 强制指定worker文件路径 pdfjsLib.GlobalWorkerOptions.workerSrc = pdfjsWorker; const convertPdfToImg = async (filePath: string, output: string) => { const pngPage = await pdfToPng(filePath, { viewportScale: 2.0, outputFileMask: "buffer", outputFolder: output, }); return pngPage; }; export default convertPdfToImg;
方案2:配置Vercel打包规则,确保worker文件被包含
在项目根目录创建vercel.json,添加打包配置,让Vercel将worker文件包含到部署包中:
{ "functions": { "api/**/*.js": { // 替换为你的Express入口文件实际路径 "includeFiles": "node_modules/pdfjs-dist/legacy/build/pdf.worker.mjs" } } }
方案3:替换为无需worker的依赖(备选)
如果前两种方案无效,可以尝试使用pdf-poppler(依赖poppler工具)。需要在package.json中添加postinstall脚本确保Vercel环境安装poppler:
"scripts": { "postinstall": "apt-get update && apt-get install -y poppler-utils" }
注意:Vercel的Serverless环境对系统命令有一定限制,此方案可能需要额外验证。
问题原因
本地Node.js环境是完整运行环境,打包工具能正确处理worker模块的路径解析;但Vercel的Serverless函数会对代码进行精简打包,可能遗漏pdf.worker.mjs文件,或者打包后的路径结构导致pdfjs无法自动找到worker文件,手动指定路径或配置打包规则即可解决。
内容的提问来源于stack exchange,提问作者nyominkhat itwizard

