NextJS TypeScript中用nodemailer发邮件遇setImmediate未定义错误求解决
解决办法与替代方案
一、修复setImmediate is not defined错误
这个错误的核心原因是nodemailer依赖Node.js的API(如setImmediate),而你的代码可能运行在客户端环境或Edge Runtime中,这些环境不提供该API。解决步骤如下:
1. 确保代码运行在服务器端
将邮件发送逻辑放在Next.js的服务器端环境中,比如:
- App Router的API路由(
app/api/xxx/route.ts) - Pages Router的API路由(
pages/api/xxx.ts) - Server Action
- Server Component
2. 修正代码中的无效调用
删除代码中多余的transport.sendMail()空调用,这行代码会无参数触发sendMail,属于无效逻辑且可能引发额外错误。
3. 显式指定Node.js运行时(App Router)
如果使用App Router,默认部分场景会使用Edge Runtime,需在API路由或Server Action文件顶部添加:
export const runtime = 'nodejs';
修复后的完整API路由示例(App Router + TypeScript)
// app/api/send-email/route.ts import nodemailer from 'nodemailer'; // 指定使用Node.js运行时 export const runtime = 'nodejs'; export async function POST(request: Request) { try { // 创建MailTrap传输器 const transport = nodemailer.createTransport({ host: "sandbox.smtp.mailtrap.io", port: 2525, auth: { user: "你的MailTrap用户ID", pass: "你的MailTrap密码" }, tls: { rejectUnauthorized: false } }); // 邮件内容配置 const mailData = { from: 'sender@example.com', to: 'recipient@example.com', subject: `Message From Test`, text: '测试邮件文本内容', html: `<div>Testing MailTrap with NextJS</div>` }; // 发送邮件(改用async/await替代回调,更符合TS风格) const info = await transport.sendMail(mailData); return Response.json({ message: '邮件发送成功', response: info.response }, { status: 200 }); } catch (error) { console.error('邮件发送失败:', error); return Response.json({ error: '邮件发送失败' }, { status: 500 }); } }
二、Next.js中发送邮件的替代方案
如果不想处理SMTP相关的环境兼容问题,可以选择更适配Next.js的第三方邮件服务:
1. 使用Server Action发送邮件
无需创建API路由,直接在组件中调用服务器端函数:
// app/actions/sendEmail.ts 'use server'; import nodemailer from 'nodemailer'; export async function sendEmail() { const transport = nodemailer.createTransport({ host: "sandbox.smtp.mailtrap.io", port: 2525, auth: { user: "你的MailTrap用户ID", pass: "你的MailTrap密码" }, tls: { rejectUnauthorized: false } }); const mailData = { from: 'sender@example.com', to: 'recipient@example.com', subject: `Message From Test`, text: '测试邮件内容', html: `<div>Testing MailTrap with NextJS Server Action</div>` }; try { const info = await transport.sendMail(mailData); return { success: true, message: '邮件已发送: ' + info.response }; } catch (error) { return { success: false, error: (error as Error).message }; } }
2. 改用Resend/SendGrid等服务的SDK
这类服务提供了更简洁的SDK,无需配置SMTP,且天然适配Next.js:
以Resend为例:
- 安装依赖:
npm install resend - 编写API路由:
// app/api/send-email/route.ts import { Resend } from 'resend'; // 初始化Resend(密钥可存在环境变量中) const resend = new Resend(process.env.RESEND_API_KEY); export async function POST(request: Request) { try { const data = await resend.emails.send({ from: 'sender@example.com', to: ['recipient@example.com'], subject: '测试邮件', html: '<div>使用Resend发送的NextJS测试邮件</div>' }); return Response.json(data, { status: 200 }); } catch (error) { return Response.json({ error }, { status: 500 }); } }
内容的提问来源于stack exchange,提问作者Rytpiv Mahi
相关产品推荐
相关产品推荐

