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

如何在NestJS Mailer的EJS模板中定义邮件主题?

实现方案

完全可以实现,NestJS Mailer本身没有原生提供从模板提取主题的能力,但通过简单的自定义封装就能适配EJS、Handlebars等所有模板引擎,满足你把主题和正文都写在模板文件里的需求。

核心思路

先读取模板文件,分步骤完成渲染:

  1. 解析渲染模板中的主题部分,得到最终的邮件主题
  2. 解析渲染剩余的正文内容,得到HTML邮件正文
  3. 把解析出来的主题和正文传给MailerService.sendMail方法即可

具体实现(以EJS为例)

步骤1:按约定格式写EJS模板

你可以直接用你期望的开头声明Subject的格式,也可以用EJS变量存主题方便处理动态内容:

Subject: '你好 <%= username %>,这是你的验证邮件'

<!DOCTYPE html>
<html>
<body>
  <p>尊敬的 <%= username %>:</p>
  <p>你的账号验证码是:<strong><%= code %></strong></p>
  <p>验证码15分钟内有效,请尽快完成验证</p>
</body>
</html>

步骤2:封装模板解析工具方法

import * as ejs from 'ejs';
import * as fs from 'fs';
import { join } from 'path';

interface ParsedEmailTemplate {
  // 解析得到的邮件主题
  subject: string;
  // 解析得到的HTML正文
  html: string;
}

/**
 * 解析邮件模板,提取主题和正文
 * @param templateName 模板文件名(不需要后缀)
 * @param context 模板渲染需要的变量上下文
 */
async function parseEmailTemplate(
  templateName: string,
  context: Record<string, any>
): Promise<ParsedEmailTemplate> {
  // 替换为你实际存放模板文件的目录路径
  const templatePath = join(__dirname, './email-templates', `${templateName}.ejs`);
  const templateContent = fs.readFileSync(templatePath, 'utf-8');

  // 1. 提取模板中声明的Subject
  const subjectReg = /^Subject: '([^']+)'/;
  const subjectMatch = templateContent.match(subjectReg);
  if (!subjectMatch) {
    // 模板没声明主题的话返回默认值,也可以直接抛错误
    return {
      subject: '默认邮件主题',
      html: await ejs.render(templateContent, context)
    }
  }

  const rawSubject = subjectMatch[1];
  // 2. 渲染主题中的动态变量
  const subject = await ejs.render(rawSubject, context);
  // 3. 去掉模板中的Subject声明行,渲染剩余的正文内容
  const htmlContent = templateContent.replace(subjectReg, '').trim();
  const html = await ejs.render(htmlContent, context);

  return { subject, html };
}

步骤3:业务代码中调用

import { Injectable } from '@nestjs/common';
import { MailerService } from '@nestjs-modules/mailer';

@Injectable()
export class EmailService {
  constructor(private readonly mailerService: MailerService) {}

  async sendVerifyEmail(receiverEmail: string, username: string, verifyCode: string) {
    // 解析模板得到主题和正文
    const { subject, html } = await parseEmailTemplate('verify-email', {
      username,
      code: verifyCode
    });

    // 调用NestJS Mailer发送邮件
    await this.mailerService.sendMail({
      to: receiverEmail,
      subject,
      html
    });
  }
}

其他模板引擎适配

如果用Handlebars等其他模板引擎,只需要把上面工具方法中的ejs.render替换为对应模板引擎的渲染方法即可,逻辑完全一致。

可选优化

如果你不想改动现有调用逻辑,也可以自定义NestJS Mailer的模板适配器,重写render方法自动提取主题,直接在适配器内部完成主题的注入,上层业务不用做任何修改。

内容的提问来源于stack exchange,提问作者Nikolaj Dam Larsen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 14:15:02