MJML 安装与使用完全指南:从 npm 安装、CLI 编译、Node.js API 到 mj-include 安全实践
前端CLI【免费下载链接】mjmlMJML: the only framework that makes responsive email easy项目地址https://gitcode.com/gh_mirrors/mj/mjml点击查看免费下载MJML 是专门面向响应式邮件开发的标记语言框架本指南以仓库 doc/install.md 为主线系统讲解 MJML 的安装方式、源码开发环境搭建、命令行编译、Node.js 集成以及mj-include模板复用的安全机制。读完本文你将掌握从零开始安装 MJML、使用 CLI 和编程 API 将 MJML 编译为邮件 HTML、以及安全地组织共享模板片段的完整实战方案并理解底层 mjml-core 的参数默认值与编译管线。一、安装 MJML一条命令接入响应式邮件开发MJML 以 npm 包形式发布通过 NPM 安装后即可在 Node.js 环境或命令行中使用npm install mjml安装完成后mjml命令会通过 packages/mjml/package.json 中声明的bin字段mjml: bin/mjml暴露到node_modules/.bin/下。为了避免每次敲./node_modules/.bin/mjml可以在项目目录中将该目录加入 PATHexport PATH$PATH:./node_modules/.bin之后即可在项目内直接运行mjml input.mjml从当前仓库 packages/mjml/package.json 可以看到mjml主包本身是一个聚合包其依赖由四部分构成各自承担独立职责依赖包职责mjml-cli命令行接口负责参数解析、文件读写、watch 与 stdout 输出mjml-core核心编译引擎实现mjml2html主流程mjml-preset-core内置标准组件集合section、column、text 等mjml-validatorMJML 文档校验规则合法标签、属性、子元素等入口文件 packages/mjml/src/index.js 的代码印证了这一组装关系它把 preset-core 的组件和校验依赖分别注册到 core 与 validator 中再导出mjml2htmlimport mjml2htmlCore, { components, assignComponents } from mjml-core import { dependencies, assignDependencies } from mjml-validator import presetCore from mjml-preset-core assignComponents(components, presetCore.components) assignDependencies(dependencies, presetCore.dependencies) export default async function mjml2html(input, options {}) { return mjml2htmlCore(input, options) }从源码结构看mjml2html是异步函数调用时返回 Promise最终通过解构拿到{ html, json, errors }。二、从源码构建 MJML搭建本地开发环境如果你要参与 MJML 开发、提交 pull request官方推荐使用 Yarn 搭建开发环境git clone https://github.com/mjmlio/mjml.git cd mjml yarn yarn buildyarn安装整个仓库lerna monorepo的全部依赖yarn build使用 Babel 将每个包的src/编译到lib/见 packages/mjml/package.json 中的build: babel src --out-dir lib --root-mode upwardyarn build:watch以监听模式持续重建代码改动即时生效适合开发调试。仓库根目录的 lerna.json 表明这是一个多包monorepo工程packages/下每个子目录都是一个独立可发布的 npm 包。开发完某个包的源码后运行yarn build即可产出可被测试消费的lib/产物例如 packages/mjml/test/ 下的测试均通过require(../lib)引入编译产物。三、MJML 的四种使用方式概览如果你不打算安装任何东西可以直接使用 MJML 官方提供的免费在线编辑器体验需要本地集成时则有编辑器插件、命令行、Node.js 三种主流方式。3.1 在线编辑器零安装体验 MJML 的首选方式是在线编辑器输入左侧 MJML 源码、右侧实时预览响应式 HTML 效果。它适合快速验证模板思路、初学者学习语法。3.2 编辑器插件MJML 拥有配套的插件生态Visual Studio Code 插件已内置 MJML 引擎安装后无需额外安装 MJML 即可在 VS Code 内直接编译预览也可在 VS Code 扩展市场或 Open VSX Registry 安装Sublime Text 插件提供 MJML 语法高亮但 MJML 引擎需要单独安装。完整的工具链清单见 工具生态文档更多社区维护的组件与工具可参考 社区组件文档 与 社区贡献文档。3.3 命令行接口CLICLI 适合脚本化、构建流水线集成将在第四节详解。3.4 Node.js API以编程方式调用mjml2html适合 Web 服务、批量渲染等场景将在第五节详解。四、命令行接口CLI详解CLI 的核心用法是编译 MJML 文件并将生成的 HTML 输出到output.htmlmjml input.mjml -o output.html参数解析由 packages/mjml-cli/src/client.js 中的 yargs 配置实现支持-r/-v/-w/-i/-s/-o/-c等短选项及对应长选项。4.1 完整 CLI 参数表CLI 接受下列可选arguments可以自由组合参数说明默认值mjml [input] -o [output]将编译结果写入[output]mjml [input] -s将编译结果输出到stdoutmjml [input] -s --noStdoutFileComment输出到stdout且第一行不添加包含源文件信息的注释输出首行包含!-- FILE: {filename} --格式的源文件注释mjml -w [input]监听[input]文件或目录的变化并自动重编译mjml [input] --config.allowIncludes启用mj-include处理true或falsefalsemjml [input] --config.allowMixedSyntax允许在同一文档中混用块级 token如{%...%}与 CSS token如color: {{...}}falsemjml [input] --config.beautify对输出 HTML 进行美化true或falsetruemjml [input] --config.filePath设置解析mj-include路径的基准目录并作为 include 沙箱的作用域--config.includePath中的相对路径基于该目录解析。当使用--stdin无磁盘输入文件时尤其有用输入文件所在目录mjml [input] --config.includePath追加允许的 include 根目录可为字符串路径或 JSON 数组。相对路径基于 CLI 工作目录解析mjml [input] --config.juicePreserveTags内联 CSS 时保留某些标签原样用于模板引擎详见 mjml-cli READMEmjml [input] --config.minify压缩输出 HTMLtrue或falsefalsemjml [input] --config.minifyOptionsHTML 压缩器选项用minifyCss控制 CSS 压缩旧键名minifyCSS仍被接受mjml [input] --config.mjmlConfigPath [mjmlconfigPath]使用指定路径或目录下的.mjmlconfig文件注册自定义组件当前工作目录下的.mjmlconfig若存在mjml [input] --config.sanitizeStyles使用模板语法时对输入做 PostCSS 前的清洗避免压缩 CSS 时解析模板 token 报错true或falsefalsemjml [input] --config.stack编译出错时打印完整错误堆栈true或falsefalsemjml [input] --config.templateSyntaxJSON 数组元素为{ prefix, suffix }对象用于声明模板定界符供清洗与还原使用mjml [input] --config.useMjmlConfigOptions允许使用.mjmlconfig文件中的options属性falsemjml [input] --config.validationLevel校验级别strict、soft或skipsoft值得注意的一个细节CLI 的默认beautify: true、minify: false定义在 packages/mjml-cli/src/helpers/defaultOptions.js这与 Node.js API 的默认值见第五节并不相同使用时需要区分上下文。4.2 minifyOptions 兼容性minifyCss 与 minifyCSSCSS 压缩统一由minifyCss控制为向后兼容旧键名minifyCSS仍被接受并在内部映射关闭 CSS 压缩mjml input.mjml -o output.html --config.minify true --config.minifyOptions {minifyCss: false} # 旧写法等效 mjml input.mjml -o output.html --config.minify true --config.minifyOptions {minifyCSS: false}使用预设或自定义选项启用 CSS 压缩# lite 预设 mjml input.mjml -o output.html --config.minify true --config.minifyOptions {minifyCss: lite} # 旧写法等效映射为 lite mjml input.mjml -o output.html --config.minify true --config.minifyOptions {minifyCSS: true} # default 预设并指定字符串使用单引号 mjml input.mjml -o output.html --config.minify true --config.minifyOptions {minifyCss: {preset:[default, {normalizeString:{preferredQuote:single}}]}}这一兼容映射在 packages/mjml-core/src/index.js 的 minify 分支中有直接实现当minifyOptions中未定义minifyCss而定义了minifyCSS时会先将其转换——minifyCSS: true映射为lite预设、minifyCSS: false映射为关闭再交给 htmlnano 处理。当minify: true且未提供minifyCss时核心引擎默认启用cssnano-preset-lite{ preset: cssnanoLitePreset }并叠加collapseWhitespace: true、removeEmptyAttributes: true、minifyJs: false等 htmlnano 默认选项。4.3 更多 CLI 能力除了 doc/install.md 表格中的参数mjml-cli README 还补充了以下高频能力仅校验不编译mjml -v input.mjml运行校验器并打印错误有错退出码为 1无错退出码为 0控制校验行为mjml -l skip -r input.mjml其中normal默认显示校验信息但仍编译、skip跳过校验直接渲染、strict校验失败即抛错终止监听重编译mjml -w input.mjml或--watch每次保存自动重渲染可配合-o/--output指定输出MJML3 迁移 MJML4mjml -m input.mjml -o result.mjmlstdout 文件注释默认-s输出首行带!-- FILE: {filename} --该逻辑实现在 packages/mjml-cli/src/commands/outputToConsole.js可用--noStdoutFileComment关闭CSS 内联保留标签--config.juicePreserveTags{myTag: { start: #, end: /# }}防止 juice 内联时把模板引擎标签属性转为小写juice 选项--config.juiceOptions{preserveImportant: true}默认applyStyleTags: false、insertPreservedExtraCss: false、removeStyleTags: falseminifyOptions 的 removeComments启用压缩时默认removeComments: safe且removeComments与keepComments联动见 packages/mjml-core/src/index.js。五、在 Node.js 中使用 MJML API5.1 mjml2html 基础用法import mjml2html from mjml /* Compile an mjml string */ async function renderMjml() { const htmlOutput await mjml2html( mjml mj-body mj-section mj-column mj-text Hello World! /mj-text /mj-column /mj-section /mj-body /mjml , options, ) /* Print the responsive HTML generated and MJML errors if any */ console.log(htmlOutput) } renderMjml()5.2 options 完整参数表mjml2html接受第二个可选参数options以对象形式传入选项类型说明默认值allowMixedSyntaxboolean清洗/压缩 CSS 时是否允许同一文档内混用块级 token 与 CSS tokenfalsebeautifyboolean是否美化 HTML 输出falsefilePathstring输入文件路径或基准目录决定默认 include 沙箱启用 include 时仅允许该目录下的引用.ignoreIncludesboolean是否忽略mj-include实例trueincludePathstring 或 string 数组除filePath外显式允许的 include 目录目录外的路径会被拒绝fontsobjectMJML 渲染 HTML 时默认导入的字体见 packages/mjml-core/src/index.jsjuicePreserveTagsobject内联 CSS 时保留的标签详见 mjml-cli READMEkeepCommentsboolean是否在 HTML 输出中保留注释trueminifyboolean是否压缩 HTML 输出falseminifyOptionsobjectHTML 压缩器选项{collapseWhitespace: true, minifyCss: lite, removeEmptyAttributes: true}minifyCss可为false、lite、default或 cssnano 预设对象如minifyCss: { preset: [default, { normalizeString: { preferredQuote: single } }] }mjmlConfigPathstring.mjmlconfig文件的路径或目录process.cwd()preprocessors函数数组解析前应用于 XML 的预处理器函数签名必须为(xml: string) string[]sanitizeStylesboolean使用模板语法时清洗输入防止 PostCSS 解析模板 token 报错falsetemplateSyntax对象数组sanitizeStyles为true时可自定义模板语法如templateSyntax: [{ prefix: {{, suffix: }} }, { prefix: {, suffix: } }][{prefix:{{,suffix:}}},{prefix:[[,suffix:]]}]useMjmlConfigOptionsboolean是否启用.mjmlconfig文件中的options属性falsevalidationLevelstring校验级别strict、soft、skipsoft5.3 源码深挖mjml-core 的默认值与编译管线packages/mjml-core/src/index.js 是这一切的底层实现从中可以确认多个关键默认值默认字体fonts默认包含 Open Sans、Droid Sans、Lato、Roboto、Ubuntu 五款 Google Fonts 链接校验行为validationLevel为soft时收集errors但继续编译strict时一旦有错即抛出带errors的ValidationErrorskip时完全不校验include 默认关闭ignoreIncludes trueincludePath默认未定义filePath默认.模板变量清洗机制当sanitizeStyles开启时核心引擎会先检测style块与style...属性中的模板 token将其替换为占位符区分 CSS 值变量、CSS 属性变量与块级变量三类交给 htmlnano/cssnano 压缩完成后再还原若检测到混用allowMixedSyntax: false时或定界符不配对会直接抛出明确错误!-- htmlmin:ignore --保护压缩阶段会把成对包裹的内容抽取为临时 token避免 htmlnano 折叠其中的空白压缩后还原。返回结构为{ html, json, errors }其中json是解析后的 MJML 语法树errors是校验信息数组——这正是 doc/install.md 中示例代码打印整个返回值即可同时看到 HTML 与错误的原因。六、mj-include模板复用与路径安全mj-include用于把公共片段头部、页脚、公共 CSS、HTML 片段复用到多个模板中。出于安全考虑它的默认行为是忽略。6.1 默认忽略与显式开启API 层面ignoreIncludes默认为true即mj-include标签默认不生效CLI 层面需显式传入--config.allowIncludes true该参数在 packages/mjml-cli/src/client.js 中被映射为config.ignoreIncludes false。开启后include 路径会被限制在输入文件目录或filePath及其子目录内绝对路径、逃逸项目目录的路径一律拒绝被拒绝的 include 会在输出中插入!-- mj-include denied --注释。6.2 includePath 配置示例CLI 示例三个参数配合使用$ mjml template.mjml \ --config.filePath /project/templates/newsletter \ --config.allowIncludes true \ --config.includePath [../_common,../vendor]单个 include 目录Node.jsimport mjml2html from mjml async function compileOne(source) { const { html, errors } await mjml2html(source, { ignoreIncludes: false, filePath: /project/templates/campaignA/email1.mjml, includePath: /project/templates/_common, }) }多个 include 目录Node.jsasync function compileMany(source) { const { html, errors } await mjml2html(source, { ignoreIncludes: false, filePath: /project/templates/campaignA/email1.mjml, includePath: [/project/templates/_common, /project/templates/_footers], }) }值得注意的解析差异CLI 中includePath的相对路径基于命令执行的工作目录process.cwd()解析而不是基于filePath或模板文件目录——这一点在 packages/mjml-cli/src/client.js 的resolveIncludePathEntry函数中有明确实现--config.filePath中的相对路径则相对于 CLI 工作目录解析。CLI 的includePath同时接受字符串与 JSON 数组两种形式会自动尝试 JSON 解析。6.3 安全机制详解doc/install.md 明确列出以下安全防线include 默认忽略ignoreIncludes: true需显式开启并用includePath限定允许目录路径在验证前会完整 URL 解码可抵御双重/三重编码绕过如%252F早期拒绝绝对路径、UNC 风格路径//server/...或\\server\\...、Windows 盘符路径C:\...、空字节%00直接拒绝规范边界检查解析并跟随符号链接symlink要求目标最终仍处于filePath或任意includePath根目录内。支持 include 的文件类型限定为mjml、css、html通过mj-include type...指定其他扩展名不受支持。6.4 共享 partials 的最佳实践项目模板根方案将filePath设为模板根目录模板内以该根为基准书写相对路径如./_common/header.mjml。结构简单但模板必须使用根相对路径显式白名单方案模板内保持原样相对路径如../_common/header.mjml用includePath声明兄弟/共享目录。无需改动模板支持多个共享根安全底线只有filePath与includePath之下的文件允许被 include这些根之外的绝对路径与..逃逸一律拒绝。6.5 测试佐证仓库中的测试用例直接印证了上述行为packages/mjml/test/ignore-includes.test.js验证默认忽略 include 不注入任何内容、ignoreIncludes: false时正常内联、逃逸根目录的路径被拒绝并插入!-- mj-include denied --packages/mjml/test/include-path.test.js验证includePath支持多根数组、typecss与typehtml的 include 能正确进入输出且未声明includePath时兄弟目录引用被拒绝packages/mjml/test/include-path-security.test.js覆盖绝对路径、UNC、盘符、空字节、双重编码逃逸等攻击向量的拒绝逻辑以及命中白名单时双重编码路径可以正常解析packages/mjml/test/include-path-cli.test.js在真实 CLI 进程中验证多根数组与 CSS/HTML include 的端到端行为。七、模板语法与 CSS 处理进阶当你的 MJML 模板来自模板引擎如 Handlebars{{...}}、EJS%...%、Nunjucks{%...%}时模板 token 若出现在mj-style或内联style...中直接走 CSS 压缩PostCSS/cssnano会解析失败。此时组合使用以下参数# 开启清洗后再压缩 $ mjml input.mjml --config.sanitizeStyles true --config.minify true # 或者干脆跳过 CSS 压缩、只压缩 HTML $ mjml input.mjml --config.minify true --config.minifyOptions{minifyCss: false}templateSyntax声明模板定界符默认同时支持{{...}}与[[...]]两种自定义示例$ mjml input.mjml \ --config.sanitizeStyles true \ --config.templateSyntax[{prefix:[[,suffix:]]},{prefix:{{,suffix:}}}]allowMixedSyntax默认禁止同一文档混用块级 token如{%...%}与 CSS 值/属性 token如color: {{...}}避免解析歧义确认需要混用时显式开启$ mjml input.mjml --config.sanitizeStyles true --config.minify true --config.allowMixedSyntax true从 packages/mjml-core/src/index.js 的实现看清洗阶段会先检测定界符是否配对不配对直接抛错并提示关闭 CSS 压缩或修复 token再按“CSS 值变量 / CSS 属性变量 / 块级变量”三种形态分别替换为占位符压缩完成后按映射还原从而保证模板变量在最终 HTML 中原样保留。八、.mjmlconfig注册自定义组件与全局选项--config.mjmlConfigPathAPI 中为mjmlConfigPath指定.mjmlconfig文件的位置用于注册自定义组件默认使用当前工作目录下的.mjmlconfig若存在。--config.useMjmlConfigOptionsAPI 中为useMjmlConfigOptions进一步允许读取该文件中声明的options。读取逻辑在 packages/mjml-core/src/helpers/mjmlconfig.js支持 JSON 格式的.mjmlconfig与 JS 格式的.mjmlconfig.js除packages自定义组件包列表外还支持preprocessors解析前 XML 预处理器与options全局默认编译选项。在 packages/mjml-core/src/index.js 中配置文件的options会与调用方显式传入的options合并显式参数优先minifyOptions做浅层对象合并preprocessors做数组拼接。.mjmlconfig中如何声明自定义组件可参考 社区组件文档。九、免费 MJML API 服务除本地安装外MJML 还提供免费的公开 API 服务方便在应用中原生集成 MJML 编译能力而无需部署编译环境。生产级集成时仍建议评估数据面模板内容发送到远端服务的合规性并根据需要选择本地 Node.js 集成方案。结语从npm install mjml到 CLI 的二十余个编译参数再到 Node.js API 的完整选项表与mj-include的多层安全防线本文已沿 doc/install.md 的主线完整覆盖 MJML 的安装与使用路径。深入源码可以确认CLI 与 API 的默认值存在差异如beautifyinclude 默认关闭且需要显式白名单模板变量清洗为 CSS 压缩提供了安全的模板引擎协作通道。你可以基于这些事实把 MJML 稳定地接入自己的构建流水线与邮件模板工程中。赞分享前端CLI【免费下载链接】mjmlMJML: the only framework that makes responsive email easy项目地址https://gitcode.com/gh_mirrors/mj/mjml点击查看免费下载相关推荐MJML 命令行工具mjml-cli完全指南安装、编译、校验与模板安全实践MJML 命令行工具mjml cli完全指南安装、编译、校验与模板安全实践 MJML 是一款将类 HTML 的声明式标记语言编译为响应式邮件 HTML 的前端CLIMJML 组件体系完全指南mjml、mj-head、mj-body 与 mj-include 实战解析MJML 组件体系完全指南mjml、mj head、mj body 与 mj include 实战解析 MJML 的核心是组件Component每个组件前端CLIAspire CLI 的 npm 安装包使用指南从全局安装到 TypeScript AppHost 实战Aspire CLI 的 npm 安装包使用指南从全局安装到 TypeScript AppHost 实战 本篇技术指南围绕 Aspire CLI 的 npm云原生后端微服务可观测性开发工具上一篇OpenArkWindows内核安全分析的架构演进与技术突破下一篇3大核心解码能力重新定义网页资源捕获的智能解码器创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考