1. 引言
接手一个陌生的代码仓库,往往是一场噩梦:模块关系不清、调用链混乱、注释过时,只能硬着头皮从入口函数一步步追踪。tt-a1i/archify正是为解决这个痛点而生——它不要求你先读懂源码,而是先为你生成一张可交互的架构图,让你在点击、缩放、拖拽中直观理解项目骨架,再带着全局视角去精读关键代码。
该项目已获得4.4k+ Star,核心思路是:解析源代码生成 JSON 中间表示(IR),再渲染为自包含的 HTML 动效图,支持架构图、时序图、数据流图等多种视图。
2. 核心场景:接手陌生仓库,先出图再看码
当你面对一个完全陌生的仓库时,传统 workflow 通常是:
- 克隆代码 → 找到入口文件 → 逐文件阅读,手工画出模块关系 → 反复跳转梳理调用链。
- 这个过程耗时且容易遗漏关键依赖,尤其在微服务、多层架构项目中。
archify 提供的替代方案:
- 一键分析仓库,生成可交互的架构图(SVG/Canvas 渲染,支持缩放、平移、节点点击跳转源码)。
- 同时输出时序图(展示函数调用顺序)和数据流图(展示数据如何在模块间流转)。
- 所有交互图都是自包含 HTML 文件,无需额外服务,可直接在浏览器中打开,分享给团队成员。
这样,你可以在 5 分钟内建立对项目骨架的宏观认知,再带着问题去阅读具体代码,效率提升数倍。
3. 原理解析:从代码到 JSON IR 到动效图
archify 的工作流程分为三个阶段:
3.1 代码解析与 IR 抽取
工具内置多种语言的解析器(目前支持 Python、JavaScript/TypeScript、Java、Go 等),它会遍历仓库文件,提取以下信息:
- 模块/包/类/函数定义及其依赖关系。
- 函数调用链(Call Graph)。
- 数据流关系(变量传递、返回值流向)。
- 文件组织结构。
这些信息被抽象为统一的JSON IR(中间表示),例如:
{"nodes":[{"id":"main","type":"function","file":"src/main.py"},{"id":"utils.load","type":"function","file":"src/utils.py"}],"edges":[{"from":"main","to":"utils.load","type":"call"}]}3.2 布局算法与视图生成
基于 IR,archify 根据不同视图需求应用布局算法:
- 架构图:使用分层布局或力导向布局,将模块按层级排列,展现整体架构。
- 时序图:将调用链按时间线垂直排列,展示函数调用顺序和嵌套关系。
- 数据流图:以数据实体为节点,展示数据的产生、变换和消费过程。
每种视图都通过独立的渲染引擎生成,保证美观且符合直觉。
3.3 自包含 HTML 动效图
渲染结果不是一张静态图片,而是一个交互式 HTML 页面,其中包含:
- 所有图形数据(节点、边)以 JSON 内嵌在 HTML 中。
- 使用 D3.js、Cytoscape.js 或自行实现的轻量渲染库驱动交互。
- 支持节点点击跳转到对应源码位置(如果开启了本地文件映射)。
- 支持搜索、过滤、高亮链路等操作。
这个 HTML 文件可离线使用,甚至可以直接提交到项目文档中,作为项目的“活文档”。
4. 技术实现与使用方式
4.1 安装
archify 使用 Python 编写,安装简单:
pipinstallarchify对非 Python 仓库,它仍可分析,但需要对应语言的解析器插件(部分已内置)。
4.2 基础用法
进入仓库根目录,执行:
archify analyze.--outputarchitecture.html这会在当前目录生成architecture.html,直接用浏览器打开即可。
常用参数:
--view:指定视图类型(architecture、sequence、dataflow),默认architecture。--include/--exclude:过滤文件或模块。--depth:分析深度,避免过深调用链。--port:启动本地服务器,实时更新图(开发模式)。
4.4 多语言支持原理 Flask 项目
下面以一个简单的 Flask 项目为例,完整走一遍“执行命令 → 查看输出 → 生成文件 → 浏览器交互”的流程。假设项目目录如下:
flask-blog/ app.py auth.py models.py templates/ base.html进入项目根目录,执行分析命令:
为了便于理解 archify 能提取出哪些关系,下面给出app.py、auth.py、models.py的简化实现:
# app.pyfromflaskimportFlask,request,jsonifyfromauthimportlogin_userfrommodelsimportget_user app=Flask(__name__)@app.route("/login",methods=["POST"])deflogin():username=request.json.get("username")password=request.json.get("password")iflogin_user(username,password):user=get_user(username)returnjsonify({"status":"ok","user":user})returnjsonify({"status":"fail"}),401if__name__=="__main__":app.run(debug=True)# auth.pyfrommodelsimportget_userdeflogin_user(username,password):user=get_user(username)ifuserisNone:returnFalsereturnuser.check_password(password)defcurrent_user(username):returnget_user(username)# models.pyclassUser:def__init__(self,username,password):self.username=username self.password=passworddefcheck_password(self,password):returnself.password==passworddefget_user(username):# 模拟数据库查询ifusername=="admin":returnUser("admin","secret")returnNone执行分析后,archify 会将函数、方法和调用关系抽象为JSON IR。针对上面的 Flask 项目,生成的节点与边数据大致如下:
{"nodes":[{"id":"app.login","type":"function","file":"app.py"},{"id":"auth.login_user","type":"function","file":"auth.py"},{"id":"auth.current_user","type":"function","file":"auth.py"},{"id":"models.User","type":"class","file":"models.py"},{"id":"models.User.check_password","type":"method","file":"models.py"},{"id":"models.get_user","type":"function","file":"models.py"}],"edges":[{"from":"app.login","to":"auth.login_user","type":"call"},{"from":"app.login","to":"models.get_user","type":"call"},{"from":"auth.login_user","to":"models.get_user","type":"call"},{"from":"auth.login_user","to":"models.User.check_password","type":"call"}]}也就是说,在最终渲染出来的架构图中,app会作为入口节点,分别指向auth和models;而auth.login_user又会进一步依赖models.get_user和models.User.check_password,正好和代码中的调用关系一一对应。
cdflask-blog archify analyze.--outputarchitecture.html命令执行后,终端会输出分析进度,大致如下:
archify v0.4.0 [1/4] Scanning project files ... [2/4] Parsing Python sources (5 files) ... [3/4] Building IR and call graph ... nodes: 16, edges: 22 [4/4] Rendering interactive architecture.html ... Done! Open architecture.html in your browser.分析完成后,项目目录中会新增一个自包含的architecture.html:
flask-blog/ app.py auth.py models.py templates/ base.html architecture.html这个 HTML 文件没有任何外部依赖,内部主要由以下几部分组成:
- 主体画布:用 SVG 渲染模块节点和调用关系连线。
- 内嵌数据:
<script type="application/json">保存完整的 IR 节点与边数据。 - 工具栏:提供搜索、过滤、布局切换等按钮。
- 交互脚本:处理缩放、拖拽、点击高亮、详情面板等行为。
用浏览器打开architecture.html后,可以对架构图进行以下交互操作:
- 拖拽空白区域:平移画布,查看被遮挡的节点。
- 滚动滚轮:放大缩小架构图,快速总览或聚焦细节。
- 单击节点:高亮该节点的上下游调用链,并在侧边栏展示所属文件与函数签名。
- 双击节点:跳转到对应源码位置(需在命令中开启本地文件映射)。
- 搜索函数名:在搜索框输入后快速定位节点,并自动聚焦到对应区域。
- 切换布局模式:在分层布局和力导向布局之间切换,从不同角度观察模块关系。
这样,即使第一次接触这个 Flask 项目,也能先通过交互图把app.py、auth.py、models.py之间的调用关系摸清楚,再回到代码中精读具体实现。
4.3 多语言支持原理
archify 通过插件化解析器支持多语言,每个语言解析器实现一个标准接口,将 AST 或静态分析结果转为统一 IR。贡献者可以轻松添加新语言支持。
4.5 与 CI/CD 集成
可以将 archify 集成到 CI 流程中,每次提交时自动生成架构图并归档到文档站,让团队始终了解项目最新结构。
5. 实际效果演示
以下是一个简化示例,假设分析一个简单的 Flask 应用。
项目结构:
app/ main.py auth.py models.py生成的架构图(交互式)会展示:
- 三个模块节点,
main依赖auth和models。 - 点击
auth节点,高亮相关调用链,并显示它调用了models.User。 - 缩放可查看整体,双击节点可跳转到源码(若配置了编辑器链接)。
时序图会展示一个请求的生命周期:
Client -> main.index() -> auth.login() -> models.User.query()数据流图则会显示User对象如何在auth和main之间传递。
这些图全部封装在一个 HTML 文件中,可以直接发给同事,无需安装任何工具。
6. 总结与展望
tt-a1i/archify 把“先读代码再画图”的流程颠倒为“先看图再读代码”,极大降低了接手陌生项目的认知负荷。其自包含 HTML 动效图的设计,让架构图不再只是文档里的一张截图,而是可以持续交互的活文档。
未来,该项目有望支持更多语言、更智能的布局算法,甚至与 AI 代码解释结合,在图中直接展示代码摘要,进一步降低理解门槛。如果你正面临一个巨大而陌生的仓库,不妨试试 archify,让架构图先开口说话。