新闻详情

新闻详情

首页 / 资讯中心 / 详情

代码地图工具Archify:自动生成架构图,轻松梳理遗留系统

发布时间:2026/9/28 17:48:28来源:尧图网络
代码地图工具Archify:自动生成架构图,轻松梳理遗留系统
接手一个遗留系统的那一刻大概是我作为程序员最头疼的时刻。代码堆在那里文档早就过期前任留下的注释玄之又玄。你只能从入口文件开始一路追着调用关系走迷宫。如果这时候能有一张图把仓库里的模块、依赖、调用关系一次性铺开那节省的可不是一点点时间。这就是我做代码地图Archify这个工具的初衷让代码仓库在几分钟内自动生成一张可读的架构图把读代码找架构这件苦差事变成看图定位。Archify的核心价值在于它不只是根据目录结构画一棵文件树而是深入到代码本身的依赖关系、模块划分、引用路径用可视化的方式还原仓库的真实结构。不管你是刚接手一个新项目还是准备给老系统做重构评估又或者是团队里需要快速对齐架构认知这个工具都能派上用场。这篇文章我会从设计思路、核心原理、实操过程和踩坑经验四个层面完整拆解这个工具是怎么做出来、怎么用起来的希望能给同样被代码结构困扰的人一些参考。1. 为什么需要代码地图接手老项目的第一天有多痛1.1 架构图的真实痛点先说一个真实的场景。我之前接手过一个电商后台系统Spring Boot 的典型结构但是三年迭代下来包路径早已面目全非。原有的 controller 里塞了业务逻辑service 之间互相调用形成了环工具类散落在各个模块里。我花了两天时间画调用关系画到一半就崩溃了——因为调用链太复杂一张图画不下拆成几张图又对不上。后来我统计了一下这个仓库大概有 900 多个 Java 文件、40 多万行代码。靠人肉读代码去还原架构就算每天看 50 个文件也要将近三个礼拜。而且人脑记忆会失真你记住的调用关系可能第二天就忘了。更现实的是团队里不止一个人要看架构每个人自己理解出来的架构图都不一样开会时各说各话对齐成本极高。所以架构图这个需求本质上不是画一张好看的图而是快速获取一份可靠、统一、可复用的系统结构认知。手动画的图好看但不准确自动生成的图准确但不一定好看。Archify 的取舍是优先保证结构准确再把可读性做到及格线以上。1.2 现有方案的局限市面上其实有不少画架构图的工具比如 PlantUML、draw.io 这类手动绘图工具也有一些商业化软件可以做代码分析。但实际用下来都有各自的别扭。PlantUML 这类工具的问题在于图还是得人来画。你需要自己理清模块关系、写好描述文本它只是帮你排版。如果代码已经复杂到一定程度你根本不知道文本该怎么写——等于前置的人工分析一步都没有省。商业化的代码分析平台功能很全面但一般面向企业采购部署复杂、费用不低而且很多是针对特定语言深度优化换个语言栈就水土不服。对于个人开发者、中小团队或者偶尔需要摸清一个陌生仓库的场景来说这显然太重了。另外还有一个很现实的问题很多分析工具给出来的结果是一堆原始依赖数据比如类 A 引用了类 B、类 C、类 D但没有在架构层面做聚合。你看到的是一张密密麻麻的网而不是一个模块—模块的结构图。这就像给你一份全城的门牌号列表却没有人帮你把街道、区域划分出来。1.3 项目定位与选型思路Archify 的定位从一开始就不是替代所有架构工具而是填补从仓库代码到初步架构结构这一段空白。它解决的是第一步把代码仓库变成一张结构图告诉你有哪几个模块、模块之间怎么依赖、大概的代码分布是怎么样的。至于这张图怎么细化为正式的设计文档那是人工的事情。技术选型上我考虑了三个关键点。第一是语言覆盖面。团队的仓库不可能是纯 Java 或者纯 Python一个项目里 JavaScript、TypeScript、Java、Python 共存很正常。所以我没有选择单一语言的 AST 解析框架而是做了一层语言无关的分析层针对每种语言提供不同的解析适配器。核心的依赖提取逻辑仍然是基于对每种语言语法的理解但没有必要自己从头写全部解析器基础部分大量复用了社区成熟的解析库。第二是输出格式。架构图要能在不同场景下使用本地看图、集成到文档、在 CI 中自动更新。所以 Archify 同时支持输出 SVG、PNG、PlantUML 文本和 JSON 数据。SVG 适合交互查看PlantUML 适合进 Markdown 文档JSON 可以给其他工具二次处理。第三是性能。仓库大了之后文件扫描和依赖分析都是体力活Archify 在架构上用了多线程解析和增量缓存。同一个仓库只要没有变更第二次生成架构图的时间基本可以忽略。这套选型思路背后只有一个逻辑工具是为人服务的而人是懒惰的。如果工具用起来比手工画图还费劲那它再强大也没人用。Archify 的设计理念是从仓库到图片的一键式体验所有复杂细节都藏在内部。2. 核心细节解析架构图是怎么秒生出来的2.1 代码剖析的三维度目录、依赖、指标架构图的生成绝不是简单地把目录树转换成一棵树状图那没有任何信息量。Archify 的分析基于三个维度三个维度叠加在一起才构成一张真正的架构视图。第一个维度是目录结构。这是基础骨架可以理解为城市里的街道网格。每个目录、每个文件的位置关系、层级关系都在这层体现。但目录结构本身有欺骗性——有的项目目录划分得很清楚有的项目则是代码堆积在一起目录名早就不能反映真实职责。所以目录结构只能作为参考底图。第二个维度是依赖关系。这是最关键的信息层。分析代码的 import、require、include 等语句提取文件与文件之间的引用关系再聚合到模块层就能看出依赖方向。谁的被依赖度高谁是核心谁依赖别人很多谁可能是上帝类或者腐败的模块有没有循环依赖这些都是架构评估的重要信号。第三个维度是代码指标。Archify 会统计每个模块的代码行数、文件数量、注释率、函数数量。这些指标可以让架构图上每个节点的面积、颜色产生差异。比如大而全的模块节点面积更大注释率过低的模块颜色更红。这样一眼就能看出来哪些模块虚胖、哪些模块营养不良。三个维度结合起来架构图就不再是静态的房子照片而是带着数据的房产评估报告。当你看到一个模块依赖特别多、代码量又特别大、注释率还低那几乎可以断定这个是重构的重点对象。2.2 依赖解析器的选择为什么不能靠正则硬啃依赖提取是架构图准确性的命脉。很多人第一反应是用正则匹配 import 语句不就行了吗我最初也是这么想的但很快就被现实教训了。正则的最大问题是无法理解语法结构。同样一句 import在字符串常量里、注释里、动态拼接的代码里出现语义完全不同。比如下面的 Python 代码# 这只是一个普通注释import os import sys s import json用正则去扫会把 os、sys、json 三行全部当成真实的 import即使 json 只是字符串里的内容甚至没有任何实际效果。如果源代码里有大量这种误导性的内容生成的依赖图就会被污染。第二个问题是动态导入和别名映射。Java 的 import 相对规范但 JavaScript 生态里 import 可以带别名、可以动态导入、还可以通过 index.js 的桶文件间接导出。Python 的from a import b和import a.b.c在语义上有细微差别。这些不是正则能够精确处理的。所以 Archify 最终回到了真正了解语法的方案上使用语言解析器或编译器的 AST抽象语法树做提取。简单说就是把你的代码解析成一棵语法树然后从树里找到导入声明这个节点读取其真实的模块名和路径。这种方式与注释、字符串无关天然跳过所有干扰项。解析方式准确率性能实现成本正则匹配低容易被注释和字符串骗到快低AST 静态解析高能精确理解语法中等较高运行时插桩观察高且能捕获动态行为慢需要实际运行高第三个需要处理的复杂情况是动态导入。这是所有静态分析工具的天敌。代码里写import(path_var)只有运行起来才知道 path 是什么。Archify 的策略是退而求其次静态分析能精确解析的直接解析解析不了的做启发式猜测并标记为未知依赖在架构图上用虚线和问号标注。这样做的好处是不会因为少量动态导入让整个图的可靠性崩掉同时给使用者提供了进一步人工确认的线索。2.3 输出设计按场景决定图格式架构图不是一张图打天下。你在 IDE 里看的时候是交互式的放到团队文档里是静态的在 CI 流水线里可能是数据格式。Archify 用四种输出格式覆盖了这些场景。SVG 是主输出因为它在放大缩小的时候不糊。浏览器里打开支持元素的显示隐藏、节点的点击高亮。Archify 生成的 SVG 会在每个节点上挂对应的文件路径信息浏览器里点击节点可以直接定位到代码文件对排查问题很友好。PlantUML 文本是给文档场景准备的。因为现在很多团队的架构文档用 Markdown 维护PlantUML 可以直接渲染在代码块里也能和 GitLab、GitHub 的 Markdown 渲染无缝集成。问题在于 PlantUML 对文本组合的布局能力有限复杂图会乱所以在 Archify 里它是一个简化版输出选项。JSON 数据格式适合二次开发。你可以在 JSON 里拿到精确的模块列表、文件列表、依赖矩阵、指标数据然后自己写脚本做定制化分析。比如我可以只筛选出某几个核心模块之间的关系生成一张子图。值得专门说一点的是布局算法。图结构一旦复杂如果只是按依赖关系随意摆放节点会互相遮挡边会交叉得没法看。Archify 默认用的是分层布局——就是模拟从上到下、从左到右的依赖流动方向把被依赖最多的基础模块放在底部把业务入口放在顶部。这样画出来的图跟你平时画架构图的手习惯一致看起来最舒服。3. 实操过程从仓库到架构图的完整跑通3.1 环境准备与依赖安装在动手之前先说清楚 Archify 的形态它是一个命令行工具核心仓库存放在本地或远端 Git 服务器上运行时只需要有 Python 3.9 环境即可。因为涉及代码解析它依赖树形结构的解析核心把每种解析器独立封装为插件主程序不强制捆绑。安装过程非常简单一条命令pip install archify-cli装完之后验证一下版本archify --version看到版本输出就说明环境没问题了。如果遇到权限问题可能是当前 Python 环境受控可以在虚拟环境里装。我的习惯是任何工具都先建一个虚拟环境避免污染全局的 Python 包python3 -m venv archify-env source archify-env/bin/activate pip install archify-cli这一步还有一个隐藏的好处如果以后 Archify 升级不会影响其他项目也不会出现莫名其妙的包版本冲突。3.2 配置扫描参数拿到一个仓库之后第一步不是马上跑而是先规划好扫描范围和输出方式。Archify 提供几个关键参数来控制行为。archify scan --repo /path/to/your/repo \ --lang java,python,typescript \ --output out/arch.json \ --svg out/arch.svg \ --plantuml out/arch.puml--repo指向仓库根目录。--lang指定要分析的语言用逗号分隔分析器只会扫描对应后缀的代码文件避免浪费时间在无关文件上。--output对应的三种格式可以同时输出互不冲突。如果你只需要快速看一眼直接跑archify scan --repo .也可以默认会在当前目录生成arch.svg和arch.json两个文件。有几个参数是实操中经常用的我单独拎出来说。--ignore参数用来排除不需要分析的目录archify scan --repo . --ignore dist,build,node_modules,test这个参数必须加。因为很多仓库里有构建产物、第三方依赖、测试代码这些如果不排除架构图会被无关节点占满。我踩过的坑就是第一次扫描一个前端仓库时node_modules 里的文件全被当成了业务代码画出来的图有上千个节点根本没法看。加上排除之后瞬间清爽多了。--depth参数控制模块聚合的深度。默认情况下 Archify 会按照代码包的根去聚合模块但对于嵌套很深的项目比如 Java 的com.company.core.util这种路径如果全部展开图的深度会特别大。设一个--depth 3可以把三层以内的目录作为模块边界更浅的层级会更粗略但更容易抓住整体。3.3 生成架构图与解读扫描完成后最直观的产物是一张 SVG 图。打开它你会看到类似这样的结构顶部是入口模块中间是业务模块底部是基础支撑模块连线表示依赖方向。没有边相连的孤立模块会被折叠在分组里需要用工具打开才能看到细节。我的建议是首次扫描后做三件事。第一件看被依赖数最高的模块。这些模块是系统的地基任何修改都可能引发连锁反应。Archify 生成的 JSON 里可以直接按fan_in字段排序我一般会过滤出 fan_in 大于 20 的模块这些是需要重点测试覆盖的安全区。第二件看注释率最低的大模块。注释率低 代码量大往往意味着模块内部的可读性已经下降到危险线以下。我合作过的一个团队就是靠这个指标识别出一个 8000 多行、注释率不到 3% 的遗留类后来花了一个迭代周期才拆完。第三件看循环依赖。Archify 会检测模块之间的循环引用并且在 JSON 输出里用circular字段标出参与循环的模块列表。循环依赖是设计腐败的典型信号它会让系统难测试、难扩展但也往往隐藏在一些看似不相关的模块组合里人工很难肉眼发现。工具能直接给出结果省下大量排查时间。3.4 参数选择背后的逻辑有人会问为什么模块聚合的默认深度要设成自动判断而不是固定值原因在于不同语言的包组织方式差异很大。Java 的包路径一般反映业务域Python 的 package 更扁平TypeScript 的模块边界通常按 src 下的目录走。写死一个深度在某种语言上合理在另一种语言上就水土不服。Archify 的处理方式是语言解析器在分析时给每个文件打上模块归属标签这个标签由该语言的包管理规范推导而不是简单地砍目录层数。--ignore参数不仅是为了图好看它还有一个性能上的意义排除大目录后文件扫描和依赖分析的数据量会大幅下降扫描速度快了一大截。在大仓库上这个差异可以从几分钟缩小到几十秒。再看输出格式方面我几乎总是同时输出 JSON 和 SVG。JSON 数据可以随时用脚本重新渲染成别的视图SVG 给人眼看。如果你是一个人本地用只输出 SVG 就够了如果是要放到 CI 里自动生成文档PlantUML 的 Markdown 兼容性更好。不同场景用不同格式这不叫麻烦这叫对症下药。4. 常见问题与排查技巧实录4.1 大仓库扫描慢或者内存爆掉这是最常遇到的一个问题。有些大型微服务仓库几个服务代码放在同一个目录下总代码量能到百万行级别。Archify 在默认配置下可能吃满全部内存、扫描时间长到让人怀疑卡死了。解决方法是分段处理。先用--depth提高聚合粒度它会同时降低分析器的状态规模。再按子目录分别扫描比如你的 repo 下有 service-a、service-b、service-c 三个独立服务分别对每个子目录执行扫描各自输出一份架构图。最后如果需要全貌可以用一个合并参数把所有结果汇总archify merge out/service-a.json out/service-b.json --output merged.json注意合并的前提是这些子目录相互之间没有代码依赖。如果它们共享一个公共库目录最好把公共目录也作为一次扫描纳入合并范围不然结果里会看到一批引用无法解析的悬空节点。如果内存还是吃紧另一个办法是把扫描线程数限制下来。多线程能加速但在超大仓库上过高的并发反而会导致内存峰值失控。我实验下来的规律是仓库规模在 10 万文件以内时四线程收益最明显超过这个量级单线程更稳定速度慢一点但不会爆内存。4.2 依赖关系解析与实际不符这个现象也很常见。你打开架构图发现某个服务明明调用了另一个服务但图上没有对应的边。大概率的原因是跨服务调用不是通过直接的 import 完成而是通过 HTTP 客户端、消息队列或者服务注册中心间接完成的。这是静态分析天然的边界。Archify 目前能解析的是代码层面的直接依赖也就是说你在文件 A 里 import 了文件 B图上会有一个依赖边。但如果你用RestTemplate去调一个 URLURL 对应的服务只有运行时才知道静态分析是无能为力的。这类隐藏依赖我会在架构图上给一个提示框列出仓库中发现的外部服务名、URL 路径、消息主题名作为人工分析时的线索。很多微服务架构图的真实绘制过程是先用 Archify 生成代码依赖底图再人工叠加一层运行时服务调用关系两层合并得到完整的架构认知。4.3 仓库托管平台集成与权限问题在一些企业场景下仓库托管平台如 GitLab、Gitee的权限策略比较严格CI 里的机器人账号权限有限。Archify 扫描本地克隆仓库时通过受支持的 Git 传输协议拉取代码权限校验由托管平台完成所以一般不会碰到权限问题。如果在 CI 中运行 Archify需要保证机器人账号对目标仓库有读取权限这一点建议提前和平台管理员确认好否则流水线跑到一半才发现拉不了代码会比较尴尬。另外有一个容易被忽视的坑在 CI 中如果直接扫描整个工作目录会把构建产物、依赖目录等全部扫进去又会出现我之前说过的那一幕——架构图被几千个无关节点占据。在 CI 脚本里一定要显式配置--ignore参数把dist、build、node_modules、target、.git这些目录排除干净。更好的做法是把扫描放进一个只包含源文件的缓存目录CI 里先pip install archify-cli再执行扫描稳定可靠。4.4 图表可读性优化架构图生成之后很多人会嫌它丑。客观地说自动布局的图确实没有人工排版那么精致但它有一个不可替代的优势——准确。为了提高可读性Archify 内置了几个可选开关。--group-by-module启用后不相关的孤立节点会被收拢到模块分组里折叠状态下只显示模块名和文件数量展开才显示具体文件。这在大仓库上很有用能让图的宏观结构更突出。--highlight-circular会把循环依赖的模块高亮标红。红色视觉冲击力强开会时一眼就能让大家意识到问题的存在。这也是我每次生成架构图后第一个看的地方。--no-isolated可以直接隐藏没有依赖任何其他模块的叶子文件。这些文件往往是单独的小工具除非你专门想分析它们否则隐藏掉可以让主体结构更清晰。还有一个建议架构图不要贪大求全。一张图放一两千个节点谁也看不过来。正确做法是先生成全局图再根据关键模块生成局部放大图。Archify 的命令行参数支持指定模块名做二次扫描或者直接对 JSON 结果做过滤渲染。局部图的生成逻辑是保留所有连接到该模块的依赖边形成该模块的上下文子图排查具体问题时非常好用。5. 一些实用扩展与心得5.1 定时任务与 CI 集成架构图如果只在某个时刻生成一次价值就大打折扣了——代码每天都在变架构图必须跟着更新。我在团队里的做法是把 Archify 集成到 GitLab CI 流水线里每次 main 分支有新的合并请求通过后自动重新生成架构图并发布到团队内部文档网站的固定地址。流水线配置的大致思路是这样的archify-doc: stage: deploy script: - pip install archify-cli - archify scan --repo . --lang java --ignore target --svg public/arch.svg --json public/arch.json --plantuml public/arch.puml artifacts: paths: - public/这样团队里的任何人打开文档站看到的架构图永远是最新代码对应的状态不用等某个热心人手动更新。这也让架构评审从开会时大家各凭记忆争论变成了对着图指认问题效率提升很明显。但要注意一点CI 流水线每次跑整个仓库重新扫描一遍如果是大仓库会拖慢流水线。我用的缓存方案是给 Archify 指定一个缓存目录用来存放各文件的哈希和依赖分析结果。只有文件内容变更时才会重新解析没变更的文件直接命中缓存速度提升非常明显。5.2 新旧代码对比另一个我觉得很实用的扩展用法是架构差异对比。同一个仓库两个分支各自生成 JSON 结果然后跑一条对比命令archify diff arch-master.json arch-feature.json它会在终端里输出新增模块、删除模块、依赖关系变化等差异项。这个功能在做重构验收时特别有用——比如你要把某个巨型模块拆成三个小模块重构前生成一张基线图重构后再生成一张新图对比一下依赖数是否如预期降下来了。没有工具辅助的时候我只能人肉比较两个版本之间的模块差异容易漏看不该动的依赖变化现在一条命令就把变化清单拉到眼前。5.3 个人使用体会与建议做这个工具和用它跑了不少仓库之后我的一个体会是架构图的意义不只是给别人看更是给自己看。你写代码的时候身处其中很容易觉得当前的模块划分很合理但把图拉出来往那儿一放很多平时没意识到的问题就藏不住了。我曾在自己的项目上跑过一次发现一个 data 目录竟然同时被三个业务模块依赖这在这个项目的原始设计里是完全没有预料到的。后来重新梳理了依赖方向才把边界清理清楚。如果你是一个独立开发者我建议至少在你每个中等规模以上的项目上跑一次 Archify把生成的架构图放进项目文档里。这不仅是对未来的自己负责也是对将来接手这个项目的同事负责——哪怕只是给了他们一张图也能省掉他们几天的摸索时间。这个工具的后续方向我还在想怎么加入更多自动化的演进分析比如持续追踪两个版本之间依赖腐化的趋势而不只是做静态快照。从代码仓库到架构图说到底只是一个起点。真正的目标是让读懂系统结构这件事变得像看图一样自然让我们能把宝贵的精力花在业务逻辑和代码质量上而不是在无尽的文件跳转里迷失方向。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

从零开始构建Agent(三):用langgraph手搓一个简略版“Manus”,实现文档分析等小功能 2026/9/28 18:25:25

从零开始构建Agent(三):用langgraph手搓一个简略版“Manus”,实现文档分析等小功能

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
单目视频三维实时重构驱动的无人平台协同智慧水利全域数字孪生与防汛抗台智能决策 2026/9/28 18:25:25

单目视频三维实时重构驱动的无人平台协同智慧水利全域数字孪生与防汛抗台智能决策

摘要流域水利场景具有覆盖范围广、地形地貌复杂、水文工况动态多变、台风暴雨突发性强、险情蔓延速度快等典型特征,防汛抗台工作存在全域态势感知难、地形水体建模滞后、隐患盲区多、洪水演进预判不准、调度决策经验化等行业痛点。传统智慧水利监测体系依托固定站点…

阅读更多 →
TaoToken 配 Cline:Llama 4 MoE 单卡 H100 跑通与 settings.json 骨架 2026/9/28 18:25:25

TaoToken 配 Cline:Llama 4 MoE 单卡 H100 跑通与 settings.json 骨架

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
AI 编程工具—Cursor 基础篇:账户问题排查与 TaoToken 统一 Key 配置 2026/9/28 18:25:25

AI 编程工具—Cursor 基础篇:账户问题排查与 TaoToken 统一 Key 配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
Linux 系统安装/卸载 Anaconda3:TaoToken 统一 Key 接入 settings.json 配置骨架 2026/9/28 18:25:25

Linux 系统安装/卸载 Anaconda3:TaoToken 统一 Key 接入 settings.json 配置骨架

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
拒绝切换IDE,10分钟让Trae编辑器接入TaoToken:C++智能补全、编译调试一网打尽 2026/9/28 18:25:19

拒绝切换IDE,10分钟让Trae编辑器接入TaoToken:C++智能补全、编译调试一网打尽

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