2、依赖清单梳理:如何生成完整的依赖清单?手动 vs 自动工具
依赖清单这东西,说白了就是你家项目的「食材明细」。
我见过太多 SDK 发布后翻车的案例——要么少了个依赖导致用户编译报错,要么多了个没用的包把体积撑得老胖。嗯,今天咱们就聊聊怎么把这份清单理清楚。
为什么依赖清单这么重要?
你想想看,用户拿到你的 SDK,第一件事是什么?不是看文档,而是直接往项目里塞。如果依赖没写清楚,人家一跑就报错,那体验就崩了。
我个人习惯把依赖清单分成三类:
- 核心依赖:SDK 运行必须的,缺一个就罢工
- 可选依赖:某些功能才需要,比如图片处理、网络请求
- 传递依赖:你的依赖又依赖了啥,这最容易出问题
我在项目中遇到过最坑的一次,就是某个底层库偷偷升级了,结果我们的 SDK 在用户那边直接炸了。从那以后,我每次发布前都会把依赖树扒个底朝天。
手动梳理:最原始但最可控
说实话,手动列依赖这事,我建议只在项目初期做。比如你刚搭好架子,依赖还不到 10 个的时候,拿个文本文件记一下就行。
手动梳理的步骤其实很简单:
- 打开你的
pom.xml或requirements.txt - 把每个依赖的名字和版本抄下来
- 标注哪些是直接依赖,哪些是间接依赖
- 检查版本号有没有冲突
自动工具:效率翻倍的正确姿势
到了中大型项目,手动就扛不住了。这时候就得靠工具。我常用的两个工具,一个 Python 的 pip freeze,一个 Java 的 mvn dependency:tree。
Python 项目:pip freeze
这个命令简单粗暴,直接把当前环境里所有已安装的包列出来:
pip freeze > requirements.txt
但这里有个坑——它会把你环境里所有的包都列出来,包括那些你根本没在项目里用到的。所以我的做法是:
- 先建一个干净的虚拟环境
- 只安装项目真正需要的包
- 再跑
pip freeze
pipreqs 这个工具,它会扫描你的代码,只生成真正用到的依赖。命令是 pipreqs ./ --force。
Java 项目:mvn dependency:tree
这个命令能帮你看到完整的依赖树,包括每个传递依赖是从哪来的:
mvn dependency:tree -DoutputFile=deps.txt
输出结果长这样:
[INFO] com.example:my-sdk:jar:1.0.0
[INFO] +- org.slf4j:slf4j-api:jar:1.7.30:compile
[INFO] +- com.google.guava:guava:jar:30.1-jre:compile
[INFO] | \- com.google.guava:failureaccess:jar:1.0.1:compile
[INFO] \- org.apache.commons:commons-lang3:jar:3.12.0:compile
看到那个 failureaccess 了吗?这就是传递依赖。如果你不检查,用户可能根本不知道自己的项目里多了这么个东西。
手动 vs 自动:到底怎么选?
我整理了一张对比表,你一看就明白:
| 对比维度 | 手动梳理 | 自动工具 |
|---|---|---|
| 适用场景 | 小项目(<10 个依赖) | 中大型项目 |
| 准确性 | 容易遗漏 | 高,但需过滤无关包 |
| 传递依赖 | 很难追踪 | 自动展示完整树 |
| 版本冲突 | 肉眼检查 | 工具可检测 |
| 维护成本 | 每次手动更新 | 一键生成 |
我个人建议:小项目用手动,大项目用自动,但最终发布前一定要用自动工具再过一遍。这不是选择题,而是组合拳。
核心逻辑:一张图看懂依赖清单生成
下面这张图是我自己画的,把整个流程串起来了:
避坑指南:我踩过的那些坑
做依赖清单这么多年,我总结了几条血泪教训:
- 别信「最新版」:我曾经直接用了某个库的最新版,结果它依赖的另一个库版本不兼容,整个项目编译不过。后来我学乖了,每次都用固定版本号。
- 传递依赖要锁死:Java 里可以用
maven-enforcer-plugin来强制版本,Python 里可以用pip-tools生成锁定文件。 - 发布前再跑一遍:我习惯在发布前最后一步,重新生成一次依赖清单,确保没有因为开发过程中的临时改动而引入脏东西。
核心要点:依赖清单不是写一次就完事的。每次发布前,都要重新生成、重新检查。手动适合小项目,自动适合大项目,但最终都要用工具兜底。
好了,依赖清单这块就聊到这儿。记住一句话:清单越干净,用户越省心。