依赖模型
按需安装背后的依赖边界
Runa 的依赖模型目标是:不用的能力不进入依赖图,不用的驱动不进入 go.sum。
本页面向 Runa 维护者和扩展作者。普通业务项目只需要按需 go get 和 app.Install(...),不需要自己维护这些边界。
依赖只能朝内核收敛
依赖方向必须朝内核收敛:
驱动块 -> 能力块 -> 内核契约
传输块 -> 内核契约
应用 -> 需要的块
内核不 import 传输、能力、驱动。这样只 import github.com/duxweb/runa 的程序不会被 HTTP、Redis、S3、ORM 等依赖污染。
模块边界怎么判断
一个模块边界应该对应真实的依赖边界。重依赖、外部服务驱动和可选 UI 都应该拆成独立模块。
建议拆分:
- Redis、S3、NATS、AMQP、MQTT、Oro、Excel、WebSocket 等外部依赖
- 控制台、观测、开发工具等 opt-in 能力
- 未来新增的大型传输块
不建议拆分:
- 很小的纯函数工具
- 没有外部依赖且强内聚的内部辅助代码
- 只为了目录好看而增加的模块
判断一次改动是否破坏边界
可以问三个问题:
- 只 import
github.com/duxweb/runa的最小项目,会不会多出 HTTP、Redis、S3、ORM 依赖 - 某个能力是否为了一个驱动反向 import 了驱动包
- 某个传输是否把业务能力类型写死进自己的核心 API
任何一个答案是“会”,都需要重新调整模块边界。
CI 要守住哪些边界
CI 应检查:
GOWORK=off go list -deps .
for mod in $(find . -name go.mod -not -path './.git/*'); do
(cd "$(dirname "$mod")" && go test ./...)
done
如果某个模块引入重依赖,必须能解释为什么它属于该模块,而不是核心。