05 代码结构分析:模块、依赖、架构识别

这是《Git 仓库蒸馏术:从代码仓库到 OpenClaw 虚拟人》系列的第 5 篇。第 04 篇从提交历史还原了项目的"时间轴",这一篇转向"空间轴"——从静态代码里识别出系统的架构。提交历史告诉你系统怎么长成的,代码结构告诉你系统现在长什么样、各部分怎么咬合。


一、为什么代码结构分析是蒸馏的"骨架"

演进报告是时间轴,架构文档是空间骨架。两者结合,才构成对系统的完整认知。

代码结构分析要回答三个问题:

问题 关注点 对应产出
模块怎么划分 目录/包的组织逻辑 模块清单
模块间怎么依赖 谁依赖谁、有没有环 依赖图
架构是什么模式 分层?微服务?插件化? 架构模式识别

这三个问题回答完,你就得到了一份"架构文档"——后续的文档蒸馏、模式提炼、知识图谱构建,都建立在这份架构文档之上。


二、模块划分与依赖关系

2.1 从目录结构识别模块

第 03 篇我们用 tree 看了目录,这一篇要更进一步——判断目录划分背后的逻辑

# 看 3 层目录结构
tree -L 3 -d -I "node_modules|.git|dist|build|__pycache__"

常见的模块划分逻辑:

划分逻辑 特征 示例
按层划分 按技术职责分层 api/components/utils/views/
按业务划分 按业务领域分模块 order/user/payment/
按功能划分 按功能点分模块 auth/dashboard/settings/
混合划分 层 + 业务混合 src/features/order/ 内含 api/components/

判断方法:看顶层目录的命名。如果顶层是 apicomponentsutils,是按层;如果顶层是 orderuserpayment,是按业务。

2.2 用 madge 分析模块依赖

madge 是分析 JS/TS 模块依赖的利器,能生成依赖图并检测循环依赖:

# 安装
npm install -g madge

# 分析依赖,输出依赖树
madge --extensions ts,tsx src/

# 检测循环依赖
madge --circular --extensions ts,tsx src/

# 生成依赖图(SVG)
madge --image deps.svg --extensions ts,tsx src/

输出示例(循环依赖检测):

✖ Found 3 circular dependencies!

1) src/core/model-service.ts > src/core/model-registry.ts > src/core/model-service.ts
2) src/api/client.ts > src/utils/request.ts > src/api/client.ts
3) src/views/dashboard/index.vue > src/components/chart-panel.vue > src/views/dashboard/index.vue

循环依赖是架构坏味道:它意味着模块边界不清晰,改一处可能引发连锁反应。循环依赖集中的区域,往往是技术债聚集地。

2.3 用 dependency-cruiser 做规则校验

dependency-cruisermadge 更强大,支持自定义依赖规则:

# 安装
npm install -g dependency-cruiser

# 生成配置文件
depcruise --init

# 校验依赖规则
depcruise src/ --config .dependency-cruiser.js

配置文件示例(.dependency-cruiser.js):

module.exports = {
  forbidden: [
    {
      name: 'no-circular',
      severity: 'error',
      from: {},
      to: { circular: true }
    },
    {
      name: 'no-utils-import-core',
      severity: 'warn',
      from: { path: '^src/utils' },
      to: { path: '^src/core' }
    },
    {
      name: 'no-views-import-api',
      severity: 'warn',
      from: { path: '^src/views' },
      to: { path: '^src/api' }
    }
  ]
};

规则校验的价值:把"架构约定"变成"可执行的检查",防止架构腐化。这也是蒸馏出的架构文档能"活"下去的关键——不是纸面文档,而是可校验的规则。

2.4 Python 项目的依赖分析

Python 项目用 pydepsimport-linter

# 安装 pydeps
pip install pydeps

# 生成模块依赖图
pydeps src/ --max-bonds=10

# 安装 import-linter(架构规则校验)
pip install import-linter

# 配置 .importlinter
cat > .import-linter << 'EOF'
[importlinter]
root_package = myapp

[importlinter:contract:1]
name = Core 不依赖 Utils
type = layers
layers =
    core
    utils
EOF

# 校验
lint-imports

三、架构模式识别

3.1 常见架构模式特征

从代码结构特征反推架构模式:

架构模式 代码特征 识别信号
分层架构 目录按层划分,依赖单向 api → service → dao 单向依赖
微服务 多仓库/多服务目录,独立部署 每个服务有独立 package.json/Dockerfile
插件化 核心 + 插件目录,注册机制 plugins/ 目录 + 注册表/接口约定
事件驱动 事件总线、消息队列 event-buspublishersubscriber
六边形/端口适配器 核心业务与外部隔离 domain/ports/adapters/ 目录

3.2 识别信号的具体命令

# 看是否有多个独立服务(微服务信号)
find . -name "package.json" -not -path "*/node_modules/*" | head -20

# 看是否有 Dockerfile(部署单元信号)
find . -name "Dockerfile" -not -path "*/node_modules/*"

# 看是否有插件注册机制
grep -r "registerPlugin\|pluginRegistry\|addPlugin" src/ --include="*.ts" -l

# 看是否有事件总线
grep -r "EventBus\|eventBus\|emit(" src/ --include="*.ts" -l | head -10

3.3 用 git log 验证架构模式

架构模式不是"看起来像"就行,还要看它是否"真的这么演进":

# 看核心目录的提交历史,验证模块是否稳定
git log --oneline -- src/core/ | head -20

# 看某个模块是否频繁变动(不稳定模块信号)
git log --oneline -- src/views/dashboard/ | wc -l

