十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

离线环境下用mermaid-cli导出SVG和PNG的完整指南

离线环境下用mermaid-cli导出SVG和PNG的完整指南 如果你的工作里经常画流程图、时序图、ER图那你大概率听过Mermaid如果还想在没有外网的环境里继续用Mermaid并且把成果稳定导出成png和svg这篇文章刚好就是你需要的东西。我上个月在客户现场做系统文档交付那边内网隔离得很彻底外网完全不通但我靠着本地的Mermaid工具链把架构图、调用链图和数据库ER图全部按时导了出来一行在线服务都没用。这篇内容不吹不黑只讲离线环境下的真实操作路径、参数细节和踩坑记录适合文档工程师、后端开发、运维和所有需要在受限网络里画图的人。先说结论离线Mermaid不是下载个编辑器就完事核心在于搞清楚谁负责渲染、谁负责导出然后选一套能离线跑通的组合工具。我会把从环境搭建到命令行导出再到日常工作流整合的完整方案摊开讲包括那些文档里不写但实际一定会遇到的问题。1. 为什么必须准备一套离线的Mermaid环境1.1 在线编辑器确实爽但“没网”时瞬间变白板很多人习惯打开mermaid.live或者各类在线渲染网站左边写代码右边出图确实方便。但这类工具一旦离开外网就成了摆设尤其在下面这些场合非常尴尬客户机房网络隔离、出差路上信号差、企业内部文档系统部署在隔离区。我遇到过不止一次在会议室现场要改一张架构图结果在线编辑器转圈十分钟最后只能掏出手机开热点体验极差。更现实的问题是在线编辑器改完的图往往是“一次性”的你要是没手动下载文件过两天想再改就得重画。而Mermaid的核心优势本来就是“用文本描述图”这个优势只有在你本地保存了.mmd源码文件后才真正成立。1.2 离线使用的典型场景内网机房、差旅、文档协同离线Mermaid不是极客情结它对应的是真实存在的场景。第一种是内网开发环境很多企业的生产网段和办公网段物理隔离你所有代码、文档、图表都必须在内网操作图也要在内网生成。第二种是差旅和现场交付我在高铁上改架构图不是一次两次离线工具能让我不受网络波动影响。第三种是文档协同和版本管理公司文档库里要长期维护一套带图表的Markdown文件如果每张图都依赖在线服务过两年在线服务改版或者域名变了整篇文档的图就全挂了。这些场景共同的特征是你需要一个完全本地、可重复执行、能对接脚本和CI流程的渲染工具而不是一个打开网页点按钮的交互界面。1.3 别被表面骗了Mermaid渲染本质是浏览器里的事这里要先讲清楚一个底层逻辑。Mermaid的源码本质上是JavaScript库它做的事情是把你写好的DSL文本类似graph TD; A--B解析成语法树再在浏览器的DOM环境里生成SVG节点。也就是说Mermaid本身不是一个桌面软件它默认的运行环境是浏览器。理解了这点你就能明白为什么离线导出不能只靠“装个Mermaid软件”。你真正需要的是两样东西一是完整的Mermaid库文件或者能用命令行调用它的包装工具二是一个能执行JavaScript并输出图片的运行环境。目前最主流的做法是用mermaid-cli它内部调用无头浏览器Chromium来完成渲染。换句话说你命令行里执行一条命令它帮你打开一个看不见的浏览器把Mermaid代码渲染成SVG再按需转成PNG或PDF。2. 从零搭一套能离线的Mermaid运行栈2.1 主力方案mermaid-cli把渲染变成命令行mermaid-cli是目前离线导出最可靠的方案安装和使用都不复杂。前提是你电脑里有Node.js环境然后全局安装这个工具包npm install -g mermaid-js/mermaid-cli装完后命令行里会多一个mmdc命令。第一次跑的时候它可能会自动下载Chromium内核这个过程比较慢而且在你网络受限时容易失败。我的建议是在有网的机器上先把它跑通一次或者手动准备好一个浏览器内核然后用环境变量指定路径export PUPPETEER_EXECUTABLE_PATH/usr/bin/chromium mmdc -i input.mmd -o output.svg在Windows上类似指定到chrome.exe的完整路径即可。这样做的好处是彻底绕开自动下载离线环境里只要你有浏览器内核就能导出。2.2 写图用VS Code插件预览和补全都在本地光有命令行工具还不够日常写图时你需要一个顺手的环境。VS Code里有两个方向可选一个是Markdown Preview Mermaid Support它能在预览Markdown时把代码块里的Mermaid渲染出来配合离线插件安装包用完全没问题另一个是Mermaid Editor主打独立编辑Mermaid文件自带语法高亮、节点提示和实时预览。我的习惯是用VS Code写图用mmdc导图。写图时只看预览确认结构对不对最终交付时再走命令行导出这样能保证产物质量受控。VS Code插件市场如果在内网无法访问可以提前在官网下载vsix安装包离线安装命令就一条code --install-extension ./mermaid-editor-0.19.0.vsix2.3 Typora这类写作工具其实自带了一半答案Typora内置了Mermaid渲染在Markdown里写个mermaid代码块它会直接在编辑界面渲染成图导出PDF或HTML时图也在。很多文档作者会觉得这就够了但要注意Typora的图片导出能力其实偏弱它没有直接“把这个Mermaid图保存为PNG”的按钮通常只能截图。如果你只是写内部文档Typora自带渲染完全够用但如果你想得到高清无损的独立图片还是得回到命令行。我经常在Typora里快速排版文字需要单独出图时再切换到mmdc两边互补。2.4 工具选择和适用场景对照工具离线渲染导出SVG导出PNG批量处理适合场景mermaid-cli (mmdc)是是是很强文档交付、CI集成、高清导出VS Code插件是手动手动弱日常编写、快速预览Typora是内置转PDF截图弱纯文档写作浏览器截图类插件是有限是弱临时应急这里多说一句浏览器截图类插件我也试过对付普通网页没问题但对Mermaid这种动态渲染的页面经常出现截图不全、模糊或者背景色不对的情况不适合作为正式方案。3. 命令行导出SVG和PNG的完整参数拆解3.1 最基础的导出命令一进一出就完事假设你已经写好一个flow.mmd文件内容大概是graph TD A[需求分析] -- B[设计] B -- C[开发] C -- D[测试] D -- E[发布]最基本的导出命令是这样mmdc -i flow.mmd -o flow.svg这条命令会生成一个矢量SVG文件。如果想导PNG把后缀换成.png即可mmdc -i flow.mmd -o flow.png这里有个细节mmdc判断输出格式靠的是-o参数的后缀名所以后缀必须要写对。另外当你不指定任何宽度、高度参数时SVG会使用Mermaid自动计算出来的尺寸PNG的默认分辨率则是96dpi下对应的像素值。对大多数屏幕阅读场景够用但要放到PPT或者印刷材料里就需要处理尺寸和缩放。3.2 尺寸、缩放和高分辨率别把PNG导出成马赛克最大坑来了直接用默认参数导出的PNG在普通编辑器里看还行一旦放大就糊。原因很简单默认导出没有做倍率放大。解决办法是用-s参数指定缩放倍数mmdc -i flow.mmd -o flow.png -s 2-s 2代表两倍分辨率比如原图宽400px导出后就是800px宽。做PPT或者海报时我一般用-s 3保证在200%缩放下依然清晰。也可以用-w和-H直接指定输出图片的像素宽度和高度mmdc -i flow.mmd -o flow.png -w 1600 -H 1200需要注意的是-w和-H只决定画布大小不会自动缩放图里节点和字体的相对大小所以如果指定的宽高比Mermaid默认尺寸大太多图可能会因为内容稀疏而显得不协调。我的经验是优先用-s控制分辨率不要直接拉-w。导出SVG时则相反SVG本身就是矢量格式无限缩放都不糊我基本不设宽高保持默认输出。3.3 主题、背景色和字体影响交付观感的三件套默认的Mermaid配色偏明亮适合开发文档但客户要求的正式交付文档往往需要更克制的配色。这时可以通过配置文件指定主题{ theme: base, themeVariables: { primaryColor: #f5f5f5, primaryTextColor: #222222, primaryBorderColor: #888888, lineColor: #666666, fontFamily: Microsoft YaHei }, backgroundColor: white }保存成mmdc.config.json导出时用-c指定mmdc -i flow.mmd -o flow.png -c mmdc.config.json -s 2这里的主题变量就是Mermaid官方提供的CSS变量接口具体可以查Mermaid主题文档但我常用的就这几个primaryColor节点填充色、primaryTextColor节点文字色、primaryBorderColor节点边框色、lineColor连线颜色。背景色用backgroundColor改成透明可以写成backgroundColor: transparent这在做网页嵌入图时很常见。3.4 批量导出用脚本一次处理整个图表目录单图导出是小打小闹真实项目里往往一个文档目录下有几十个.mmd文件。我一般会写一个循环脚本mkdir -p output for f in diagrams/*.mmd; do name$(basename $f .mmd) mmdc -i $f -o output/${name}.svg -c mmdc.config.json mmdc -i $f -o output/${name}.png -c mmdc.config.json -s 2 done在Windows环境可以用PowerShell实现同样的逻辑Get-ChildItem diagrams\*.mmd | ForEach-Object { $name $_.BaseName mmdc -i $_.FullName -o output\$name.svg -c mmdc.config.json mmdc -i $_.FullName -o output\$name.png -c mmdc.config.json -s 2 }批量导出唯一要注意的是别把大量文件放在同一个导出的毫秒级循环里比如导出100张图。mmdc每次都要启动一个无头浏览器实例这个开销很大。我处理80张图的时候脚本跑了差不多三分钟后来改成只对改过时间戳的文件重新导出速度才上来。4. 导出过程中最常见的几个翻车现场4.1 首次运行卡死或报错十有八九是Chromium的那点事mermaid-cli首次运行最大的坑就是Chromium下载。如果你在离线环境直接跑mmdc大概率会看到一个连接超时的报错然后整个命令退出。这个问题我碰到过两次一次是在内网服务器一次是刚刚配的新笔记本。解决方案分两步。第一步是在有网环境把工具装好、至少跑通一次让Puppeteer把Chromium下载到本地缓存目录然后把整个缓存目录一块带走。第二步是用环境变量指定系统已有的浏览器export PUPPETEER_EXECUTABLE_PATH/opt/google/chrome/chrome在Linux服务器上如果以root身份运行还需要追加--noSandbox参数否则Chromium的安全沙箱机制会拒绝启动mmdc -i flow.mmd -o flow.png --noSandbox这个参数组合在Docker容器里跑CI的时候尤其常用算是离线导出绕不开的一个门槛。4.2 中文乱码和字体渲染和你在本地预览时不一样这是中文用户最痛的一个问题。本地VS Code预览完全正常但导出PNG后中文字全变成方块。原因很简单无头Chromium默认运行在一个极简环境里它可能压根没有安装中文字体。解决办法两个字装字体。Windows本地一般没有这个问题但Linux服务器上非常常见。先确认系统里有中文字体fc-list :langzh没有就装apt-get install -y fonts-wqy-microhei然后在mmdc配置文件里把字体指定到位{ themeVariables: { fontFamily: \Microsoft YaHei\, \Noto Sans CJK SC\, \PingFang SC\, sans-serif } }这里要注意fontFamily既可以在themeVariables里配也可以在Mermaid的配置项里配但themeVariables里的优先级更高我实测用这个位置最保险。字体问题解决后导出图和本地预览基本一致。4.3 图片一大起来就空白、超时或内存爆掉我画一张包含六百多个实体关系的ER图时mmdc渲染了快两分钟最后导出PNG整个页面空白。排查后发现是节点数量太多无头浏览器在生成SVG时内存占用过高最终渲染进程崩了。这类问题没有银弹我的处理思路是拆图把一张超大型图按业务域拆成多张中小型图每张控制在两百个节点以内。简化节点文案Mermaid渲染时的布局计算量大致和节点数量的平方相关文案过长也会加剧布局困难。放宽浏览器资源限制mmdc启动Chromium时可以加--no-sandbox以外的参数但单纯调大内存并不能根治问题拆图才是正道。在CI里设置超时和重试脚本里给每条mmdc命令加上超时控制失败后自动重试一次能有效缓解偶发崩溃。另外如果你用erDiagram画超大ER图还可以试试先把结构拆成若干子图每个子图先用subgraph归类导出后再用设计工具拼合虽然麻烦但能解决问题。4.4 导出的SVG在旧式桌面程序里显示不出来有同事问我为什么导出的SVG放到他们项目的WinForm里PictureBox控件完全显示不了。这里得说清楚PictureBox原生不支持SVG它只能显示GIF、JPG、BMP、PNG这些位图格式。如果只能使用WinForm三个思路一是让mmdc直接出PNG这是最省事的二是用SVG渲染库比如SVG.NET或者SkiaSharp相关封装在程序里自己绘制三是先把SVG转成PNG再加载。我平时给桌面项目提供图表资源时都是同时交SVG和PNG各一份避免对接方在格式上浪费功夫。如果说你还要把SVG贴到Cesium或其他WebGIS里当覆盖层那SVG本身是没问题的直接按资源路径加载就行真正卡人的全是桌面软件的格式兼容。5. 让导出的SVG/PNG真正进入工作流5.1 直接把SVG嵌进网页和Markdown文档SVG最大的优势是体积小、无限清晰非常适合Web场景。导出的.svg文件可以直接当成普通图片引用img src./diagrams/flow.svg alt业务流程图 /也可以在HTML里内嵌Mermaid渲染后的SVG代码但这要求你导出时能拿到SVG源码而非文件。用mmdc导出的SVG文件本质上就是文本你可以直接打开复制粘贴到HTML里效果是矢量无损的。前端在搞标题扫光、图标动画这些效果时也常用SVG因为路径和文字都是可编程的DOM节点配合CSS可以做出很多位图做不到的动态效果。在Markdown文档里用法更简单页面支持直接引用相对路径的SVG图片![业务流程图](./diagrams/flow.svg)5.2 转成base64数据塞进消息和缓存受限的地方有些场景下你不能引用外部文件比如要给内部IM发一张图或者要在一个受限的网页环境里内嵌图片这时候把图片转成base64字符串就很实用。命令行下一条命令就能生成base64 -w 0 diagram.svg在Windows PowerShell里这样写[Convert]::ToBase64String([IO.File]::ReadAllBytes(diagram.png))生成的base64字符串拼到URL前缀后面就是一张完整的data:image/svgxml;base64,...或者data:image/png;base64,...图片。我常在自动化报告脚本里用这个方式把每天生成的架构图直接写进HTML邮件正文完全不用图床。5.3 把.mmd源码和导出产物一起纳入版本管理这是我特别想强调的一个习惯。很多团队文档仓库里只保留了PNG图片原始.mmd代码被随手丢掉了等下一次要改图就只能重新画成本直接翻倍。我现在所有项目里都坚持源码和产物一起入库docs/ diagrams/ flow.mmd flow.svg flow.png er_diagram.mmd er_diagram.svg er_diagram.png提交代码时.mmd提供可修改的源SVG和PNG提供可直接引用的产物。如果担心图片更新不及时可以在CI流水线里加一步检测到.mmd有变更时自动执行mmdc批量导出命令再把生成的新图片提交回仓库。这套思路跑顺以后整个团队永远不会再遇到“图过期了找不到源文件”的情况。5.4 从数据库表结构自动生成ER图的Mermaid源码ER图是Mermaid里比较常用也带一点门槛的类别。如果数据库表特别多手工写Mermaid代码几乎不现实正确做法是从数据库字典自动生成。MySQL可以查information_schema拿到表、字段、主键、外键关系SELECT TABLE_NAME, COLUMN_NAME, COLUMN_KEY, DATA_TYPE, COALESCE(REFERENCED_TABLE_NAME, ), COALESCE(REFERENCED_COLUMN_NAME, ) FROM information_schema.KEY_COLUMN_USAGE WHERE TABLE_SCHEMA my_database ORDER BY TABLE_NAME, ORDINAL_POSITION;再用一个简单脚本把查询结果拼成Mermaid语法erDiagram USER ||--o{ ORDER : places USER { int id PK varchar name } ORDER { int id PK int user_id FK }这类生成脚本我建议直接用Python或者Node写逻辑不复杂核心就是遍历表结构、拼字符串。虽然每个数据库的系统表结构略有差异但MySQL、PostgreSQL都提供了类似的信息做法一通百通。走完这步你就可以把整库ER图当作普通文档资产一样随时离线重新生成、重新导出了。回头再看这套流程我最大的体会是真正提高效率的不是某一个神奇工具而是把“写图源码”和“渲染导出”分开的思路。以前我画图都是截个图就完事现在我习惯把所有图都保留成.mmd文件随时能改、随时能按需出SVG或PNG。团队如果还在用截图方式维护文档图建议先把最常变动的几张架构图转成Mermaid源码走一遍完整的离线导出流程。那种“断网也不慌、改图不抓狂”的踏实感试一次就会上瘾。
返回列表