2. 依赖分析工具入门
说实话,我见过太多项目,node_modules 文件夹比源码还大好几倍。你想想看,一个简单的 CRUD 应用,依赖树能膨胀到上千个包。为什么会这样?因为很多人根本不知道“谁依赖了谁”。
今天我们就来聊聊依赖分析工具。这三个命令——npm ls、yarn why、pnpm ls——是我日常排查依赖问题的左膀右臂。我个人习惯先跑一遍它们,再决定要不要动手术。
npm ls:最基础的依赖树查看器
npm ls 是 Node.js 自带的命令。它能打印出当前项目的完整依赖树。说白了,就是把你 package.json 里声明的依赖,以及它们各自的依赖,一层层展开给你看。
核心用法:
# 查看所有依赖
npm ls
# 查看某个特定包
npm ls lodash
# 只看顶层依赖(不展开子依赖)
npm ls --depth=0
# 查看生产依赖
npm ls --prod
我在项目中遇到过最典型的场景:项目构建突然变慢,我第一反应就是跑 npm ls。结果发现某个工具库被安装了三个不同版本。嗯,这就是典型的依赖版本冲突。
小技巧:如果输出太长,可以配合 --all 参数查看完整树,或者用 grep 过滤。比如 npm ls | grep lodash 能快速定位 lodash 的所有出现位置。
yarn why:精准定位“为什么会有这个包”
yarn 的 why 命令是我最喜欢的工具之一。它不像 npm ls 那样一股脑输出整棵树,而是直接告诉你:这个包是怎么被引入的,谁依赖了它。
核心用法:
# 查看某个包为什么存在
yarn why lodash
# 查看某个包的版本信息
yarn why --recursive lodash
输出示例:
yarn why v1.22.19
[1/4] Why do we have the module "lodash"?
[2/4] Initialising dependency graph...
[3/4] Finding dependency...
[4/4] Calculating file sizes...
=> Found "lodash@4.17.21"
info Reasons:
This module exists because
project#package.json depends on it.
"webpack#lodash" depends on it.
info Disk size without dependencies: "1.5MB"
info Disk size with unique dependencies: "1.5MB"
info Disk size with transitive dependencies: "1.5MB"
info Number of shared dependencies: 0
你看,它直接告诉你:项目自己的 package.json 依赖了 lodash,同时 webpack 也依赖了 lodash。这就是为什么它会出现。
注意:yarn why 只能用于 yarn 管理的项目。如果你用的是 npm 或 pnpm,需要换用对应的命令。
pnpm ls:更清晰的依赖树展示
pnpm 的 ls 命令和 npm 类似,但输出更清晰。它默认会显示包的版本号、路径,以及是否是重复安装的。
核心用法:
# 查看所有依赖
pnpm ls
# 查看某个包
pnpm ls lodash
# 查看深层依赖
pnpm ls --depth=5
# 查看全局依赖
pnpm ls -g
我个人觉得 pnpm ls 的输出比 npm ls 更友好。它会用缩进和颜色区分不同层级的依赖,一眼就能看出哪些包是重复的。
如何判断哪些包是冗余的?
光知道“谁依赖了谁”还不够,我们还得找出冗余的包。这里我分享几个实战经验:
- 版本重复:同一个包出现多个版本,比如 lodash@4.17.21 和 lodash@4.17.20。这通常意味着某个子依赖锁死了旧版本。
- 未被引用:某个包在
package.json里声明了,但代码里根本没用到。可以用depcheck工具辅助检测。 - 间接依赖过多:某个包本身很小,但它依赖了一大堆其他包。比如
is-odd这种包,就为了判断奇偶,结果依赖了is-number等好几个包。
避坑指南:我曾经在项目里发现一个包被安装了 7 个版本。原因是某个老旧的工具库锁死了 lodash@3.x,而其他库用的是 lodash@4.x。最后我通过 npm dedupe 合并了版本,node_modules 体积直接减少了 40%。
实战:用依赖分析工具排查问题
假设你发现项目构建时间变长了。我们来一步步排查:
- 先跑
npm ls --depth=0,看看顶层依赖有没有明显多余的包。 - 如果发现某个包可疑,比如
moment(它体积很大),用yarn why moment看看是谁依赖了它。 - 如果发现是某个工具库依赖了 moment,而那个工具库你只用了其中一小部分功能,可以考虑替换成更轻量的替代品。
- 最后用
pnpm ls --depth=3确认依赖树是否干净了。
嗯,这里要注意:不要一上来就删包。先搞清楚依赖关系,再动手。否则很容易把项目搞崩。
知识体系图:依赖分析的核心逻辑
总结一下
依赖分析工具说白了就是你的“侦探工具”。npm ls 看全貌,yarn why 查原因,pnpm ls 看细节。三者配合使用,基本能解决 90% 的依赖问题。
我个人建议:每次接手新项目,第一件事就是跑一遍 npm ls --depth=0。看看顶层依赖有多少,有没有明显多余的包。然后再用 yarn why 深挖几个可疑的包。这样你心里就有底了。
记住,不要盲目删包。先分析,再行动。这才是工程师该有的态度。