juice-email-cli
v4.1.0
Published
CLI tool to generate email-client-compatible HTML with juice (CSS inlining) + Handlebars templating (Mustache-compatible semantics) + minification
Maintainers
Readme
juice-email-cli
一个用于生成符合各大邮件平台标准的 HTML 邮件命令行工具,基于 juice 实现 CSS 内联,支持 Handlebars 模板(完全兼容 Mustache 语义),同时输出标准版与压缩版。
功能特性
- CSS 内联 —— 将
<style>中的样式全部内联为style=""属性,兼容 Gmail / Outlook / Apple Mail 等 - 模板引擎 —— Handlebars 渲染 + Mustache 语义完全对齐(空串/0 为假值、上下文规则一致),现有 Mustache 模板零改动可用
- 模板增强 —— 循环索引
{{@index}}、逻辑 helper(eq/gt/and/or…)、{{#each}}、partial({{> name}})、{{{var}}}原样输出 - 本地样式表内联 —— 模板中
<link rel="stylesheet" href="./xx.css">构建期自动合并内联(自定义 CSS / Bootstrap / uno.css) - 片段组装 —— 将片段 HTML 插入模板的
<tbody id="content">,自动调整缩进,输出 4 个阶段文件 - 页面装配 ——
juice build -p page.yaml:多个片段(可带独立变量)按序组装进页面骨架,另支持交互式装配 - 三层配置合并 —— CLI 默认 < 用户目录 < 优先配置,层层合并
- HTML 标签渲染 —— 变量值中的
<sup>、<sub>等 HTML 标签直接渲染(可通过rawHtml关闭) - 双文件输出 —— 普通模式生成
.output.html+.minified.html - 四文件输出 —— 片段模式 / 页面装配生成
.raw.html+.html+.output.html+.minified.html - 交互模式 —— 无参数运行,逐步选择品牌、模板、片段、配置
- 资源浏览 ——
juice view查看 EDM 资源树,-i交互式逐层翻页 - 资源拷贝 ——
juice init将模板/片段/配置拷贝到当前目录 - Windows 右键菜单 —— 文件/文件夹/空白处多场景支持,一键注册/卸载
安装
# 全局安装
npm install -g juice-email-cli
# 安装时自动注册 Windows 右键菜单(无管理员权限时静默跳过)提示:安装时如未注册右键菜单,安装完成后以管理员身份运行:
juice --install
# 本地克隆安装
git clone https://github.com/GuoSirius/juice-cli.git
cd juice-cli
npm install # 自动注册右键菜单
npm link # 链接到全局使用方法
普通模式(CSS 内联 + 压缩,输出 2 个文件)
# 最简用法
juice -f my-email.html
# 指定配置文件
juice -c project.yaml -f my-email.html
# 使用 EDM 模板库中的模板
juice -f edm/elabscience/elabscience-template.html输出冲突:若
.output.html/.minified.html已存在,会提示覆盖(默认)/版本/重新输入文件名三种处理方式(与片段模式菜单一致);非交互环境(如 CI/管道)默认覆盖并给出警告,不会卡死。
生成文件(与输入文件同目录):
| 文件 | 说明 |
|------|------|
| <name>.output.html | CSS 内联 + 变量替换后的标准版 |
| <name>.minified.html | 压缩版 |
片段模式(片段 + 模板拼接,输出 4 个文件)
# 完整指定片段和模板
juice -s edm/elabscience/literature/snippet.html -f edm/elabscience/elabscience-template.html
# 只指定片段,交互式选择模板
juice -s edm/elabscience/literature/snippet.html
# 自定义输出文件名
juice -s snippet.html -f template.html -n my-output生成文件(当前工作目录):
| 文件 | 说明 |
|------|------|
| <name>.raw.html | 原始组装(模板未渲染,无 CSS 内联) |
| <name>.html | 已渲染(模板变量已替换,无 CSS 内联) |
| <name>.output.html | Juice CSS 内联后 |
| <name>.minified.html | 压缩版 |
输出文件名默认为模板文件名(不含扩展名)。如果文件冲突,会提示 覆盖(默认) / 版本 / 重新输入文件名 三种处理方式;-s -f 直接指定时同样走此逻辑,非交互环境默认覆盖并给出警告。
页面装配(多片段组装成页面,输出 4 个文件)
# 按 page.yaml 装配
juice build -p page.yaml
# 自定义输出名(覆盖 page.yaml 的 outputName)
juice build -p page.yaml -n my-page
# 交互式装配:选择品牌/模板/多选板块,自动生成 page.yaml
juice buildpage.yaml 结构(路径相对 page.yaml 所在目录,产物输出在运行命令时所在目录):
template: tpl.html # 页面骨架,<tbody id="content"> 处插入板块
outputName: demo-page
variables: # 全局变量
brand: ACME
sections: # 按序装配,每个板块可带独立 vars
- snippet: sections/header/snippet.html
vars: { title: 标题A }
- snippet: sections/products/snippet.html
vars: { items: [{ name: P1, tag: hot }] }
partials: # 可选:{{> sub}} 局部复用
sub: sections/footer/sub.html生成文件(与片段模式相同的 4 文件):
| 文件 | 说明 |
|------|------|
| <name>.raw.html | 原始组装(板块已插入、变量未渲染) |
| <name>.html | 已渲染(变量已替换、无 CSS 内联) |
| <name>.output.html | Juice CSS 内联后 |
| <name>.minified.html | 压缩版 |
完整示例见 examples/page-assembly/。
交互模式(逐步选择)
juice流程:选择品牌 → 模板 → 片段文件夹 → 片段 HTML → 配置文件 → 输出文件名 → 确认执行。
浏览资源(查看 EDM 模板库)
# 查看完整资源树
juice view
# 查看指定品牌/系列/变体
juice view elabscience
juice view elabscience/literature
# 列出所有模板 / 系列 / 片段
juice view --templates
juice view --series
juice view --snippets
# 交互式浏览(可上下翻层级,叶节点可直接拷贝)
juice view -i
juice view -i elabscience拷贝资源到当前目录
# 交互式选择(每步支持返回/退出)
juice init
# 拷贝整个 EDM 资源库
juice init --all
# 从指定 EDM 路径拷贝
juice init elabscience/templates/standard
# 仅拷贝指定文件
juice init --template edm/elabscience/templates/standard/template.html
juice init --snippet edm/elabscience/series/literature/default/snippet.html
juice init --config edm/elabscience/series/literature/default/juice.yaml交互拷贝进入变体后提供三个操作:
🧩 仅片段+配置— 快捷拷贝片段 HTML + juice.yaml(跳过模板)✅ 确认拷贝— 按当前选择执行🔄 自定义选择— 打开多选 checkbox 调整
拷贝模板时自动附带 favicon.ico。配置文件冲突自动加版本号。
参数说明
| 参数 | 简写 | 说明 |
|------|------|------|
| --file <path> | -f | 输入 HTML 模板文件路径 |
| --snippet <path> | -s | 片段 HTML 文件路径:插入到模板 <tbody id="content"> |
| --config <path> | -c | 配置文件路径,不指定时自动查找 |
| --name <name> | -n | 片段/页面装配模式输出文件名(不含扩展名) |
| --page <path> | -p | 页面装配描述文件(YAML),仅 juice build 子命令使用 |
| --install | | 注册 Windows 右键菜单(当前用户,无需管理员) |
| --uninstall | | 取消 Windows 右键菜单注册 |
| --version | -v | 查看版本号 |
| --help | -h | 查看帮助 |
CLI 执行模式
| -s | -f | -c | 执行模式 |
|------|------|------|----------|
| ✓ | * | * | 片段模式(-s 指定片段,-f 可选指定模板) |
| ✗ | ✓ | * | 普通模式(生成 .output.html + .minified.html) |
| ✗ | ✗ | ✗ | 交互式片段模式(逐步选择) |
| — | — | — | juice build [-p page.yaml] 页面装配(无 -p 时交互式) |
| — | — | — | juice view [path] 浏览资源 / -i 交互浏览 |
| — | — | — | juice init [path] 拷贝资源到当前目录 |
配置文件优先级
优先级 低 ──────────────────────────────────────────────── 高
CLI 内置默认值 < 用户主目录 ~/juice.yaml < 优先配置(互斥)优先配置(-c 和输入文件同级目录互斥,只生效一个):
| 来源 | 说明 |
|------|------|
| -c <path> | 命令行指定,最优先 |
| 输入文件同目录 juice.yaml | 随模板文件走,适合项目级配置 |
合并规则:
- 用户主目录配置(如果存在)始终参与合并
- 优先配置覆盖用户主目录配置中的同名字段
- CLI 内置默认值兜底所有未配置字段
示例:
# 指定配置文件(与用户目录合并)
juice -c project.yaml -f email.html
# 使用输入文件同级目录配置(与用户目录合并)
juice -f email.html片段模式配置
片段模式下,会自动检测片段目录下的 juice.yaml / juice.yml 作为项目配置参与合并:
优先级 低 ──────────────────────────────────────────────────────── 高
内置默认 < ~/juice.yaml < 片段目录 juice.yaml < -c 指定配置文件示例
用户配置文件(~/juice.yaml 或项目目录 juice.yaml)只需填写需要覆盖的字段,其余自动继承:
# 设为 false 时,变量值中的 HTML 标签会被转义
rawHtml: true
variables:
brandName: "我的品牌"
brandColor: "#ff6600"
logoUrl: "https://cdn.example.com/logo.png"
ctaText: "立即订购"
ctaUrl: "https://example.com/buy"
companyName: "My Company"
currentYear: "2026"
# 列表数据示例
products:
- name: "产品 A"
price: "¥99.00"
tag: "热销"
- name: "产品 B"
price: "¥199.00"
# 变量值支持 HTML 标签(rawHtml: true 时)
overview:
title: "CD38-NAD<sup>+</sup> Axis Study"
keywords: "Immune Thrombocytopenia, NMN, NAD<sup>+</sup>"
# juice 选项(全部可选,均有内置默认值)
# juice:
# removeStyleTags: true
# preserveMediaQueries: true
# preservePseudos: true
# 输出后缀(可选)
# output:
# normalSuffix: ".output.html"
# minifiedSuffix: ".minified.html"完整默认配置见 defaults/juice.yaml。
模板语法
完整语法参考见 docs/template-syntax.md(含值类型→行为对照表、helper 一览、迁移注意事项)。速查:
| 语法 | 说明 | 示例 |
|------|------|------|
| {{var}} / {{a.b.c}} | 插值(默认转义) | {{overview.title}} |
| {{{var}}} | 插值,恒不转义 | {{{html}}} |
| {{#var}}…{{/var}} | 条件渲染(真值时显示;对象压栈上下文、字符串保持父级上下文) | {{#gift}}{{gift}}{{/gift}} |
| {{^var}}…{{/var}} | 反向(空串/0/undefined/空数组时显示) | {{^banner.link}}…{{/banner.link}} |
| {{#list}}…{{/list}} | 数组迭代,{{.}} 为当前项 | {{#products}}{{name}}{{/products}} |
| {{#each list}}…{{/each}} | 增强迭代:@index / @first / @last | {{@index}}. {{name}} |
| {{#if (eq a "x")}}…{{else}}…{{/if}} | 逻辑 helper:eq/ne/gt/gte/lt/lte/and/or/not | {{#if (gt count 3)}}…{{/if}} |
| {{> name}} | partial 引入(yaml partials 注册) | {{> note}} |
| <link rel="stylesheet" href="./x.css"> | 本地样式表构建期内联 | — |
HTML 标签在变量中:rawHtml: true(默认)时直接渲染:
variables:
overview:
keywords: "CD38-NAD<sup>+</sup> Axis, NO<sub>3</sub><sup>-</sup>"<p>{{overview.keywords}}</p>
<!-- 渲染为:CD38-NAD<sup>+</sup> Axis, NO<sub>3</sub><sup>-</sup> -->片段组装
EDM 目录结构
edm/
├── <brand>/ # 品牌目录
│ ├── <brand>-template.html # 品牌模板(含 <tbody id="content">)
│ └── <series>/ # 片段系列目录
│ ├── snippet.html # 片段 HTML(Handlebars/Mustache 模板片段)
│ └── juice.yaml # 片段配置(variables)片段 HTML 格式
片段是模板中 <tbody id="content"> 内的内容片段,会被自动插入并调整缩进:
<!-- edm/elabscience/literature/snippet.html -->
<tr>
<td></td>
<td colspan="2">
<table>
<tbody>
<tr>
<td><img src="{{overview.image}}" /></td>
<td><strong>{{overview.title}}</strong></td>
</tr>
</tbody>
</table>
</td>
<td></td>
</tr>跨品牌检查
片段和模板来自不同品牌时,会输出警告但仍继续执行,避免样式错乱。
Windows 右键菜单
.html / .htm 文件右键
📧 用 juice 生成邮件 HTML
├── 📄 作为模板,生成邮件 HTML → juice -f %1(后台执行)
├── 🧩 作为片段,拼接邮件 HTML → juice -s %1(交互选择模板)
├── 📋 查看可用资源 → juice view
├── 📦 拷贝全部资源 → juice init --all
├── 📥 选择资源拷贝 → juice init
└── 📂 打开 PowerShell ← 仅已安装 pwsh 时出现.yaml / .yml 文件右键
📧 用 juice 生成邮件 HTML
├── ⚙️ 作为配置,拼接邮件 HTML → juice -c %1(交互选择品牌/模板/片段)
├── 🧱 作为页面装配,生成邮件 HTML → juice build -p %1
├── 📋 查看可用资源
├── 📦 拷贝全部资源
├── 📥 选择资源拷贝
└── 📂 打开 PowerShell文件夹右键
📧 用 juice 生成邮件 HTML
├── 🧱 页面装配,交互生成邮件 HTML → juice build(选模板/多选板块,自动生成 page.yaml)
├── 📋 查看可用资源
├── 📦 拷贝全部资源
├── 📥 选择资源拷贝
└── 📂 在此打开终端空白处右键
📧 用 juice 生成邮件 HTML
├── 🧱 页面装配,交互生成邮件 HTML → juice build
├── 📋 查看可用资源
├── 📦 拷贝全部资源
├── 📥 选择资源拷贝
└── 📂 在此打开终端juice --install # 注册(当前用户,无需管理员)
juice --uninstall # 卸载注意:注册到当前用户(HKCU),无需管理员权限。注册成功后如菜单未立即出现,重启文件资源管理器(
explorer.exe)即可。
发布说明
提交信息规范
使用 Conventional Commits 规范:
feat: 添加新功能
fix: 修复 bug
docs: 更新文档
chore: 其他变更自动化发布
npm run release # 一键发布
npm run release:dry # 预览License
MIT
