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

带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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 21:18:17