$ emailens lint emails/welcome.html --fail-on-warning
emails/welcome.html
warn 7:10 outlook-windows-legacy display:flex Outlook Classic receives this flex box. The MSO branch needs a table.
warn 7:25 outlook-windows-legacy,yahoo-mail,yahoo-mail-android+2 gap Outlook Classic does not support "gap".
warn 8:32 gmail-web,outlook-windows-legacy,yahoo-mail-android+2 box-shadow Gmail does not support "box-shadow".
warn 14:5 yahoo-mail font-family Yahoo Mail drops an inline font-family that names a quoted font, like 'Courier New': that text shows in Yahoo's own font instead.
warn inboxPreview preheader-too-short Preheader is only 21 characters, so email clients may backfill with body text (recommended: 30+).
12 info: safe fallbacks, not problems. --info lists them.
1 file | 5 warnings
Failed: 5 warnings found (--failOnWarning)
See it rendered in Gmail, Outlook and Apple Mail, no signup: https://app.emailens.dev/try?utm_source=cli&utm_medium=lint
这是一个欢迎的邮件,有 弹性行和卡片阴影,检查与21
电子邮件客户端。 每个发现都有其行:列和出站代码(此处为2)
失败 。 该卡的圆角属于12个信息发现:
Outlook Classic 把它们画成正方形, 一个安全的倒置而不是问题。 这个
最后一个行仅在检查失败时显示; --quiet 放弃它,和 --json
从来没有过.
安装
npm install -g @emailens/cli
运行
emailens lint 'emails/*.html'
或者不安装: npx @emailens/cli lint email.html。HTML, 反应电子邮件
(单位:千美元).tsx编号 :.jsx),从扩展中检测出MJML和Maizzle并编译
首先,检查将发送的 HTML 。 没有帐户也没有
网络:分析在本地运行.
退出代码 : 0 干净, 1 错误, 2 警告为 --fail-on-warning,或
超过 --max-warnings。 。 。 .
在反应邮件计划中
npx @emailens/cli react-email
查找电子邮件文件夹 email dev 使用量(emails/, (中文(简体) ), src/emails/),使
每一个模板 与您的项目自己的反应电子邮件, PreviewProps 包括,
并检查 HTML。 本地导入,任何 npm 包和 tsconfig 路径工作,
包含子文件夹,以及 _components- 样式文件夹和文件无
默认导出被跳过 。 没有导出步骤 . --watch 重新检查保存.
过 --email-type transactional (或设置) "emailType": "transactional" 内
.emailensrc当文件夹持有登录、接收和提醒邮件时
不需要取消订阅链接. emailens lint emails/ 执行与命令相同
在您命名的文件夹上.
为什么不发罐头 或回放邮件自己的检查器?
我可以发邮件吗 是支持表:一个特征, 每个客户 它不读你的电子邮件。 此 CLI 的支持数据生成 从caniemail's(synced 2026-10-27),加上细胞一个真设备截图 矛盾的是,每个标记的"Observed"与其日期相矛盾. CLI补充的是 读取: 它找到您文件所用的特性, 在行处的分数, 每个分数 客户端,并退出非零.
反应邮件 4 添加兼容性
checker, 也通过电子邮件提供电源, 到它的预览 。 其CLI(email dev, (中文(简体) ),
build, (中文(简体) ), start, (中文(简体) ), export)没有检查命令,没有CI的退出代码
其文档。此 CLI 读取 React Email 文件为
以及MJML,Maizzle和Plain HTML,并失败了构建.
除了CSS的支持之外, lint 检查没有覆盖的内容:垃圾邮件信号,链接,
可访问性,图像,收件箱预览文本,大小,模板变量,
溢出,暗模式和移动对比, Outlook VML, 样式为客户端滴出,以及
客户目标黑客.
额外
lint 选项
| 旗帜 | 别名 | 说明 |
|---|---|---|
--format | -f | 输入格式 : html, (中文(简体) ), jsx, (中文(简体) ), mjml, (中文(简体) ), maizzle。 。 。 . .vue 实值 maizzle。检测到粘贴的 Vue 文件没有标记. |
--json | 作为 JSON 输出, 一行, 每一个发现, 包括信息 | |
--info | 列出信息调查结果。 默认情况下,它们被计算,而不是列出:它们是安全的后退而不是问题 | |
--fail-on-warning | 找到警告后退出 2 | |
--max-warnings | 如果超过 n 警告, 则失败 | |
--reporter github | 并打印出 GitHub 动作说明, 因此在拉取请求中每个发现都显示在其行上 。 不是用这个 --json | |
--quiet | -q | 失败后没有关于主机预览的行 |
--skip | 要跳过以逗号分隔的检查 : spam,links,accessibility,images,compatibility,inboxPreview,size,templateVariables,overflow,visual,darkContrast,mobileContrast,design,vml,styleSurvival,targeting | |
--targeting-policy | progressive (违约), strict,或 lenient | |
--email-type | transactional 放弃未订阅的要求; marketing 留着吧 默认 : emailType 内 .emailensrc | |
--gate | 同时将每封邮件发送到主机预发出闸门, 相对于通过的文件的上个版本, 它在回归时失败 。 计划,需要 EMAILENS_API_KEY |
A 类 .emailensrc 在工程中,VS代码扩展读取的文件可以设置
规定断开和跳过; --skip 在命令线上获胜.
Maizzle HTML 需要吗 @maizzle/framework@5 安装在CLI旁边。 A 类 .vue
文件需要 @maizzle/framework@6一个安装是一个主.
emailens design:它看起来还是你的设计吗?
lint 读取代码. design 读取渲染: 它绘制邮件为每个
客户端的活预览显示它,当你设计时,然后比较两者
按元素排列布局元素。 每一个元素都被比较到其位置,大小,
颜色、角、字体和间隔。 它给了判决 电子邮件
页面显示 : 准备, (中文(简体) ), 工作需求 或者说 断开还有原因.
$ emailens design emails/welcome.html --clients outlook-windows-legacy,gmail-web
✗ Outlook Classic Broken
Outlook Classic breaks your design.
- Columns that sit side by side in your design stack on top of each other.
- The email is drawn at a very different width from your design (54% of it).
- “Track your parcel” is moved (centre at 25% → 50% across the email) and 1107px wide instead of 300px.
- “Manage your order” is moved (centre at 75% → 50% across the email) and 1107px wide instead of 300px.
- Layout differs in 4 places. For example, “Hello, your order has shipped.” has width 600px instead of 552px.
and 1 more
✓ Gmail Ready
那封邮件同时放两个按钮 display:flex。经典展望
没有弹性框,所以按钮堆放在全宽处。 Gmail 设置自己的行
高度和文本颜色,但两页的截图在下方不同
其像素的2.5%,所以设计读取保持.
布局需要浏览器,所以这个命令也需要一个. sharp 添加像素
比较:
npm install -g @emailens/cli playwright-core sharp
npx playwright-core install chromium # a local Chromium, or:
export BROWSERLESS_URL=wss://... # your Browserless instance
emailens design email.html
或者不安装: npx -p @emailens/cli -p playwright-core -p sharp emailens design email.html。 。 。 .
| 旗帜 | 别名 | 说明 |
|---|---|---|
--clients | -c | 逗号分离客户端ID. 默认: 所有 21 |
--format | -f | 输入格式 : html, (中文(简体) ), jsx, (中文(简体) ), mjml, (中文(简体) ), maizzle |
--strict | 不仅在断层上,在需求上也失败了 | |
--json | 输出为 JSON | |
--quiet | -q | 没有旋转器 |
退出代码 : 0 当没有客户 打破设计, 1 当有人这样做时(或
--strict,当一个人改变它时).
它所覆盖的和它没有的:
- 它以光线模式运行,与我们每个客户端的直播预览相对. 没有 截图真实收件箱:正版的截图在主机计划中.
- 与
sharp已经安装,它也会截取两页并进行比较 按像素排列的像素, 和保存的电子邮件的寄件检查一样 。 这更同意 经常和人类评论员在一起 无sharp,它比较页面结构 只是,就像浏览器中的电子邮件页面那样,JSON没有diff。 。 。 . - 在无浏览器时,会话必须保持全程开放. 一个短
会话超时关闭浏览器 :
TIMEOUT,或通过 减少--clients。 。 。 . - 脚本在两页中被关闭. 电子邮件本身的图像和字体从 他们的地址.
- 预览使用的字体站( Segoe, Aptos, 苹果和Android)
系统字体)从app.emailens下载一次. 输入
~/.cache/emailens/fonts。 。 。 .
其他命令
emailens analyze email.html # score per client, findings by client
emailens analyze email.html --clients gmail-web,outlook-windows --json
emailens audit email.html # compatibility plus every other check
emailens preview email.html --dark-mode # transforms, analysis, dark mode simulation
emailens preview email.html --screenshots --out ./shots # needs BROWSERLESS_URL and playwright-core
emailens design email.html --clients gmail-web # still looks like the design? needs playwright-core (+ sharp)
emailens export email.html -o ./report # self-contained HTML report (--json for JSON)
emailens fix email.html -o fixed.html # AI fix, needs ANTHROPIC_API_KEY (--estimate: tokens only)
emailens clients # the 21 clients
cat email.html | emailens analyze - # stdin
emailens inbox wait
您的应用程序实际发送内容的CI步骤 。 让您的应用程序发送真正的邮件 (签名,重置,接收) 到您的电子邮件测试收件箱,然后等待它。 这个 当电子邮件不再是您在电子邮件中检查的邮件时, 或更改时失败 自上次到达以来:链接移动到中转、空出变量、新的 线条,一个图像不见了,一个大小跳跃, 签名停止通过。 代码、标志 和跟踪的ID在每次发送时都不同,不计数。 它需要一个 API 键.
export EMAILENS_API_KEY=... # app.emailens.dev/dashboard/api
SINCE=$(date +%s000) # before the send
npm run send-signup-email # your app sends it
emailens inbox wait --subject "Welcome" --since "$SINCE"
选项 : --subject, (中文(简体) ), --sender, (中文(简体) ), --inbox <id>, (中文(简体) ), --since (ISO时间,时代)
毫秒或持续时间,例如 5m; 默认2分钟后, --timeout (秒数,
默认 60,最多600), --fail-on all|check|drift|none (默认) all, (中文(简体) ),
--json。退出代码 : 0 传球, 1 换了, 2 没有到达或Emailens
无法到达 .
在你的测试中
与 lint作为断言。 每一次失败都会抛出
寻找和它的行,读你的 .emailensrc,并在维特,杰斯特和
包:测试.
import { render } from "@react-email/render";
import { expectEmailToPass } from "@emailens/cli/test";
test("welcome email passes", async () => {
expectEmailToPass(await render(<Welcome name="Ada" />));
});
选项 : failOnWarning, (中文(简体) ), skip (单位:千美元) --skip 名称, framework。 。 。 .
在 GitHub 动作
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npx -y @emailens/cli lint 'emails/*.html' --fail-on-warning --reporter github
--reporter github 在拉动请求中将每个发现都放在线上
已更改文件.
** glob不支持:使用单级通配符或列出文件.
对于拉动请求注释中每个客户的分数,请使用
行动。 。 。 .
托管
app.emailens.dev/try (英语) 给每个客户端发送电子邮件: 5个客户端没有账户, 21个都免费 一个 + Real 计划会添加真实的设备截图: Windows 和 Mac上的 Outlook, 苹果邮件在Mac和iPad上,Gmail,雅虎和质子在网络上.
生态系统
| 项目 | 这是什么 |
|---|---|
| @ emailens/ engine (英语) | 这个 CLI 作为库运行的分析引擎 |
| @ 电子邮件ens/ mcp | 编码代理商的相同检查: claude mcp add emailens -- npx -y @emailens/mcp |
| 电子邮件/行动 | GitHub 动作: 构建失败, 可以根据拉动请求对每个客户端的分数进行注释 |
| 电子邮件/vscode | VS 代码扩展: 编辑器中的发现和预览 |
许可证
麻省理工学院