Node.js邮件内容构建优化咨询:替代硬编码实现方案
更优的Node.js邮件内容构建方案
问题背景
我基于Node.js开发业务功能,需根据业务执行结果向支持团队及用户发送邮件,当前采用硬拼接HTML标签的方式构建邮件内容,代码如下:
let emailStartTags = "<html><body><p>Hi Team,</p><p>"; const emailEndTags = "</p><p>Thanks,<br>ABC Support</p></body></html>" const Subject = `DEV Order No 1234` let emailContent=""; emailContent+=emailStartTags; const s3FilesList = await this.getFilesFromS3Directory(directoryName) emailContent+="<p>S3 files are ${s3FilesList}<p>" emailContent+=emailEndTags await this.sendEmail(emailContent,Subject,From,To);
请问是否有更优的邮件内容构建方式替代上述硬编码实现?比如使用带getter/setter的邮件类,若可行请提供参考方案。
方案一:模板引擎(推荐)
硬拼接HTML的核心痛点是维护成本高、易出现标签语法错误,模板引擎能实现内容与结构分离,常用的有EJS、Handlebars等,以EJS为例:
- 安装依赖
npm install ejs
- 创建独立的邮件模板文件(如
order-notification.ejs)
<html> <body> <p>Hi Team,</p> <p>S3 files are <%= s3FilesList %></p> <p>Thanks,<br>ABC Support</p> </body> </html>
- 在业务代码中渲染模板
const ejs = require('ejs'); const fs = require('fs').promises; async function renderEmailTemplate(data) { const templateContent = await fs.readFile('./order-notification.ejs', 'utf8'); return ejs.render(templateContent, data); } // 业务逻辑中调用 const subject = `DEV Order No 1234`; const s3FilesList = await this.getFilesFromS3Directory(directoryName); const emailContent = await renderEmailTemplate({ s3FilesList }); await this.sendEmail(emailContent, subject, From, To);
方案二:封装带getter/setter的邮件类
如果需要更强的封装性和数据校验能力,可以创建邮件构建类,把动态数据、模板结构统一管理:
class OrderEmailBuilder { constructor() { this._recipient = 'Team'; this._s3Files = []; this._orderNumber = ''; } // 收件人称呼的getter/setter set recipient(type) { if (typeof type === 'string' && type.trim()) { this._recipient = type.trim(); } else { throw new Error('Recipient must be a valid string'); } } get recipient() { return this._recipient; } // S3文件列表的getter/setter set s3Files(files) { if (Array.isArray(files)) { this._s3Files = files; } else { throw new Error('S3 files must be an array'); } } get s3Files() { return this._s3Files; } // 订单号的getter/setter set orderNumber(num) { if (typeof num === 'string' && num.trim()) { this._orderNumber = num.trim(); } else { throw new Error('Order number must be a valid string'); } } get orderNumber() { return this._orderNumber; } // 自动生成邮件主题 get subject() { return `DEV Order No ${this._orderNumber}`; } // 构建最终HTML内容 buildHtmlContent() { const filesListHtml = this._s3Files.map(file => `<li>${file}</li>`).join(''); return ` <html> <body> <p>Hi ${this._recipient},</p> <p>S3 files are:</p> <ul>${filesListHtml}</ul> <p>Thanks,<br>ABC Support</p> </body> </html> `.trim(); } } // 业务代码中使用 const emailBuilder = new OrderEmailBuilder(); emailBuilder.orderNumber = '1234'; emailBuilder.s3Files = await this.getFilesFromS3Directory(directoryName); const emailContent = emailBuilder.buildHtmlContent(); const subject = emailBuilder.subject; await this.sendEmail(emailContent, subject, From, To);
方案对比
- 模板引擎:适合内容复杂、需要频繁修改邮件结构的场景,非开发人员也能编辑模板,维护成本低;
- 邮件类:适合逻辑固定、对数据格式有严格要求的场景,封装性强,能统一控制数据校验和内容生成逻辑。
内容的提问来源于stack exchange,提问作者Pavan Kumar
相关产品推荐
相关产品推荐

