ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

把架构图当代码管理:文本化图表工作流完整指南

把架构图当代码管理:文本化图表工作流完整指南 画架构图本来是个挺简单的事但我见过太多团队在这个“简单的事”上反复翻车PPT里的架构图改了一版又一版最后谁都不知道最新版在哪评审会上为了一个框的位置讨论二十分钟等真要把图塞进文档时发现导出的是模糊截图还得重新画。后来我把整套工作流迁到了 diagram-design 这套思路底下用文本定义图表、用命令渲染、把图放进 Git 里评审这套方式解决了我自己的大部分问题。这篇文章就把我攒下来的那套完整方案整理出来——不是给你推荐某一个画图工具而是讲清楚一套从“选型”到“日常维护”的完整链路用哪些工具、为什么这么选、目录怎么组织、脚本怎么写、CI 怎么卡、哪些坑我替你先踩了。内容更适合后端工程师、技术文档维护者、解决方案架构师以及所有不想再被格式和鼠标拖拽折腾的人。不要求你有前端基础只要会用命令行就能把整套流程跑起来。1. 图表设计作为代码工程为什么需要重新审视 diagram-design先说一个反直觉的结论图表设计这件事瓶颈从来不在“画图”而在“管理”。过去我们用 Visio、draw.io、Figma 这类图形化工具时遇到的问题其实不是“画不出来”而是“画完之后怎么办”。版本、协作、复用、变更记录、review——这些工程化诉求图形化工具解决得并不好。1.1 图形化画图工具的四大结构性痛点第一个痛点是版本追踪基本靠“另存为”。哪怕你用 draw.io 的文件存在 Git 里打开一看也是 XMLdiff 之后根本看不懂谁改了什么除非你能记住一大段 SVG path 里的数字变化。第二个痛点是协作 review 成本极高。图形界面里一次架构调整可能只是“把两个框换了层”但评审者看到的是新图很难通过对比知道到底哪里变了。没有 diff就没有真正意义上的 review。第三个痛点是复用性差。这次画一个订单流程图下次要画一个支付流程图绝大多数人都是重新拖一遍框而不是抽出一套可复用的组件。你很难在 draw.io 里优雅地定义一个“订单节点”然后在十个图里引用它。第四个痛点是图表与代码的漂移。系统在演进图还停在三个月前。等你发现的时候图已经不能准确描述系统了得花半天问一圈人才能补回来。1.2 diagram-design 的完整含义现在很多人在说 diagram-design这个词很容易被误解成“图表设计”好像只是比“画图”多了一层视觉要求。实际上在工程语境里diagram-design 应该包含三层文本化定义图表的全部内容用文本描述可以进 Git、可以 diff、可以 review。管线化渲染通过 CLI 或构建脚本将文本渲染成 PNG/SVG/HTML嵌入文档或网页全程无需人工拖拽。模块化组织同一种节点类型、同一套配色规范、同一组图标资源是共享的而不是每张图单独定义。把这三层拉通才能真正把一个画图动作升级成一套设计体系。我自己的体验是一旦形成了这套闭环画图这件事的时间成本至少下降一半而且越往后期收益越明显。1.3 谁最适合切换到文本化 diagram-design如果你符合下面任意一条我强烈建议你认真看完这篇文章你的团队已经用 Git 管理代码但架构图、流程图、时序图还在用网盘文件名的模式管理你每周都要给不同的方案画边界基本相同的系统架构图你在写技术文档时需要反复截入系统图你的项目往往需要“图随码走”代码变了图要跟着变你需要对多张图的样式做统一迭代比如换一套配色、统一字体。但坦白讲并不是所有人都适合完全抛弃图形化工具。下面我会专门用一节讲清楚不同工具的边界免得你看完文章之后盲目切换生产力工具结果发现不适合自己又切换回去。2. 工具链选型逻辑五类方案各自的边界在哪里我这几年陆陆续续把主流工具都用过一遍包括 Mermaid、PlantUML、Graphviz、D2 以及图形化的 draw.io/Excalidraw。每个工具都有自己的脾气搞清楚它们的边界比跟风选型重要得多。2.1 Mermaid文档内嵌生态的首选Mermaid 是我日常使用频率最高的方案没有之一。原因很简单它的生态位是“文档内嵌图表”尤其适配 Markdown 系文档体系。Mermaid 的核心能力是把类似文本的 DSL领域特定语言渲染成流程图、时序图、状态图、甘特图等支持直接嵌入 GitHub Markdown、GitLab 和各类文档站。你在代码文档库里面写一个mermaid代码块渲染层会自动识别并画出图表。我用它最多的场景是 README、架构文档、内部 wiki、接口时序说明。这类场景的特点是“图应该长在文字旁边”而不是独立成一个文件。Mermaid 配合 Markdown 天然实现这一点零心智负担。但 Mermaid 也有硬伤。它的自定义能力偏弱复杂样式控制、大型图的布局稳定性都不算优秀。图一旦超过几十个节点布局往往会自动变得奇怪想手动调又缺少图形化编辑器那样直观的拖拽能力。所以我的定位是Mermaid 承担高频、轻量、文档内嵌类图表。2.2 PlantUMLUML 序列图的老牌选择PlantUML 是最早让我觉得“文本画图这事靠谱”的工具。它发展了十几年语法成熟对 UML 的支持极其全面用例图、类图、时序图、活动图都有特别适合做软件设计相关图表。PlantUML 有一个非常独特的优势对时序图的支持非常细腻。在描述系统之间消息交互时PlantUML 的语法几乎是为这个场景量身定制的alias 可以让你把复杂的对象名映射成简洁的展示名激活框、消息序号、异步消息这些语义都表达得很清楚。缺点是渲染依赖 Java 环境首次启动需要下载 jar 包渲染速度也不快而且它生成图形的审美比较“工程师”——默认配色和字体风格都偏朴素想做得好看需要额外工作量。就我个人的体感PlantUML 适合作为“设计期交流工具”用完之后如果图要放对外文档我通常还是手工优化样式。2.3 Graphviz布局算法的隐藏强者Graphviz 的核心不是“画图”而是“布局”。它用 dot 语言定义节点和边然后通过一套严谨的图布局算法自动计算节点位置。这一点和 Mermaid、PlantUML 完全不同后两者的布局引擎更多是“能排开就行”而 Graphviz 的 dot/neato/fdp 等引擎对复杂有向图、层次图的布局质量有几十年的算法积淀。举一个我实际遇到的例子画一个微服务依赖图有 60 多个节点、100 多条边。用 Mermaid 渲染出来边交叉严重换用 Graphviz 的 dot 引擎它在处理分层时会把同层节点对齐、减少交叉出来的图一眼就能看懂核心链路。但是 Graphviz 的学习曲线也真实存在。dot 语法虽然简单但要写出布局质量高的图需要懂 nodesep、rankdir、splines、constraint 这些参数很多人到这里就放弃了。我的建议是当你需要处理复杂系统关系图时别犹豫直接上 Graphviz花一小时学语法之后会一直受益。2.4 D2新一代文本图表的设计感D2 是近年比较受关注的一个新工具出自 Terrastruct 团队。它的定位是“现代的、声明式的图表语言”语法比 Mermaid 更统一比 Graphviz 更易读。D2 官方文档里有一个很打动我的设计理念正确地确定结构关系而不是让用户手动去调位置。它的默认样式和布局在现代感上明显强于 Graphviz 和 PlantUML。举个例子在 D2 里面用a - b表达一条边在许多顺序下布局都稳定而且它的自动配色系统里面内置了多个主题基本不需要手动定义颜色。目前 D2 比较大的短板是生态还在建设期网上的教程和现成模板相对少和文档系统的集成比如 GitLab、GitHub 原生支持不如 Mermaid。我个人用它来画对外展示的架构图效果会比较精致。2.5 Excalidraw / draw.io该保留的图形化白板这套文章虽然主要讲文本化 diagram-design但我不建议你完全扔掉图形化白板工具。在探索期、头脑风暴期、快速画草图与同事对齐想法时图形化工具仍然效率更高。Excalidraw 的“手绘风”很适合早期讨论强调想法的敏捷性不受精细对齐的束缚draw.io 则更适合团队协作项目和复杂的分层图绘制支持多人实时编辑。所以我的工具组合是日常文档图用 Mermaid复杂系统关系图用 Graphviz对外正式架构图用 D2头脑风暴用 Excalidraw。下面用一个表格把这五个方案的边界和适用场景摆清楚你可以直接对照表做决策。工具文本化布局算法UML 支持文档生态对外美观度学习曲线适合场景Mermaid强中中极强中低文档内嵌图PlantUML强中强中中中UML 时序图Graphviz强极强中中中中高复杂依赖关系图D2强强弱中强低中对外架构图Excalidraw/draw.io弱手动弱中极强低头脑风暴/精细设计这个表格是我自己实际操作中沉淀下来的结果不是“一律文本化”的激进派结论。选型的第一原则永远是匹配场景而不是追逐新工具。3. 从零搭建一套可维护的图表设计流水线工具选好之后接下来关键的事情是组织流水线。这一步做得好了图表设计的日常维护成本会大幅下降。下面以最通用、最容易上手的 Mermaid Node CLI 方案为例完整走一遍我搭建流水线的全过程这套思路也适配 Graphviz 和 D2。3.1 初始化目录结构与 npm 工程第一步在一个独立目录里初始化工程。我习惯把所有的图文件放在项目根目录下的diagrams/子目录用src存放源文件、dist存放渲染产物结构长这样├── diagrams/ │ ├── src/ │ │ ├── system-overview.mmd │ │ ├── order-flow.mmd │ │ └── payment-seq.mmd │ ├── dist/ │ │ ├── system-overview.svg │ │ ├── order-flow.svg │ │ └── payment-seq.svg │ ├── package.json │ └── render.js初始化的时候直接npm init -y然后安装mermaid-js/mermaid-cli它就是 Mermaid 官方提供的命令行渲染工具。npm install -g mermaid-js/mermaid-cli装完验证一下mmdc --version如果命令可用说明基础环境就绪。这里有一个比较容易踩的坑mmdc 底层依赖 Puppeteer 来调用无头浏览器渲染 SVG/PNG第一次运行时可能会下载 Chromium。如果你所在网络的下载比较慢可以用系统已有的 Chrome 或者配置镜像源否则你会卡在这一步卡很久。3.2 编写渲染脚本把手工命令变成一键执行单个文件渲染很简单mmdc -i src/system-overview.mmd -o dist/system-overview.svg但图多了之后逐个敲命令就很蠢。我在render.js里写了一个脚本自动遍历src下所有.mmd文件并批量渲染同时支持监听模式文件变更后自动重新渲染。下面是一个精简但直接能用的版本const { execSync } require(child_process); const fs require(fs); const path require(path); const srcDir path.join(__dirname, src); const distDir path.join(__dirname, dist); if (!fs.existsSync(distDir)) { fs.mkdirSync(distDir, { recursive: true }); } const files fs.readdirSync(srcDir).filter((f) f.endsWith(.mmd)); const watch process.argv.includes(--watch); function renderAll() { files.forEach((file) { const input path.join(srcDir, file); const output path.join(distDir, file.replace(.mmd, .svg)); console.log(Rendering ${file}...); execSync(mmdc -i ${input} -o ${output}, { stdio: inherit }); }); } renderAll(); if (watch) { fs.watch(srcDir, { persistent: true }, () { console.log(File changed, re-rendering all...); renderAll(); }); }把这个脚本放到package.json的 scripts 里{ scripts: { diagram:build: node render.js, diagram:watch: node render.js --watch } }之后每次改完.mmd文件跑一句npm run diagram:build就能更新全部产物。这在写技术文档时特别顺手文档里的图片引用直接指向dist/system-overview.svg图变了文档自动跟着变不会再出现“图上画的和文档里写的对不上”的尴尬。3.3 打通文档链接让图表真正存活在文档体系里文本化图表最大的价值之一是图表不再是脱离上下文的一个孤立文件。我在团队内部的技术文档库里会用相对路径直接引用渲染出来的 SVG请参阅系统总体架构[system-overview.svg](../diagrams/dist/system-overview.svg)如果文档平台支持内嵌资源还可以把 SVG 转换并嵌入页面。这里我推荐 SVG 而不是 PNG原因有两个一是 SVG 是矢量图放大不模糊适合 Retina 屏和印刷二是 SVG 文件可以内联进 HTML方便统一做样式调整。3.4 用 Git 跟踪与 CI 卡点保证图表不腐化目录和脚本都就绪后必须把图表纳入 Git 跟踪。这里有个策略问题.mmd源文件必须入库dist下的 SVG 产物也需要入库。为什么产物也要进 Git因为团队成员不一定都安装了 mmdc有时候别人只是为了改文档标题不应该被迫搭一套 Node 环境。SVG 产物入库后普通人改完文档引用的图仍然可见只有要改图内容时才需要碰源文件。再往后一步如果你的项目已经有 CI建议加一个流水线步骤让 CI 在每次 MR 时执行渲染脚本然后用git diff --exit-code校验产物是否和源文件保持同步。如果开发者改了.mmd但没有重新渲染 SVGCI 就会失败提醒他补产物。- name: Render diagrams run: | cd diagrams npm ci npm run diagram:build git diff --exit-code dist/这个卡点看着简单但能根治“图和源码不一致”的问题。说实话团队里有了这张卡比任何口头要求都管用。4. 文本语法如何影响图表的长期可维护性切换文本化绘图之后很多人第一个感觉是“我终于可以 diff 图了”。但真正决定图表长期维护成本的其实是语法的设计质量。前面选的工具不同语法风格差很多这会直接影响你后续维护的心情。4.1 好的语法让图表 diff 友好为什么说传统的 draw.io XML 不友好因为一次简单的框移动DOM 节点顺序、坐标值、样式字符串可能全变diff 之后你根本看不出来“意图”的变化。而 Mermaid 这类 DSL 不同每一行就是一个语义单元。比如graph TD A[用户请求] -- B[网关] B -- C[订单服务] B -- D[支付服务]在这里“增加一个服务”就是增加一行边定义“改一个节点名称”就是改一对中括号里的内容。评审者从 Git diff 中一眼就能看出这次变更的意图。D2 的语法甚至更紧凑用户请求 - 网关 - 订单服务 网关 - 支付服务这种“意图即代码”的属性让文本化图表的 review 成本大幅低于图形化方案。这也是我为什么一直强调选工具时不要只看渲染出来的图好不好看要看它源文件的阅读体验和维护成本。4.2 Mermaid 语法核心从 flowchart 到 sequenceDiagram我从 Mermaid 最常用的两种图来讲讲它的语法设计逻辑。flowchart 的语法核心是节点与边。节点用各种形状语法标记矩形、圆角矩形、菱形、圆柱等边用箭头表示单向、双向、虚线。它的设计非常直观稍微看一遍文档就能上手graph LR Start([开始]) -- Process[处理中] Process -- Cond{是否完成} Cond -- 否 -- Process Cond -- 是 -- End([结束])我实际用下来觉得 Mermaid 最贴心的设计是“子图”subgraph。当一张图有清晰的分层时用 subgraph 把同层节点包起来不仅能视觉上分区也能避免节点跨层导致布局混乱。sequenceDiagram 的语法则更强调查看网络调用的顺序。sequenceDiagram participant C as 客户端 participant S as 服务端 participant DB as 数据库 C-S: 创建订单请求 S-DB: 事务写入 DB--S: 返回主键 S--C: 返回订单信息这套语法的好处是“participant 别名 as”机制底层对象名和展示名分离。服务端叫UserServiceV2_Internal展示时只需要显示“用户服务”维护者不用看一堆驼峰命名的类名。4.3 D2 语法更统一Graphviz 尽力而为D2 在设计上有一个野心让一切图表表达都用同一种语法范式。比如容器和连接关系在 D2 里都是关键字: 内容的结构direction: right 用户: { shape: person } 网关: { 样式: { fill: #E3F0FF } } 用户 - 网关 网关 - 订单服务这种统一性带来的好处是记忆负担低如果你要画对比鲜明的架构图D2 的缺口补全能力也比较强。缺点是社区模板少早期摸索需要一些时间。Graphviz 则是完全另一套体系。dot 语言把重心放在“关系”上用有向边、无向边、集群——用 cluster 表示子图——来表达层级digraph G { rankdirLR; node [shapebox, stylerounded]; subgraph cluster_gateway { label网关层; gateway_api [labelAPI 入口]; } subgraph cluster_service { label服务层; order_service [label订单服务]; pay_service [label支付服务]; } gateway_api - {order_service, pay_service}; }如果你想精确控制布局Graphviz 的 rank、weight、constraint 等属性非常强大但代价是门槛更高。而且 dot 语法在 diff 时的表现比 Mermaid/D2 略逊一筹——它虽然有语义但属性多了之后diff 阅读体验会下降。4.4 我的建议为不同图定义不同的“语法纪律”最近我收到一个感受很深的启发文本化绘图更像写代码语法自由度过大和过小都不好。大型项目里如果完全不约束图表的写法三个月后你会看到五花八门的风格有人把节点写成大段文字有人把边搞成八爪鱼维护起来想砸键盘。为此我在团队里定了几条不成文但不讲情面的规则节点文字宽度不超过 20 个字符过长就拆成子图或者加注释避免图上文字挤成一团。一个.mmd文件控制在一屏左右。超过就先拆分比如把“系统总览”和“订单详细流程”拆成两个图而不是画一张巨图。所有节点命名用有意义的英文展示文字用中文避免出现“node1、node2”这种谁都看不明白的名字。颜色、字体等样式不出现在单张图的业务逻辑里统一走全局主题保证全库风格一致。这套纪律要是不定你很快就会发现“文本化画图”变成“另一种方式的乱画”那就违背我们切换工具的初衷了。5. 样式组织和排版控制复杂图的秩序感从哪来很多人在文本化绘图时有一个疑问图的“美观”到底怎么保证鼠标拖拽还能手动对齐文本化之后会不会只能看天吃饭其实文本化绘图的美观本质上由两件事决定一是主题样式是否统一二是布局算法是否适合当前图的类型。这两件事掌握了文本图的颜值根本不会输给手拖图。5.1 样式统一从单图配色到全局主题Mermaid 支持在文件开头使用%%{init: {...}}%%来初始化主题参数。我在所有工程里都会把主题参数抽成一个公共配置或者直接写在每个图文件的头部%%{init: {theme: base, themeVariables: { primaryColor: #E1F0FF, primaryTextColor: #1E293B, primaryBorderColor: #3B82F6, lineColor: #64748B, fontFamily: PingFang SC, Microsoft YaHei }}}%%这套写法的核心价值是让整套文档体系里的图都用同一套品牌色和字体。你不可能接受产品官网一个按钮一个颜色同样你也不应该让架构图每张配色都不一样。实际上我更推荐把 themeVariables 放在配置文件mermaid.json里运行时通过mmdc -c mermaid.json指定这样每个源文件就能保持干净样式变更也能只改一个文件{ theme: base, themeVariables: { primaryColor: #E1F0FF, primaryTextColor: #1E293B, primaryBorderColor: #3B82F6, lineColor: #64748B, fontFamily: PingFang SC, Microsoft YaHei } }Graphviz 里类似的机制是默认字体和颜色定义D2 则内建了多个主题如--theme 300选好后基本够用。关键是形成“全局样式优先”的意识而不是每张图自己造一套轮子。5.2 布局引擎选择同一张图换个引擎天差地别Graphviz 的布局质量很大程度上依赖引擎选择。下面是我实拍过的体会dot引擎适合有向层次图默认按上下或左右分层是画流程图、层次结构图的首选。neato引擎适合无向图更强调力导向布局适合表达关联关系但无明显方向的结构。fdp也是力导向适合更大规模的图速度相对快。同样一组节点关系用dot画出来是清晰的层次换成neato就会变成一团以中心发散的“星云”。没有绝对的好坏但选错了引擎通常会让图显得乱。Mermaid 的 flowchart 默认布局也会对不同图类型有不同的表现。遇到一张大图布局乱掉时我常用的调整手段是给节点分组利用subgraph强制划分区域调整direction参数改TD上下、LR左右用classDef批量样式节点减少内联样式降低布局引擎的复杂度。5.3 大型复杂图的模块化拆分策略控制复杂度的终极方案是拆分而不是硬画。一张图超过 30 个节点后无论你的布局算法多强可读性都会急剧下降。这时候要做的是画一张主图说明整体关系然后针对每个子系统画子图用链接把子图嵌进主图。Mermaid 支持通过flowchart的click加上 URL 链接实现互动跳转在有 HTML 文档环境下看主图的人可以直接点进子图。Graphviz 也可以用href属性绑定跳转。这套“主图总览 子图分述”的组织方式相当于给你的图表设计做了系统架构。我在项目里最常用的一张主图只有 8 个节点每个节点关联一张子图。总的业务复杂度和一张 60 节点的大图完全一样但阅读起来轻松太多——你不需要一次处理所有信息。5.4 导出参数别让输出图片毁掉好布局画得好好的图导出来一团糟这种情况我见得太多了。Mermaid CLI 默认导出 PNG 时如果没指定尺寸会按默认比例放大有时候会导致周边留白过大或者元素被裁切。实际经验是导出时用-w指定宽度单位像素并用--scale控制分辨率mmdc -i input.mmd -o output.png -w 1920 -b white -s 2-b white是为了避免透明背景在某些文档里展示异常-s 2是两倍缩放配合高分屏使用效果更佳。SVG 导出则很少遇到清晰度问题所以能导出 SVG 的场景我优先导 SVG。6. 实测排错六个高频问题的根因与对策下面这一节的内容全部来自我实际踩过的坑每一个都让我浪费过时间希望你不用再踩一遍。6.1 中文字体失效导致的乱码在 Mermaid 里写中文节点默认主题在部分 Linux 环境会渲染成方块。根因是 Puppeteer 调用 Chrome 渲染时环境中没有匹配的中文字体。对策有两个在 mermaid.json 的 themeVariables 里明确指定一个团队通用的中文字体比如“PingFang SC”macOS或“Microsoft YaHei”Windows/Linux。在服务器环境里安装对应字体包比如 Ubuntu 可以用apt-get install -y fonts-noto-cjk。我遇到过一次 CI 渲染的架构图全部乱码排查了一圈发现是官方镜像里根本没有中文字体加一行安装命令就解决了。这个问题在本地正常但 CI 乱码的时候优先查字体别浪费时间调别的。6.2 HTML 标签冲突导致渲染异常Mermaid 的一部分语法借鉴了 Markdown比如[文字]、斜体、加粗在节点文字里如果出现、、这类 HTML 敏感字符会被解析器误认为 HTML 标签导致渲染异常。比如A[订单金额100元的请求]这段会出问题因为100被当成标签开头。解决办法是把敏感字符做转义或者直接用引号包裹节点文字A[订单金额100元的请求]加双引号是 Mermaid 官方比较推荐的做法。我在项目里有个约定节点文字里只要出现任何符号一律加引号从源头上消灭这个坑。6.3 导出图片内容被截断这个问题出现在我早先处理超宽架构图时渲染出来的 PNG 左右两侧少了一段。根因是默认画布尺寸不够内容溢出后超出了截图范围。对策是在 CLI 命令里加大预留空间或者将输出格式换成 SVG。SVG 天然没有尺寸上限内容多少都会完整呈现。如果你一定需要位图可以用后续命令把 SVG 转成 PNGmmdc -i input.mmd -o output.svg # 然后借助 rsvg-convert 或 Inkscape 转换为目标尺寸6.4 布局抖动图随缘变化文本图表的布局稳定性在不同版本间可能存在差异。你辛苦调整好的层次升级一下 Mermaid 版本后整个图的布局变了这种情况在 CLI 工具里也存在。我的做法固定依赖版本。package.json里锁死mmdc的版本号升级时单独提交一次 MR验证所有图输出符合预期后再统一更新。不要把它丢在latest这种自由浮动的 tag 上否则你永远无法预测明天渲染出来的图长什么样。6.5 多人协作时 .mmd 文件冲突多人维护同一个图目录时.mmd文件会出现 Git 合并冲突。这个问题的根因和代码冲突一样解决方案也相似尽量让不同图文件职责单一避免多人同时编辑同一个文件。如果确实需要多人高频改同一张图用文本化工具反而不如图形化协同工具。这是我唯一的“回退”建议——工具永远要服务于协作模式强行把一个轮子拧成方的没必要。6.6 大图性能瓶颈当单个图节点超过百个Mermaid、PlantUML 的渲染会很慢有时甚至会卡死浏览器。Graphviz 相对好一些毕竟它生来就为处理大规模图设计。面对大图我的优先级是首先拆分模块这是根源解法其次如果一定要渲染大图用 Graphviz 的neato/fdp引擎 关闭某些算法优化选项通常能得到可接受的结果。文本化绘图本来就不应该追求“一图包万物”拆开之后性能问题和可读性问题一起被解决。7. 最后分享一个小技巧为什么我放弃了内嵌 Mermaid 而选择预处理产物文章最后还忍不住分享一个让我体验“质变”的小调整内嵌mermaid依赖文档平台实时渲染虽然用起来爽但有几个现实问题不同平台的 Mermaid 版本不一致渲染结果参差图片无法直接引用到其他文档或 PPT平台的渲染结果也无法纳入 Git diff 管理。后来我全面改成“预渲染 SVG 产物 文档引用”的方式在文档仓库里用 CLI 渲染 SVG提交到 Git然后文档用相对路径引用。好处是所有图的渲染环境一致结果一致SVG 产物可以被任何文档复用不受平台锁死图片版本的变更记录同样可以在 Git 里看到。代价是每次改图必须重新跑一次构建命令。但结合前面的npm run diagram:watch监听模式这个代价几乎可以忽略——保存文件图就自动更新好了。现在我的所有技术文档基本不再依赖平台内嵌渲染了回到本文开头说的那个场景评审会现场所有图都来自同一个版本任何人都能指出“这次的 diff 是加了支付服务、调整了链路顺序”而不是在模糊的截图里反复拉扯。真正把 diagram-design 当成一套工程体系来维护这是我这一年多做得最值的一件事。
返回列表