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

在PUG引擎中使用Nodemailer遭遇require未定义问题求助

解决PUG中使用Nodemailer时"require is not defined"的问题

这个错误的核心原因很直白:require是Node.js专属的模块加载语法,浏览器环境(包括PUG渲染后在前端运行的<script>标签)完全不支持这个功能。你的Nodemailer代码是纯服务器端逻辑,根本不能直接放到客户端脚本里执行。

下面是具体的解决方案,分两步走:


1. 把Nodemailer代码留在服务器端,封装成API接口

先保留你原本能正常运行的Nodemailer代码,把它改成可被接口调用的函数,比如用Express框架创建一个POST接口:

// 服务器端的 mail-service.js 文件
"use strict";
const nodemailer = require("nodemailer");
let config = require("../js/config");

// 封装邮件发送函数
async function sendStudyListEmail() {
  // 创建 transporter 实例(和你原来的代码一致)
  let transporter = nodemailer.createTransport({
    host: "mail.mywebsite.com",
    port: 8889,
    secure: false, // true 对应465端口,其他端口用false
    auth: {
      user: config.user,
      pass: config.pass
    },
  });

  // 可选:验证服务器连接
  transporter.verify(function(error, success) {
    if (error) {
      console.error("邮件服务器连接失败:", error);
    } else {
      console.log("邮件服务器已就绪");
    }
  });

  // 发送邮件
  let info = await transporter.sendMail({
    from: '"E-Mail Service ☕" <me@mywebsite.com>',
    to: "customer@domain.com",
    subject: "Your List of Selected Studies 📌",
    html: "<b>Test e-mail</b> starts here. And ends <i>here</i>",
  });

  console.log("邮件已发送,Message ID:", info.messageId);
  return info;
}

// 导出函数供路由使用
module.exports = sendStudyListEmail;

然后在你的Express路由中添加一个POST接口,用来触发这个邮件发送函数:

// 服务器端的 routes/email.js 文件
const express = require('express');
const router = express.Router();
const sendStudyListEmail = require('../mail-service.js');

// 创建发送邮件的接口
router.post('/send-study-email', async (req, res) => {
  try {
    const emailInfo = await sendStudyListEmail();
    res.status(200).json({
      success: true,
      message: "邮件发送成功",
      messageId: emailInfo.messageId
    });
  } catch (err) {
    console.error("发送邮件出错:", err);
    res.status(500).json({
      success: false,
      message: "邮件发送失败",
      error: err.message
    });
  }
});

module.exports = router;

别忘了把这个路由挂载到你的Express主应用里:

// 服务器端的 app.js 文件
const emailRoutes = require('./routes/email');
app.use('/api', emailRoutes);

2. 在PUG的客户端脚本中调用服务器接口

现在,你可以在PUG文件里写客户端脚本,通过AJAX请求调用上面的服务器接口,触发邮件发送:

// 你的PUG文件内容
html
  body
    h1 邮件发送测试
    // 添加一个按钮触发邮件发送
    button#sendEmailBtn 发送测试邮件

    script.
      // 客户端脚本:调用服务器接口
      const sendBtn = document.getElementById('sendEmailBtn');
      sendBtn.addEventListener('click', async () => {
        try {
          sendBtn.disabled = true;
          sendBtn.textContent = '发送中...';

          const response = await fetch('/api/send-study-email', {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json'
              // 如果需要动态传递收件人、邮件内容,可以在这里加body
              // body: JSON.stringify({ to: 'user@example.com', subject: '自定义主题' })
            }
          });

          const result = await response.json();
          if (result.success) {
            alert(`邮件发送成功!Message ID: ${result.messageId}`);
          } else {
            alert(`邮件发送失败:${result.message}`);
          }
        } catch (err) {
          console.error('请求出错:', err);
          alert('请求出错,请稍后重试');
        } finally {
          sendBtn.disabled = false;
          sendBtn.textContent = '发送测试邮件';
        }
      });

重要注意事项

  • 绝对不要把邮箱的账号密码暴露在客户端代码里:你的config.js里的user和pass必须留在服务器端,一旦泄露到前端,任何人都可以用你的邮箱发送垃圾邮件。
  • 如果需要动态传递邮件内容(比如用户输入的收件人、自定义正文),可以通过POST请求的body参数传给服务器,服务器接收后再调整sendMail的参数即可。
  • 确保你的服务器已经正确配置了CORS(如果前端和后端不在同一个域名下),不过如果是同域名部署的话,这一步可以忽略。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 20:02:41