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

Vercel部署Express+Nodemailer邮件API时Serverless函数崩溃问题

Vercel部署Express邮件API时ES模块与CommonJS冲突的解决办法

我在Vercel部署一个仅处理邮件API的Express后端应用,用Nodemailer实现邮件发送功能,但部署后Serverless函数崩溃,报错提示require is not defined in ES module scope。


我的package.json

package.json内容

我的server.js代码

import express from "express";
import cors from "cors";
import bodyParser from "body-parser";
import nodemailer from 'nodemailer';
import { config } from "dotenv";
config()

const app = express();
app.use(bodyParser.json({ limit: "100mb" }));
app.use(bodyParser.urlencoded({ limit: "100mb", extended: true }));
app.use(cors({credentials:true}));


const transporter = nodemailer.createTransport({
     service: 'gmail',
     auth: {
         user: process.env.EMAIL_USER, // 使用环境变量而非硬编码
         pass: process.env.EMAIL_PASSWORD, // 使用环境变量而非硬编码
}
});

function sendEmail(req, res) {
const { name, email, message } = req.body;

const mailOptions = {
    from: process.env.EMAIL_USER,
    to: process.env.RECIEVER_MAIL,
    subject: `You got a message from ${name}`,
    html: `<h4>Hello, Someone Contacted you through contact Form</h4>
    <h4>Name: ${name}</h4>
    <h4>Email: ${email}</h4>
    <p>Message: ${message}</p>
    `
    ,
};

transporter.sendMail(mailOptions, function (error, info) {
    if (error) {
        console.log(error);
        res.status(500).json({code:500, error: 'Failed to send email' });
    } else {
        console.log('Email sent: ' + info.response);
        res.status(200).json({code:200,success: 'Email sent successfully' });
    }
});
}
app.get('/', (req, res)=>{
    res.send("This is my api running!")
})

app.post('/contact', (req, res) => {
    sendEmail(req, res);
});

const PORT = process.env.PORT || 5000;

app.listen(process.env.PORT,()=>{
    console.log(`App listening on port ${PORT}`)
})

我的vercel.json配置

{
"version": 2,
"builds": [
  {
    "src": "server.js",
    "use": "@now/node"
  }
],
"routes": [
  {
    "src": "/(.*)",
    "dest": "server.js"
  }
]
}

报错日志

Uncaught Exception {"errorType":"ReferenceError","errorMessage":"require is not defined in ES module scope, you can use import instead\nThis file is being treated as an ES module because it has a '.js' file extension and '/var/task/package.json' contains "type": "module". To treat it as a CommonJS script, rename it to use the '.cjs' file extension.","stack":["ReferenceError: require is not defined in ES module scope, you can use import instead","This file is being treated as an ES module because it has a '.js' file extension and '/var/task/package.json' contains "type": "module". To treat it as a CommonJS script, rename it to use the '.cjs' file extension."," at file:///var/task/___now_launcher.js:1:18"," at ModuleJob.run (node:internal/modules/esm/module_job:194:25)"]}
Uncaught Exception {"errorType":"ReferenceError","errorMessage":"require is not defined in ES module scope, you can use import instead\nThis file is being treated as an ES module because it has a '.js' file extension and '/var/task/package.json' contains "type": "module". To treat it as a CommonJS script, rename it to use the '.cjs' file extension.","stack":["ReferenceError: require is not defined in ES module scope, you can use import instead","This file is being treated as an ES module because it has a '.js' file extension and '/var/task/package.json' contains "type": "module". To treat it as a CommonJS script, rename it to use the '.cjs' file extension."," at file:///var/task/___now_launcher.js:1:18"," at ModuleJob.run (node:internal/modules/esm/module_job:194:25)"]}
Unknown application error occurred
Runtime.Unknown


解决办法

原因分析

报错核心是:项目package.json中设置了"type": "module",所有.js文件被当作ES模块处理,但Vercel旧版构建器@now/node(已弃用)内部使用CommonJS的require语法,与ES模块环境冲突,导致启动器崩溃。

修复步骤

  1. 替换Vercel构建器
    将vercel.json里的@now/node替换为官方推荐的@vercel/node(支持ES模块):

    {
      "version": 2,
      "builds": [
        {
          "src": "server.js",
          "use": "@vercel/node"
        }
      ],
      "routes": [
        {
          "src": "/(.*)",
          "dest": "server.js"
        }
      ]
    }
    
  2. 适配Serverless环境的启动逻辑
    Vercel Serverless函数不需要调用app.listen(),需导出Express实例供平台调用,修改server.js最后部分:

    // 移除原有listen代码
    // const PORT = process.env.PORT || 5000;
    // app.listen(process.env.PORT,()=>{
    //     console.log(`App listening on port ${PORT}`)
    // })
    
    // 导出Express实例
    export default app;
    
  3. 确认环境变量配置
    在Vercel项目的「Settings」→「Environment Variables」中,正确配置EMAIL_USER、EMAIL_PASSWORD、RECIEVER_MAIL三个变量,确保部署时能正常读取。

  4. 验证Gmail权限(可选)
    若使用Gmail发送邮件,需开启「不太安全的应用访问」(或为开启2FA的账号生成App密码),否则会被Google拦截。

完成以上步骤后重新部署,即可解决问题。


内容的提问来源于stack exchange,提问作者Lokesh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 15:59:55