DiagraDesign:用代码化思维管理架构图,让绘图成为工程的一部分
发布时间:2026/9/8 3:50:02 锦皓数字建站

当团队里开始有人问“这张架构图是谁画的还能不能改”的时候基本意味着你们需要一个叫diagram-design的东西。别被这个名字吓到它不是什么高深框架而是一套“把画图当写代码来对待”的思路和工具链。我最初关注到 diagram-design是因为维护了几年的系统文档里架构图全部躺在 draw.io 的二进制文件里改一次要半天改完还看不清谁改了什么。后来我彻底切到“文本代码化画图”的工作流把流程图、时序图、架构图全部用 Mermaid、Graphviz 这类声明式工具管理起来这才算真正解决了图表维护的痛点。这篇文章我会从思路、工具选型、实操语法、工程化集成到踩坑实录完整拆解我个人的 diagram-design 工作流。不管你是后端开发、前端、架构师还是写技术文档的同学只要能碰命令行这套方法就能直接抄作业。1. 我为什么不再拖拽画图了先说结论手动拖拽画图适合一次性的临时草图不适合需要持续维护的技术图。这个观点可能有点绝对但经历过“图永远比代码旧”的痛苦之后你会明白它有多实在。1.1 拖拽画图的三个长期痛点过去我用传统画图工具比如 Visio、draw.io、ProcessOn画一张图并不难问题出在图的“生命周期”上。首先是版本管理。传统工具的源文件通常是二进制或者私有格式存在 Git 里就是一个巨大的 blob没法 diff、没法 review。同事改了节点位置、改了线条颜色你根本不知道具体动了什么。有时候合并分支图上莫名其妙多了一个方块也没人说得清是谁加的。其次是协作成本。团队里多个人同时编辑一张图几乎一定会出现“各改各的、最后手工合并”的局面。因为图形工具的并集天然难大家只能排队改或者靠聊天工具传来传去最后总有一版覆盖掉别人的修改。最后是更新滞后。代码改了图没改图改了代码又改了。这种“图文不同步”在拖拽工具下几乎无解因为修改成本太高大家宁愿去读代码也不愿去伺候图久而久之图就成了摆设。1.2 代码化画图的本质让图成为工程的一部分diagram-design 的核心思路是把图形看作一种结构化文本用声明式语法描述节点、连线、分组和样式再交给渲染引擎生成 PNG、SVG 或 HTML。拿流程图举例子传统方式是从工具栏拖一个“矩形”放到画布双击改文字代码化的方式是写一段文本graph LR A[用户请求] -- B{鉴权} B -- 通过 -- C[业务处理] B -- 拒绝 -- D[返回错误]这段文本就是一个图。你可以把它放进 Git让同事给你提 PR用 diff 工具看每一行改动甚至可以在 CI 里自动渲染检查语法对不对。打个比方拖拽画图像是手写纸质简历写错了只能用涂改液代码化画图像是用 Markdown 写简历内容、格式、版本全部可追溯。这个思维转变是 diagram-design 带给我最大的收益。1.3 什么样的人和团队适合 diagram-design如果你是“画一张图交给老板看一眼”的场景我建议你还是用拖拽工具省事。但如果你属于下面任意一种情况就很有必要切换到文本画图文档里需要长期维护架构图、时序图、状态图这些“易变图”而不是一次性可视化团队希望对图表做 Code Review让图跟着代码一起迭代需要跨平台、跨工具复用同一份图数据比如既要在 GitHub 里显示又要导出到 PDF有自动化需求比如每次发版自动更新一张依赖关系图。我接触过的不少团队真正推不动 diagram-design不是因为工具不好用而是因为“手动拖图”已经成了习惯。所以下面我会把工具链和实操串起来讲让大家看到一个完整的替代方案。2. 主流 diagram-design 工具选型我的选择思路代码化画图的生态已经挺成熟了但不同工具的定位差别很大。我梳理一下最常见的四类Mermaid、Graphviz、PlantUML、diagrams.netdraw.io给出选型建议。2.1 Mermaid轻量、生态好最适合文档嵌图Mermaid 是目前最“出圈”的文本画图语言。语法直观学习曲线非常平缓而且被 GitHub 原生支持Markdown 里直接嵌代码块就能渲染。我日常工作里七八成的图都用 Mermaid尤其是流程图、时序图、状态图和饼图。优点是上手快、社区活跃、彩虹屁一样多的样式主题缺点是复杂布局能力弱节点一多容易挤成一团对精确排版控得不够。所以它适合“表达逻辑”不适合“做精细排版”。2.2 Graphviz布局算法强大适合复杂关系图Graphviz 是老牌开源工具底层用 dot 语言描述图结构由引擎自动计算节点位置。它的最大特点是布局算法强比如层级图、依赖图、状态机这种节点多、关系密的场景Graphviz 的自动布局比 Mermaid 更科学。代价是语法偏“程序化”刚开始用会觉得不直观而且样式体系比较古典。但如果你要画“微服务调用关系图”“代码模块依赖图”Graphviz 是非常可靠的选择。2.3 PlantUML面向 UML 的工程化利器PlantUML 是我在项目内做架构文档时的秘密武器。它用文本描述 UML 图时序图、用例图、组件图、部署图都能画还支持 C4 模型可以和架构描述结合得很好。它比 Mermaid 更偏向“工程建模”语法里有类的属性和方法、参与者、消息序号这些概念渲染出的图也更接近标准 UML 风格。缺点是依赖 Java 环境稍微重一些。2.4 diagrams.netdraw.io半拖拽半文本的折中方案有人会说 diagrams.net 不是拖拽工具吗其实它支持 .drawio 文件直接存成 XML 文本格式也能在 GitHub 里 diff。不过说实话它更多是把“拖拽的结果”文本化了并没有改变“手动摆放”的交互模式。我的定位是作为临时协作工具。别人发我一个 draw.io 文件我能快速打开、补一笔、导出发回去。但它不是我的主战工具。2.5 选型对照表与建议工具语法难度布局能力典型场景渲染依赖Mermaid低中文档嵌图、快速流程、时序、状态纯 JS / CLIGraphviz中强依赖图、状态机、复杂关系本地引擎PlantUML中高中强UML 建模、C4 架构Javadiagrams.net极低手动强快速草图、跨团队临时协作无我个人的默认组合是文档里用 Mermaid复杂关系用 Graphviz架构建模用 PlantUML临时头脑风暴用 diagrams.net。这不是“都要学”的负担而是不同场景下效率最优的自然选择。下面我挑最常用的 Mermaid 做主菜详细走一遍实操。3. 核心实操用 Mermaid 完成一套架构图3.1 环境准备VS Code 插件与命令行 CLIMermaid 零依赖也能玩GitHub 和很多笔记软件都支持。但如果你想在本地渲染、批量导出、接 CI我建议装一下 CLI 工具。Node.js 环境下执行npm install -g mermaid-js/mermaid-cli装完之后可以用mmdc命令把.mmd文件渲染成 PNG/SVG/PDFmmdc -i input.mmd -o output.svg --width 1200 --backgroundColor whiteVS Code 我推荐装“Markdown Preview Mermaid Support”插件写 Markdown 时可以直接预览 Mermaid 代码块。预览的实时反馈很重要能帮你快速调整语法错误。提示如果运行时提示 Puppeteer 相关错误通常是浏览器内核下载失败需要翻看你的网络代理或换用puppeteer的 mirror 配置。这个我放到后面问题章节细讲。3.2 三张最常用的图流程图、时序图、状态图Mermaid 能画的图很多我先拆三张最常出现在研发文档里的。流程图graph。graph TD A[开始] -- B{是否有权限} B --|是| C[执行操作] B --|否| D[提示无权限] C -- E[记录日志] D -- ETD表示方向为从上到下改成LR就是从左到右节点里[文本]是矩形{文本}是菱形判断(文本)是圆角矩形连线后面加|是|可以给边加标签。时序图sequenceDiagram。sequenceDiagram participant U as 用户 participant S as 服务端 participant D as 数据库 U-S: 发起登录请求 S-D: 查询用户信息 D--S: 返回结果 S--U: 返回登录结果participant声明参与对象可以起别名-是实线箭头--是虚线返回能很好表达调用链。状态图stateDiagram-v2。stateDiagram-v2 [*] -- 待支付 待支付 -- 已支付: 支付成功 待支付 -- 已关闭: 超时关闭 已支付 -- 已完成: 确认收货 已支付 -- 退款中: 申请退款 退款中 -- 已完成: 退款成功状态图用于表达状态流转和代码里的状态机一一对应写的时候要保持状态命名和代码枚举一致。3.3 从零设计一张微服务系统架构图我用一个“订单服务 支付服务 消息队列”的简化微服务架构图展示完整的思考过程。先明确图里要表达什么外部接入方、网关、核心服务、依赖组件、服务间调用关系。然后确定拆分层次最上层是客户端中间是网关和业务服务底层是中间件和数据库。写成 Mermaidgraph TB subgraph 客户端层 U[Web 前端] A[App 客户端] end subgraph 接入层 G[API 网关] end subgraph 服务层 O[订单服务] P[支付服务] I[库存服务] end subgraph 依赖层 R[(Redis)] DB[(MySQL)] MQ[消息队列] end U -- G A -- G G -- O G -- P O -- I O -- DB P -- DB O -- R P -- R O -- MQ P -- MQ这里面有几个细节值得注意subgraph后面加名字可以把一组节点收进一个区块让复杂图有层次感节点的 ID 我全部用大写字母别名这样改动文字描述时不需要改连线引用箭头方向统一由调用方指向被调用方读图很顺不会出现一半反向一半正向的别扭感。架构图的节点不要放太多业务细节每个服务一个方框下面可以用文字补充职责。如果有更多描述文字我通常用换行或悬浮注释避免图上塞满字。3.4 样式与主题定制让图不再“默认脸”Mermaid 给每个企业级文档要做品牌化默认配色确实不够好看。我平时会这样定制%%{init: {theme: base, themeVariables: {primaryColor: #e6f0ff, lineColor: #334466}}}%% graph TB A[下单请求] -- B[校验库存] B -- C[创建订单] C -- D[返回成功]想对特定节点加样式可以用classDef和classgraph LR A[核心服务] -- B[辅助服务] classDef core fill:#ffe6e6,stroke:#cc0000,stroke-width:2px; class A core样式的重点不是“炫”而是用颜色快速区分“核心链路”和“旁路逻辑”。这个对复杂系统理解帮助特别大。4. 进阶Graphviz 与 PlantUML复杂图怎么画4.1 Graphviz 的 dot 语言入门当图里节点超过 30 个、关系高度交织时Mermaid 往往会排出一坨让人绝望的线条。这时候我切 Graphviz。先看个最小例子digraph G { rankdirLR; node [shapebox]; A - B [label调用]; B - C [label依赖]; C - A [label回调]; }digraph表示有向图rankdirLR指定布局方向从左到右node [shapebox]对所有节点统一设置形状label给边加文字。Graphviz 的厉害之处是自动布局引擎把节点扔进去边连好它自己会计算位置。复杂依赖关系下它会尽量让连线不交叉或减少交叉。相比之下Mermaid 在这方面弱很多。我常用它的一个场景是录入系统模块之间的数据流。比如有个几十个微服务互相调用手动画图绝对会崩溃但用 dot 描述依赖关系后渲染出一张全局调用关系图可以很直观地发现“某个服务被所有服务调用这可能是瓶颈”。4.2 PlantUML 的 C4 模型玩法C4 模型是一种分层描述软件架构的方法Context上下文、Container容器、Component组件、Code代码。PlantUML 提供了 C4 相关宏可以用文本代码快速生成架构图。例如startuml !include C4_Context.puml Person(user, 普通用户, ) System(store, 商城系统, ) System_Ext(pay, 第三方支付, ) Rel(user, store, 浏览/下单) Rel(store, pay, 调用支付) enduml这种写法的好处是架构角色有语义而且官方提供了一系列图标主题生成出来的架构图非常专业。做架构汇报、系统设计评审的时候拿这套图出来很有说服力。4.3 布局调优的两个小经验第一个经验别手动调坐标靠约束引导布局。Graphviz 里可以通过rank、weight、constraintfalse这些属性影响布局而不是手动指定 x/y。手动调坐标的图一旦数据变化就全乱靠约束引导的图增减节点后布局会自动调整。第二个经验复杂图优先分组而不是追求一图打尽。我见过有人非要把所有系统画到一张图里结果图放大到 200% 都看不清。正确的做法是用subgraph或cluster把系统按层次分组每张图重点讲一条主线细节图单独再画一张用“图链接”串联。5. 让图表进入工程流程版本管理、渲染与文档集成5.1 把 .mmd 文件纳入 Git 管理画图一旦变成文本就能直接纳入版本管理。我习惯在仓库里建一个docs/diagrams目录docs/diagrams/ ├── order-flow.mmd ├── auth-seq.mmd ├── system-arch.dot └── README.md所有.mmd、.dot、.puml文件都用文本保存。改图 改文本 走 Merge Request 流程评审人打开 diff 就能看到“哪个节点加了”“哪条连线改了”这个体验是拖拽工具完全给不了的。5.2 在 CI 中自动渲染图片让 CI 自动渲染图可以保证“代码库里的图永远可用”。我提供一个简单的 GitHub Actions 思路name: render-diagrams on: push: paths: - docs/diagrams/** jobs: render: runs-on: ubuntu-latest steps: - uses: actions/checkoutv3 - uses: actions/setup-nodev3 with: node-version: 18 - run: npm install -g mermaid-js/mermaid-cli - run: | mkdir -p docs/assets for f in docs/diagrams/*.mmd; do mmdc -i $f -o docs/assets/${f%.mmd}.svg done - uses: actions/upload-artifactv3 with: name: rendered-diagrams path: docs/assets这套流水线会监听图片源文件的变更重新渲染 SVG把产物传到构建记录里。团队文档链接可直接指向产物的 URL保证每次看到的是最新版。如果文档平台支持直接渲染 Mermaid那段循环可以省略比如 GitHub 的 Markdown 预览天然支持。但需要长图、导出或统一缓存时我推荐自渲染。5.3 不同文档平台集成差异GitHub、GitLab、语雀、Notion 对 Mermaid 的生态支持不一GitHub/GitLabMarkdown 内置支持 mermaid 代码块最省心语雀支持 mermaid 绘图但版本和语法支持可能滞后Notion原生不支持 mermaid 代码块需要生成图片后再插入自建 Wiki多数支持插件Confluence 可通过第三方宏实现。我的原则是重要且频繁更新的图全部走 CI 渲染成 SVG再放到文档临时分享直接用平台内置渲染。两条路并行既不丢失实时性也不让平台限制工具链。6. 常见问题与排查技巧实录切换到 diagram-design 的过程中我踩过不少坑整理出来给后来人省时间。6.1 高频问题速查表现象原因解决办法中文显示成方块或乱码缺少中文字体或 SVG 字体未嵌入给渲染环境安装中文字体SVG 里指定font-familyPNG 渲染时设置--fontFamily子图subgraph背景不显示使用了较老版本语法确认 Mermaid 版本支持subgraph title写法升级到 v10箭头的方向不是预期TD/LR方向混用或节点引用方向反了统一graph TB或graph LR按调用方向描边节点太多布局混乱Mermaid 对超大型图支持有限拆图、分组或换 GraphvizMermaid CLI 报 Puppeteer 错误本地没下载 Chromium配置PUPPETEER_SKIP_DOWNLOAD或手动安装浏览器PlantUML 需要 Java 环境本身依赖本地项目安装 JDK或使用 PlantUML 在线服务CI 渲染乱码/字体缺失容器里没有字体文件Docker 里安装fonts-noto-cjk6.2 几个“文档不会写”的调试心得调试代码化图时最快的方法是二分法先把所有节点和连线删到只剩三条确认能正常渲染再逐步加回来哪一步开始崩就是那部分语法或结构有问题。还有一个很有用的技巧给每个节点 ID 起“语义化名字”避免使用 a、b、c 这种。语义化名字在 diff 时一眼能看出改了什么而且代码里也有自注释效果。比如orderService和paymentService比node1清楚得多。另外长文本节点一定要换行。一个节点里塞 100 个字渲染出来又长又丑。控制在两行以内太多就提取核心词详情放注释或说明文档。6.3 一个常见的认识误区代码化画图不等于“只会简单图”很多人以为 Mermaid 只能画“入门流程图”。其实 Mermaid 还能画象限图、甘特图、需求图、C4 图实验性Graphviz 更是可以画极其复杂的网络拓扑。难画的是“审美的图”因为自动布局不一定符合人的阅读习惯。我的解决办法是让图的结构主导布局让文字精简主导可读性颜色作为唯一强调手段。少即是多在 text 模式下比拖拽模式更容易实现。7. 一点个人体会也当作结尾在整个 diagram-design 的实践过程中最大的收获其实是思维转变。以前我画图是为了“交差”画完就忘现在写图是为了“表达”图跟着代码迭代、跟着架构演进成为真正活着的一等公民文档。用熟了之后我发现并不是所有图都需要代码化。一次性摊开讲个思路或者开白板头脑风暴拖拽反而更自然。但凡是会进仓库、会被反复修改、需要多人协作的图我都会优先写在文本里。这个边界感很重要别为了技术情怀把一次性的图也搬上 CLI那就是过度工程了。最后再分享一个小习惯每次画完架构图后我会在图下面附带一段“变更记录”用注释写清楚谁在什么时候改了什么。graph LR A[核心服务] -- B[新增加密模块] %% v2.1 - 2025-01-15 - 增加加密模块 %% v2.0 - 2024-12-01 - 初始化核心链路半年后你再看这张图会感谢当时多写了这三行注释。
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。