带ESM依赖react-pdf的Express服务器部署Vercel报错求助
解决Vercel部署ESM+React-PDF Express服务的语法错误
我有一个使用ESM依赖react-pdf的Express服务器,用TypeScript JSX(.tsx文件)渲染PDF。本地运行正常,但部署到Vercel时出现以下语法错误:
/var/task/api/pdf.js:1 (function (exports, require, module, __filename, __dirname) { import React from "react"; ^^^^^^ SyntaxError: Cannot use import statement outside a module at new Script (node:vm:117:7) at Object.precompile (/opt/rust/bytecode.js:2:426) at Module.<anonymous> (/opt/rust/bytecode.js:2:1392) at A.l._compile (/opt/rust/bytecode.js:2:3145) at Object..js (node:internal/modules/cjs/loader:1895:10) at Module.load (node:internal/modules/cjs/loader:1465:32) at Function.<anonymous> (node:internal/modules/cjs/loader:1282:12) at /opt/rust/nodejs.js:2:12456 at Function.Rr (/opt/rust/nodejs.js:2:12834) at Ae.e.<computed>.Me._load (/opt/rust/nodejs.js:2:12426) Node.js process exited with exit status: 1. The logs above can help with debugging the issue.
相关核心代码如下:
import React from "react"; import express, { Request, Response } from "express"; import ReactPDF, { Document, Page, Text, View, StyleSheet, } from "@react-pdf/renderer"; const styles = StyleSheet.create({ page: { flexDirection: "row", backgroundColor: "#E4E4E4", }, section: { margin: 10, padding: 10, flexGrow: 1, }, }); const MyDocument = () => ( <Document> <Page size="A4" style={styles.page}> <View style={styles.section}> <Text>Section #1</Text> </View> <View style={styles.section}> <Text>Section #2</Text> </View> </Page> </Document> ); app.get("/pdf", async (req: Request, res: Response) => { const pdfStream = await ReactPDF.renderToStream(<MyDocument />); res.setHeader("Content-Type", "application/pdf"); pdfStream.pipe(res); });
解决方案
1. 声明项目为ESM模块
在项目根目录的package.json中添加:
"type": "module"
这会让Node.js将所有.js、.ts、.tsx文件当作ESM模块处理,避免CJS环境下的import语法冲突。
2. 配置Node.js版本与构建命令
- 在
package.json中指定兼容的Node.js版本(建议v18及以上,匹配本地开发环境):"engines": { "node": ">=18.0.0" } - 设置正确的TypeScript编译命令:
在package.json的scripts中添加:
同时检查"build": "tsc"tsconfig.json的关键配置:{ "compilerOptions": { "module": "ESNext", "target": "ESNext", "jsx": "react-jsx", "moduleResolution": "node", "outDir": "./dist" }, "include": ["api/**/*"] }
3. 适配Vercel Serverless Functions结构
- 确保编译后的文件输出到
dist/api目录 - 在Vercel项目设置中,将Functions Directory设置为
dist/api,让平台正确识别Serverless函数入口
4. 优化ESM模块兼容
如果仍存在第三方模块导入问题,在tsconfig.json中添加:
{ "compilerOptions": { "esModuleInterop": true, "allowSyntheticDefaultImports": true } }
这能解决部分ESM模块在CJS环境下的导入兼容问题。
5. 本地预验证
先在本地执行npm run build,再运行node dist/api/pdf.js,确认编译后的代码无语法错误后再部署,排除本地与构建环境的差异。
内容的提问来源于stack exchange,提问作者Evanss
相关产品推荐
相关产品推荐

