我最近几个月一直在处理一个历史包袱非常重的老项目,代码量接近百万行,模块之间的调用关系乱成一团麻。每次有新人入职,光是把项目结构和核心链路讲清楚,就得花掉两三天时间。我自己排查线上问题的时候也经常遇到这种情况:明明根据报错日志能定位到一个函数,但根本不知道是谁在调用它、它又依赖了哪些底层服务,只能靠全局搜索加肉眼追踪,效率低得让人抓狂。
后来我在做技术选型调研的时候发现了 codegraph 这个工具,试用了一段时间之后,最大的感受就是:它把一个仓库里那些肉眼看不见的关系,变成了一张可以探索、可以查询、可以自动维护的地图。这篇文章我会从使用者的角度,把 codegraph 是什么、核心原理、graphify 命令怎么用、以及在我实际项目里的几个典型场景完整梳理一遍,希望能给同样被代码库复杂度折磨的人一些参考。
1. 我为什么会在代码库里迷失方向
先说背景。我手头这个项目是由多个团队共同维护的服务端应用,分了十几个顶层模块,每个模块下面还有子模块和公共依赖层。看起来很规范,但真实情况是:模块之间边界早就模糊了,业务 Service 互相乱调,基础设施层也被业务代码渗透,整个调用关系呈现一种无序蔓延的状态。
拿一次典型的排查经历来说。线上告警显示某个 RPC 接口超时了,日志定位到了一个叫parseConfig的私有方法。我第一反应是去项目里搜索这个方法的定义和所有调用点。搜索结果拉了差不多四十多个引用,分布在二十个类里面。问题是:光知道这四十多个调用点,我还是没法判断哪一个调用链是导致超时的关键路径,因为我看不到方法之间的调用层级、依赖深度和真实的调用链走向。
我当时就意识到,传统的grep、全文搜索、甚至 IDE 的 Find Usages,解决的是“代码在哪里”的问题,但它们都解决不了“代码之间到底是什么关系”的问题。而后者恰恰是维护老项目、排查问题、评估改动影响面最需要的核心信息。
还有一种常见场景是代码走查。每次要做模块梳理或者架构评审,大家都习惯打开 IDE 的调用层级视图一路点下去,但 IDE 的层次图仅限于单个符号的展开,没有办法对整个项目生成一张全局的关系视图。一旦涉及到模块之间的相互引用、循环依赖、未使用的公共代码,靠人工整理基本是不可能完成的任务。
我在那段时间尝试过几种方案。用tree命令看目录结构只能解决“代码在哪个文件”的问题;用代码搜索工具能看到“谁引用了我”,但看不到完整的依赖层级;用传统静态分析工具做检查又觉得太重量级,配置复杂,产出的报告不容易转化为可视化图谱。
后来我在团队内部做了一个小的技术调研,列了几个候选方案,包括 Sourcegraph 的开源版本(现在改名了)、Understand、CodeQL,还有一个就是我今天要讲的 codegraph。前几个要么是重量级的服务端部署方案,要么是商业授权,要么学习曲线陡峭。codegraph 吸引我的点是最轻量:它没有要求我们部署服务端、不需要连数据库,直接在本地就能生成代码图谱,而且基于图谱的查询能力非常贴合中文开发者的使用习惯。当然,后来我意识到这是一个很有潜力开源项目,背后也有人在做持续迭代,但作为使用者,我更关心它能不能解决实际问题。
所以如果你想快速建立一个“我会用”的正反馈,codegraph 是很合适的。你不需要一开始就设计复杂的 CI 流程或者自动化规则,只要在本地运行一条命令,立刻就能看到一个仓库的知识图谱长什么样。
2. codegraph 的底层逻辑:代码图谱到底是怎么构建出来的
Codegraph 并不是一个简单的“目录树可视化工具”。它本质上是一个代码静态分析引擎外加图谱查询能力的集合。想要用好它,首先得理解它的数据源和分析链路。
2.1 从源码到图谱的数据链路
我在研究它的过程中发现,codegraph 的工作方式大致可以分为三个阶段。
第一个阶段是解析源码文件。它会根据文件后缀识别语言类型,比如 Python 的.py、JavaScript 的.js、TypeScript 的.ts、Java 的.java等等,然后把每个文件拆解成语法树。这个阶段最核心的部分是它不只是读取文件内容,而是利用语法级别的信息识别出代码中的声明节点和引用节点。比如一个类定义、一个函数声明、一个变量赋值,这些是声明节点;而调用一个函数、继承一个类、import 一个模块,这些是引用节点。
第二个阶段是建立符号表。符号表简单说就是“谁定义了什么”的索引。比如文件中定义了一个函数processOrder,codegraph 会记录它的名称、所属类、所在模块、入参类型、返回类型等信息。这个阶段有点类似于编译器在编译中期做的名字解析。符号表的质量直接决定了图谱的准确度,因为如果同一个函数名在不同模块里重复定义,而代码中有误用,它们会被错误连接。
第三个阶段是关系抽取。有了符号表和语法树之后,codegraph 会扫描每个引用节点,然后通过符号表找到它指向的定义节点,在两者之间建立一条边。边的类型可以表现为“调用关系”“继承关系”“导入关系”“组合关系”。举个例子,A 模块 import 了 B 模块,那么在图中就是A -> B的一条import边;OrderService 调用了 PaymentService.pay(),那就是OrderService -> PaymentService的一条call边。
生成完这些节点和边之后,最终的数据会落成一个图谱结构,可以通过可视化界面或者查询 API 来使用。这个图谱不是一张静态图片,而是一个可以查询的数据结构。我理解它的设计哲学是把代码库当作一个图数据库来对待,而不是当作一个文件树来对待。
2.2 图谱的核心单元:节点和边
搞清楚节点和边的概念,比配置工具本身更重要。我在用的时候习惯把整个仓库看作一张大网,文件是网面上的节点容器,而具体的类、函数、模块是更细粒度的节点。边则表示节点之间的各种关系。
举个例子,在 codegraph 的查询结果里,我可以输入一个函数名,让它展示这个函数被谁调用了、它又调用了谁。这个查询结果本质上就是从这个函数节点出发,沿着一层或者多层边遍历出来的子图。如果把全项目所有文件和函数都连起来,这张图的规模会非常大,所以实际使用中一定要学会过滤和聚焦,而不是一上来就要看全图。
那种“全图生成之后一坨线密密麻麻”的体验,新手最容易遇到。别慌,这是正常现象。图的价值并不在于“看着好看”,而在于你可以对它做局部定向遍历。学会用节点过滤、深度限制、路径搜索,比把整个图谱导入到可视化工具里更重要。
2.3 和普通索引工具的根本区别
这里拿 grep 和 IDE 的 Find Usages 做对比可能更容易理解。grep 是纯文本匹配,它看到的是一行字符串里有没有出现某个名字,根本没考虑上下文语义。Find Usages 比 grep 聪明一点,它能看到某个符号在哪些地方被引用的,但它通常是针对单个符号操作的,而且不同文件之间的调用层级关系需要你一层一层手动点开。
codegraph 做的事情是把所有文件和符号的关系一次性算出来,形成一个全局的静态调用图。它不是回答“这个符号出现在哪里”,而是回答“从模块 A 到模块 B 之间有哪些路径”“这个函数的全部调用链是什么”“这两个模块之间的耦合程度有多深”。数据的形态不一样,能玩出来的深度就完全不一样。
3. 把 codegraph 跑起来:安装与最小实践
工欲善其事,必先利其器。codegraph 的安装不算复杂,但因为涉及语言解析器和运行环境,有几个细节还是值得单独拿出来讲的。
3.1 安装过程和注意事项
我本机环境是 macOS + Windows WSL2 双开,Python 版本是 3.10。codegraph 安装我采用了官方推荐的 cli 方式,核心依赖是 Python 环境和一套语言解析器。如果你所在团队用 Docker,也可以把工具封装在镜像里,避免每台机器都装环境。
安装前建议先确认两件事。第一,Python 版本是否满足要求,老旧的 3.7 环境大概率会报错。第二,确认你的代码库里是否有需要额外安装的语言解析依赖。codegraph 支持的语言解析不是内置一套全包,而是按语言类型动态加载不同解析器。
一条典型安装命令大概是这样的:
pip install codegraph装完之后验证一下版本信息,确保可执行文件已经在 PATH 中:
codegraph --version如果在公司内网环境遇到 pip 下载慢或者被安全策略拦截的问题,可以考虑配置内部 PyPI 镜像源,这里就不展开讲了。总之,安装这一步,顺利的话五分钟之内就能完成,不快也不慢。
3.2 生成第一个最小图谱
进入到一个小型项目目录(最好是那种结构不复杂、单语言的项目),运行:
codegraph graphify .这条命令的含义是“把当前目录下的项目解析并生成代码图谱”。第一次运行的时候,它会输出一些“正在扫描文件”“正在构建符号”之类的日志。完成后目录下会新增一些图谱相关文件,可能是节点列表、边列表或者一个综合的图谱数据文件。
我第一次用的时候犯了一个很典型的错误——直接对一个几十万行的老项目跑 graphify,结果跑了很久都没结束,进程一直在做解析。后来发现它默认会扫描项目目录下的所有文件,包括node_modules和dist目录,直接把解析时间拉满了。所以新手拿到工具后的第一个正确姿势,是找一个干净的小项目先把流程跑通,然后再学习如何配置忽略规则。
生成了图谱文件之后,还会有一个可视化查看的环节。即便不打开可视化界面,也可以通过查询命令读取图谱内容,这一步我下面会用一个实际场景详细说。
3.3 观察生成的图谱结构
用文本方式打开图谱数据文件,你会发现它大体上是一个节点表加一个边表的结构。节点表里记录每个代码实体的基本属性:ID、类型、名称、文件路径、起止行号。边表里记录关系的两个端点、关系类型和可能的关系元数据。
我自己的感受是,第一次看这些数据的时候会觉得有点抽象,但当你能把一个函数名从节点表里找出来,再去边表里查它周围的关联边,你就能直观感受到这个工具的数据模型了。后面的操作,无论是可视化还是做自动化分析,本质上都是在处理这张节点加边的表。
4. graphify 命令的精髓:从单模块到全仓库
codegraph graphify是整个工具最核心的入口,掌握好它的参数和场景,基本就掌握了项目分析的上层操作。我会把几个我实际验证过的用法拆开来讲。
4.1 目录选择与忽略规则
graphify 支持指定扫描目录,这个参数可以传一个.表示当前目录,也可以传一个相对路径。但光传路径还不够,大型项目里总有不需要进入图谱的目录,比如:
- 第三方依赖:
node_modules、vendor、.venv、site-packages - 构建产物:
dist、build、target、out - 测试辅助代码:如果暂时只关心主链路,可以把测试目录忽略掉
- 静态资源:一些包含大文件或者模板的目录
配置忽略规则之后,解析速度和图谱的清晰度都会有明显提升。我第一次对一个中型项目跑的时候,忽略前要处理差不多五千多份文件,忽略之后只剩两千多份核心源码,时间缩短了接近一半,图谱里的噪声也少了很多。
建议第一次跑图谱之前,先花五分钟把项目的目录结构过一遍,把那些不需要分析的大目录列进忽略配置。这一步节省的时间,后面一定会加倍还给你。
4.2 全量构建 vs 增量构建
大项目还有一个绕不开的问题:我没法每次都全量构建。codegraph 在这个问题上提供了增量构建支持,主要思路是记录上次构建的指纹信息,如果一个文件的修改时间和哈希没有变化,就从缓存里复用它的解析结果,不再重新分析。
我个人的使用节奏是:第一次在分支上做全量构建,后面每次代码改动之后,用增量构建快速更新图谱。这个操作对于日常开发来说非常方便,尤其是当我正在评估一个改动的影响范围时,每隔几分钟就要刷新一次图谱。
增量构建也不是万无一失的。如果我在分析过程中改动了关系比较复杂的公共模块,它下游的调用链可能因为依赖关系的变更而需要重新连接,这时候缓存失效的判断逻辑就显得格外重要。我在实践中的建议是:小步改动用增量,涉及模块级重构时果断全量重跑。
4.3 多语言项目的处理
如果你的项目是纯 Python 或者纯 JavaScript,配置起来会比较省心。但如果你像我一样维护一个“前端 TypeScript + 后端 Python”的项目,需要注意 codegraph 对不同语言的分析逻辑是各自独立的,跨语言的调用关系(比如 Python 后端通过 HTTP 调用前端 BFF 接口)不会自动建边,需要你用自定义关系或者手动标注的方式弥补。
我当初也想让分析工具自动画出前端到后端的完整调用链,后来发现现实一点的做法是:把代码图谱聚焦在单侧语言内部的依赖关系上,跨语言的链路靠文档或注解补充。这一点在选型之前就要有心理准备,不能指望一个万能工具把所有边界都打通。
4.4 输出格式与可视化落地
graphify 完成后生成的数据文件,目前支持多种输出形式。我们可以选择纯 JSON 格式方便二次加工,也可以生成能够被前端可视化的格式。如果你想在浏览器里浏览图谱,codegraph 本身会启动一个本地服务暴露图谱数据。
我在团队内部用得比较多的做法是,把图谱数据导出成 JSON,然后在我们自研的一个内部代码分析页面套接数据。如果你也想做二次开发,最好先把 JSON 的结构理清楚,再考虑前端展示。避免把可视化界面做得很炫但数据维度没有打通,最后变成花瓶。
5. 用图谱导航日常开发:三个在我项目中真实跑通的场景
光讲工具本身容易变成本地文档翻译。这一节我分享三个我在实际工作中用 codegraph 解决问题的具体场景,你可以对照自己的情况举一反三。
5.1 场景一:快速定位线上问题的调用链路
回到开头我提到的那个parseConfig定位难题。以往的做法是全文搜索之后手动梳理调用链,非常费劲。用了 codegraph 之后,我先在图谱节点表里找到parseConfig函数,然后从这个节点出发做一个调用反查。
具体操作相当于沿着“谁调用了这个函数”的方向扩展一层、两层、三层,最终我拿到了完整的反向调用链:parseConfig被loadConfig调用,loadConfig被ConfigManager.refresh调用,ConfigManager.refresh被HttpServer.startup调用。看到这一条链的时候,问题基本就清晰了:线上超时发生在服务启动阶段,和运行时请求无关,这跟最开始猜想的“某个请求路径导致的瓶颈”完全不同。
这个体验给我最大的启发是:工具的价值不光是“省去搜索时间”,而是它能帮你把黑盒变成白盒,让你用结构化的数据去推理业务链路。
5.2 场景二:评估一次代码重构的影响面
老项目里最怕的改动就是:我改了一个公共函数,不知道会不会影响一堆调用方。以前的做法是改完代码之后全局跑测试,看测试挂了哪些,但测试覆盖不到的地方还是存在隐患。
codegraph 的调用反查在这里体现出了独特价值。我在重构前,先查询这个公共函数的所有被调节点,再把被调节点按照所属模块聚合,就能看出一份“受影响模块清单”。比如我准备改动validateUser这个方法,图谱显示它被三个业务模块、两个工具库、一个定时任务模块引用,那么这个改动大概率不是一个小改动,需要协调的测试范围也清晰了。
然后我再查询每个引用点到根节点之间的调用层数,看哪些调用是长链路末端的间接引用,哪些是直接耦合。间接引用的模块在代码改动后可能需要更多回归测试,直接引用的模块则应该优先考虑接口兼容性。
重构完成之后,重新生成图谱,对比两次图谱的差异,还能顺带验证“旧的调用链是否被正确移除”“新增的模块是否按预期建立了引用”。这种基于图谱的对比,比人眼检查代码 diff 要可靠得多。
5.3 场景三:给新人做模块导航
团队来新人,让他光看代码,效率太低;给他讲架构图,可架构图往往早在两个版本前就过期了。后来我把 codegraph 生成的图谱作为一个辅助教学工具。
我会指定一个核心业务模块作为起点,把从该模块出发的一级依赖和二级依赖列出,配合会议室的投屏一起走一遍。新人很快就能理解:这个模块调用了基础设施的哪些能力、依赖了哪些外部 RPC、哪些代码是自包含的、哪些代码是公共的。
相比旧式的“从一个类开始点 IDE 调用层级”,我的体感是新人接受得更快,因为他看到的是一张“地图”,而不是一堆逐层展开的树节点。地图的形态天然适合讲“整体架构”和“模块边界”,而树节点天然适合讲“细节实现”。两者互补,前者用来搭认知框架,后者用来填细节。
6. 图谱准确性:哪些关系它能画出,哪些画不出来
用静态分析工具最怕一个坑:它给的依赖关系明明不对,我基于错误关系做了重要决策,后果就比较严重。所以我建议把 codegraph 的能力边界搞清楚。
6.1 静态分析能覆盖的类型
- 显式导入/导出:这种最常见,模块 A
import模块 B 的某个函数,图谱必然能正确建边。 - 函数调用:同一个模块内部或者跨模块调用某个已定义的函数,只要符号解析准确,都能反映。
- 类继承/实现接口:基于语法树的分析很容易识别出
extends和implements关系。 - 装饰器和注解引用:这在 Python/Java 项目里很常见,codegraph 也能识别。
大多数基于 AST(抽象语法树)的代码分析工具,在这些场景下准确率都很高,因为它们是纯语法层面的关系,不涉及运行时推导。
6.2 动态派发和运行时绑定是重灾区
“鸭子类型”“反射调用”“消息转发”这类动态特性,会让静态分析工具比较头疼。比如 Python 里:
def dispatch(action): handler = get_handler(action) # 运行时动态获取 handler.process() # 这里的 handler 是哪一类?静态分析难以判断遇到这种代码,codegraph 通常只能标记“调用了某个名为 process 的方法”,但无法建立到具体实现类的边。这种情况下生成的图谱会出现“断裂”或者“触点多”的现象,你需要自己根据场景判断是不是需要手动补充。
另外像 Java 的反射机制Class.forName(...)+newInstance(),Spring 里的动态代理 Bean,JavaScript 里Function.prototype.call等场景,都有类似问题。解决思路很朴素:图谱是辅助工具,它反映的是静态结构和显式关系,动态行为要配合运行时监控(APM、链路追踪)来补充。
6.3 条件编译和宏展开
C/C++ 项目里,宏和条件编译会让代码分析变得复杂。codegraph 在处理这类语言的时候,能识别基本语法结构,但宏展开带来的隐藏依赖很难被完全还原。如果你所在的项目大量使用宏或者模板元编程,建议对小范围代码做抽查,验证图谱的实际准确程度再做决策依据。
我自己实践的验证方法很简单:随机选一个核心函数,人工读它的实现和调用点,看图谱给出的调用链是否与实际一致。验证三五个节点如果都是对的,那就可以继续信任;如果发现有的边明显错了,就要排查是否是解析器版本问题或者特殊语法支持问题。
6.4 版本不一致带来的误差
还有一种情况不是工具能力问题,而是使用习惯问题。如果图谱不是基于最新代码生成的,那么你查询到的依赖关系会停留在上一次构建的状态。团队在并行开发多条分支时尤其容易出现这种误差。我的习惯是,在做影响面评估之前,先确认图谱的构建时间和当前分支 HEAD 是否一致。如果不一致,就重新跑一次增量构建,几秒钟的事情,但能避免方向性的误判。
7. 从命令行到协作流程:codegraph 落地的两条路线
个人使用和团队落地,对工具的要求完全不一样。我分两条路线说一下。
7.1 个人本地工作流
个人使用场景大多数是“临时建图、用完即走”。我的本地命令序列大概是:
codegraph graphify ./my-service --language python codegraph query "BaseConfig" --depth 2第一条命令生成当前服务子目录的图谱,第二条命令查询BaseConfig这个符号两层以内的关联。这种方式足够轻,适合日常开发中快速验证想法。因为查询只依赖本地文件,速度很快,整个过程没有任何服务端依赖,这对我这种喜欢在多个终端窗口来回切的人来说非常友好。
如果你不想记太多命令,也可以把常用查询封装成一个小脚本,放入本地 PATH。脚本做的事情很简单:在指定目录跑增量构建,然后接受一个符号名进行查询,最后把结果输出成一个文本摘要。我团队里的初级工程师基本一次就能上手。
7.2 团队协作落地探索
想把 codegraph 变成团队共享的能力,有几个方向可以尝试。
第一,把图谱生成过程接入 CI。如果团队用 GitLab CI 或 Jenkins,可以在代码合并请求阶段触发一次增量构建,然后把图谱差异作为变更说明的一部分。这个模式尤其适合大型重构分支:评审者不仅看到代码 diff,还能看到模块依赖关系的变化,对评审效率和准确性都有帮助。
第二,把图谱数据作为共享产物。可以把生成好的 JSON 传到内部制品库或者对象存储,这样后端开发者不用本地安装任何工具,也能通过一个网页查询到当前主干的依赖关系。
第三,将图谱和代码评审工具插件集成。不过这部分取决于团队的评审工具生态,codegraph 最近也在提供相关能力,如果你所在的评审平台支持自定义插件,可以考虑做一层代理来对接图谱数据接口。
7.3 增量构建在 CI 里的注意点
在 CI 环境中做增量构建比较容易踩坑的点是:CI 每次拉取的代码可能跨越多个提交,而本地增量构建的缓存基于本地文件哈希,如果 CI 环境没有做好缓存持久化,每次构建都会退化成全量构建,时间成本不减反增。
正确做法是把图谱缓存目录作为 CI 的缓存或制品保存下来,让下一次构建可以直接复用上一次的解析结果。另一个注意点是 CI 构建时的代码目录可能和本地不一样,注意保持相对路径的一致性,否则节点表里的文件路径会全部错位。
8. 我在使用过程中踩过的坑和总结出来的经验
工具再好,实际用起来还是会有各种意外。这一节算是我个人在使用过程中沉淀下来的避坑记录,不一定适用于所有项目,但大概率能帮你少走弯路。
8.1 坑一:忽略规则配置晚了
第一次直接全量分析一个大项目,跑了十分钟还没结束,最后强行终止。后来才意识到是依赖目录没忽略掉。所以我的建议是:任何项目第一次建图谱之前,先花五分钟配置忽略规则,不要嫌麻烦。忽略规则可以用相对路径或者 glob 模式指定,支持排除整个目录。
配置完成之后,我特意验证了一次图谱的节点数,与预期大体一致,说明忽略规则没有误伤源码。这一步看似琐碎,但后来每次图谱运行速度都很快,都是当时配置的功劳。
8.2 坑二:多模块共享目录导致路径混乱
一个仓库里如果通过软链接或者多模块嵌套引入了共享代码,codegraph 在解析时可能会把同一个文件识别成多个不同的路径,进而导致图谱中出现重复节点。这种问题排查起来比较隐形,因为从查询结果里看不出明显的报错。
我的建议是避免用软链接方式共享代码,如果历史原因已经存在,那么在生成图谱之后,可以手动检查共享目录下的文件节点是不是有重复路径前缀。如果有,可以考虑在构建配置里指定统一的根目录,让所有文件都以仓库根为基准来存储路径。
8.3 坑三:只看一级依赖,忽略链条整体
很多人在查看图谱的时候,习惯只看某个节点的直接依赖列表。这确实很快,但信息密度偏低。比如模块 A 直接依赖模块 B,而模块 B 又依赖了被废弃的模块 C,这种二次、三次依赖如果不去挖掘,很容易让团队在不知不觉中维护一个技术债深坑。
我自己定的经验法则是:做模块级梳理至少看两层依赖,做架构评审至少看三层。多花几十秒,能看清一条链,而不是只看一个点。
8.4 坑四:以为图谱等同于架构文档
最后一条是提醒,不是批评。代码图谱表达的是代码实际存在的关系,而不是架构设计上“应该存在”的关系。它会诚实告诉你“当前代码就是这么乱的”,但不会替你判断“这里应该解耦”。
所以使用 codegraph 的正确姿势是:用图谱发现事实,用架构原则做决策,必要的时候把图谱导出成文件作为讨论素材。我见过有同事把图谱展示当成架构评审的最终结论,这是比较危险的。图谱是起点,不是终点。
9. 关于 codegraph 的未来和我最终的使用心得
从个人实际体验来看,codegraph 在“轻量、快速生成代码图谱”这个方向上做得很有特色。它没有给你一个沉重的平台,而是把最核心的能力放在本地命令行和查询 API 上,把二次开发的空间留给使用者。这一点非常符合我这种喜欢从底层数据开始构建工作流的人。
如果说接下来有哪些可以期待的方向,我比较关注以下几点:
- 更多语言解析器的完善深度,尤其是 C++ 模板元编程和 Kotlin 扩展函数这类复杂语法;
- 可视化交互层面的进步,比如在网页里直接拖拽节点做依赖剪枝;
- 更成熟的增量缓存失效策略,减少因为边界改动导致的无效重建;
- 和主流 CI/CD 平台的原生集成能力进一步增强。
不过对普通使用者来说,这些升级点都不影响你现在就开始尝试。哪怕项目只有几千行代码,codegraph 生成的图谱也能帮你重新认识一遍项目的结构。
最后说一个很个人的体会:在用过一段时间后,我开始觉得代码库不是一堆文件,而是一张不断演化的网。每次调整代码的时候,我会下意识地想一想“这次改动会拉动网上的哪些边”,而这种思维方式的转变,比单纯学会一个工具要值钱得多。如果你也长期在一个复杂度越来越高的仓库里挣扎,我建议你把 codegraph 当成本地工具箱里一个常驻的伙伴,而不是用完就删的一次性脚本。