Node.js后端用emailjs遇ERR_REQUIRE_ESM错误,如何用dynamic import解决?
问题解决:CommonJS环境中使用ESM模块的emailjs
报错原因
你遇到的ERR_REQUIRE_ESM错误,是因为当前版本的emailjs包属于ESM模块(ECMAScript模块),而你的Express项目采用的是CommonJS模块系统(通过require()导入依赖),两者直接不兼容,因此需要用动态导入来解决。
什么是Dynamic Import(动态导入)
动态导入是ES6引入的特性,通过import()函数实现:
- 它返回一个Promise,以异步方式加载指定模块
- 允许在CommonJS模块中加载ESM模块,无需将整个项目转为ESM规范
- 支持按需加载模块,可优化项目启动或运行时的性能
项目中的具体修改步骤
1. 移除原有require导入
删掉代码里的const emailjs = require("emailjs")语句。
2. 在路由中使用动态导入
由于emailjs的操作是异步的,将/email路由的处理函数改为异步函数,用await import()加载模块,同时修正代码里的逻辑错误:
- 修复
subject字段的语法错误(原代码中request.body.from_namerequest.body.subject属于非法拼接) - 移除未调用的
sendContactData函数,简化逻辑 - 避免重复调用
response.send()(原代码中两次调用会触发报错)
修改后的完整代码:
const express = require("express") const app = express() const port = 3000 app.listen(port, () => { console.log(`Listening at port ${port}`) }) app.use(express.static("public")) app.use(express.json({limit: "1mb"})) app.post("/email", async (request, response) => { try { // 动态导入emailjs模块 const emailjs = await import("emailjs"); // 初始化emailjs emailjs.init("My top secret API key"); const tempParams = { from_name: request.body.from_name, reply_to: request.body.reply_to, // 修正subject拼接逻辑,可根据需求调整格式 subject: `${request.body.from_name} - ${request.body.subject}`, message: request.body.message, }; // 发送邮件 const res = await emailjs.send( "My top secret service ID", "My top secret template", tempParams ); console.log("邮件发送成功:", res); response.send("Success!"); } catch (error) { console.error("邮件发送失败:", error); // 返回错误状态码及提示 response.status(500).send("Failed to send email"); } console.log("接收的请求体:", request.body); })
3. 客户端正常运行的说明
你在客户端使用的是@emailjs/browser包的CDN链接,这个包是专门为浏览器环境构建的UMD模块,支持通过<script>标签直接引入,和后端的emailjs包属于不同的发布包,因此不存在模块兼容问题。
内容的提问来源于stack exchange,提问作者Ethan
相关产品推荐
相关产品推荐

