依赖爆炸
项目刚开始,依赖还不多,package.json 里就 20 多个包。但用了一年多,依赖就爆炸了,直接依赖 50 多个,间接依赖 200 多个。
每次 npm install 都要等好几分钟,node_modules 文件夹有 500MB。更烦的是,有些包已经没人维护了,但还在用。
版本冲突
最烦的是版本冲突。A 包依赖 React 16,B 包依赖 React 17,C 包依赖 React 18。三个包都要用,但 React 只能装一个版本。
用 npm 的话,会装多个版本,但只用一个。用 yarn 的话,会报错,要手动解决。
我们最后用了 pnpm,它用符号链接,同一个包只装一次,但不同版本可以共存。虽然解决了冲突,但 node_modules 的结构变得很复杂。
安全漏洞
用 npm audit 检查,发现 50 多个安全漏洞。有些是直接依赖,有些是间接依赖。
修复漏洞要升级包,但升级包可能破坏功能。我们试过升级一个包,结果整个项目都挂了。排查了半天,发现是 API 变了。
有些漏洞在间接依赖里,不能直接升级。要用 npm audit fix,但有时候会升级到不兼容的版本。
功能重复
项目里有很多功能重复的包:
- 日期处理:
moment、dayjs、date-fns,三个都在用 - HTTP 请求:
axios、fetch、request,三个都在用 - 工具函数:
lodash、ramda、underscore,三个都在用
功能重复,但都在用。想统一,但改起来很麻烦,就一直拖着。
没人维护的包
有些包已经没人维护了,但还在用。比如 request,官方已经废弃了,但项目里还在用。
想换,但改起来很麻烦。不改,又担心安全问题。最后只能硬着头皮用,等有时间再换。
我们的改进
用了一年多,我们做了这些改进:
1. 定期清理
定期清理不用的包,用 depcheck 检查。发现不用的包,直接删掉。
清理了几次,依赖从 200 多个降到 150 多个,但还是很多。
2. 统一工具
统一工具库,比如日期处理只用 dayjs,HTTP 请求只用 axios。其他工具库逐步替换。
替换很慢,但至少方向对了。
3. 锁定版本
锁定依赖版本,用 package-lock.json。这样不同环境装的版本一样,不会出问题。
但锁定版本也有问题,升级很麻烦。每次升级,都要测试一遍,确保没问题。
4. 安全扫描
定期做安全扫描,用 npm audit 和 snyk。发现漏洞,及时修复。
但修复漏洞很麻烦,有时候要升级很多包,风险很大。
如果重新开始
如果重新做一个项目,我会:
- 尽量少用第三方库,能自己写就自己写
- 选维护活跃的库,不要选没人维护的
- 统一工具库,不要重复
- 定期清理,不要积累
总结
依赖管理是个大问题,不是简单的安装和升级。版本冲突、安全漏洞、功能重复、没人维护,都是常见问题。
如果你们项目也有依赖问题,建议定期清理,统一工具,锁定版本,做好安全扫描。虽然麻烦,但总比出问题好。
另外,依赖管理要早规划,不要等出问题再处理。等出问题了,处理起来就很麻烦了。