判断标准

  • 核心模块提交少、稳定 → 架构健康
  • 某个模块提交极多 → 可能是"上帝模块"(什么都往里塞)
  • 目录结构频繁重组 → 架构还在探索期

四、核心模块与边界

4.1 识别核心模块

核心模块是系统的"心脏",识别方法:

# 方法1:按依赖被引用次数(被依赖最多的模块是核心)
# 用 madge 输出 JSON 后统计
madge --json --extensions ts,tsx src/ > deps.json

# 方法2:按提交频率(改动最多的模块)
git log --name-only --pretty=format: | grep "^src/" | cut -d/ -f1-2 | sort | uniq -c | sort -rn | head -10

输出示例:

  1890 src/core/
  1450 src/api/
  1200 src/components/
   890 src/views/
   450 src/utils/

核心模块特征:被依赖多 + 提交频繁 + 业务逻辑集中。src/core/ 就是典型的核心模块。

4.2 识别模块边界

模块边界是"哪些东西属于这个模块,哪些不属于"。判断方法:

# 看模块内部文件是否内聚(是否只做一件事)
ls src/core/
# 输出: model-service.ts model-registry.ts model-loader.ts
# 内聚:都是模型相关

# 看模块间是否有"越界"引用
grep -r "from '../views'" src/core/ --include="*.ts"
# 如果 core 引用了 views,说明边界被破坏

边界被破坏的信号

  • 核心模块引用了 UI 模块(core 依赖 views
  • 工具模块引用了业务模块(utils 依赖 core
  • 模块间互相引用形成环

4.3 用 git log --follow 追踪模块演进

# 追踪核心模块的目录演进
git log --oneline --follow -- src/core/

# 看核心模块是否被拆分过
git log --diff-filter=D --name-only -- src/core/ | head -20

模块演进的价值:一个模块从"单体"拆成"多个子模块",往往对应一次架构决策——这是决策记录(第 08 篇)的重要素材。


五、输出架构文档

分析完成后,把发现整理成"架构文档"。这是蒸馏流程的第三个正式产出物。

5.1 架构文档模板

# 架构文档:xxx

## 架构概览
- 架构模式:分层架构(UI → 业务 → 数据)
- 技术栈:Vue 3 + TypeScript + Pinia + Element Plus
- 部署形态:单页应用(SPA)

## 模块清单
| 模块 | 职责 | 依赖 | 稳定性 |
|------|------|------|--------|
| src/core/ | 核心业务逻辑 | 无外部依赖 | 高(稳定) |
| src/api/ | 接口封装 | core | 中 |
| src/components/ | 通用 UI 组件 | 无 | 高 |
| src/views/ | 页面 | api、components | 低(频繁变动) |
| src/utils/ | 工具函数 | 无 | 中 |

## 依赖关系
- 依赖方向:views → api → core(单向)
- 循环依赖:3 处(详见下方"风险")
- 核心模块:src/core/(被 4 个模块依赖)

## 架构模式
- 分层:UI 层(views/components)→ 业务层(core)→ 数据层(api)
- 状态管理:Pinia(全局 store)
- 组件通信:props/events + Pinia

## 模块边界
- 边界规则:
  - views 不得直接依赖 core(应通过 api)
  - utils 不得依赖任何业务模块
  - 禁止循环依赖
- 边界破坏:2 处(utils 引用了 core)

## 风险与建议
- 循环依赖 3 处:建议拆分 model-service 与 model-registry
- utils 引用 core:建议将相关函数下沉到 core
- views 模块过大:建议按业务拆分子模块

## 可执行规则
- 已用 dependency-cruiser 固化边界规则(见 .dependency-cruiser.js)
- CI 中运行 depcruise 校验,防止架构腐化

5.2 架构文档的用途

架构文档是蒸馏流程的空间骨架

  • 给 06 文档蒸馏:知道哪些模块的文档最值得写
  • 给 07 模式提炼:模块边界 = 模式应用的上下文
  • 给 09 知识图谱:模块关系是图谱的节点和边
  • 给 12 虚拟人化:架构文档是虚拟人 memory 的"系统认知"部分

六、小结

这一篇的核心收获:

  1. 模块划分:从目录结构识别划分逻辑(按层/按业务/按功能/混合)。
  2. 依赖分析:用 madge 检测循环依赖,用 dependency-cruiser 固化架构规则。
  3. 架构模式识别:从代码特征反推模式(分层/微服务/插件化/事件驱动),并用提交历史验证。
  4. 核心模块与边界:用依赖引用数和提交频率识别核心模块,用越界引用检测边界破坏。
  5. 输出架构文档:一份带模块清单、依赖图、边界规则、可执行校验的架构文档。

下一篇,我们开始"蒸馏"文档:[06 文档蒸馏:从 issue、PR、README 提炼知识](06-Git 仓库蒸馏术:从代码仓库到 OpenClaw 虚拟人-文档蒸馏.md)——把散落在 issue、PR、注释里的知识,提炼成结构化的文档。


上一篇:[04 提交历史挖掘:从 commit 提炼演进脉络](04-Git 仓库蒸馏术:从代码仓库到 OpenClaw 虚拟人-提交历史挖掘.md)
下一篇:[06 文档蒸馏:从 issue、PR、README 提炼知识](06-Git 仓库蒸馏术:从代码仓库到 OpenClaw 虚拟人-文档蒸馏.md)

Logo

小龙虾开发者社区是 CSDN 旗下专注 OpenClaw 生态的官方阵地,聚焦技能开发、插件实践与部署教程,为开发者提供可直接落地的方案、工具与交流平台,助力高效构建与落地 AI 应用

更多推荐