composer show --tree是唯一开箱即用的依赖树查看命令,它基于vendor/和composer.lock的真实安装快照,无需插件或Graphviz,但需在项目根目录运行且目标包必须已安装。

直接用 composer show --tree,别试 composer tree——它不是 Composer 内置命令,是旧插件残留,装了反而可能破坏 composer update。
为什么 composer show --tree 是唯一开箱即用的方案
这个命令读的是 vendor/ 和 composer.lock 的真实快照,不是 composer.json 里写的“理想状态”。它不需要额外安装插件、不依赖 Graphviz、不卡在权限或 PATH 上。
- 必须在项目根目录运行,且目标包已安装(
ls vendor/guzzlehttp/guzzle能看到才算) - 不加包名会输出整个树,几百行起,基本没法扫;加包名才聚焦:
composer show --tree guzzlehttp/guzzle - 输出里缩进层级 = 实际依赖深度,但纯文本无颜色/折叠,超过 4 层就容易看串行
-
--no-dev必须加:否则phpunit、mockery这类 dev-only 包会把树拉得又深又偏
查“谁把我拉进来的”要用 composer why --tree
composer show --tree 只回答“它依赖谁”,而 composer why --tree 才能回溯源头。比如你发现 monolog/monolog 被装进来了,但没在自己 composer.json 里写,就得靠它定位。
- 输出格式是倒序链路:
monolog/monolog └── laravel/framework └── your-project-name dev-main,末尾才是你自己的项目 - 带
[dev]表示来自require-dev,上线部署时不会出现 - 如果某层中断(比如停在
symfony/console就没了),大概率是它通过provide psr/log虚拟声明,没继续向下解析 - 不加
--tree只显示第一层,等于白查
文本太乱?用 grep 和 less 比图形化工具更准
可视化工具(如 composer-graph 或 composer-visualizer)要装 Graphviz、生成 HTML/SVG、还得开浏览器——但真正排查问题时,你往往只需要确认“guzzlehttp/guzzle 是被 laravel/framework 还是 spatie/laravel-ignition 拉进来的”,这时候终端一行命令更快。
- 横向滚动看全貌:
composer show --tree --no-dev | less -S - 精准定位上下文:
composer show --tree | grep -A 3 -B 3 "guzzlehttp/guzzle"(-A 3显示匹配后 3 行,-B 3显示前 3 行) - 包名必须带斜杠,写成
"guzzlehttp/guzzle",否则可能误匹配到guzzlehttp/ringphp等无关项 - 如果
grep输出为空,先运行composer show确认包是否真在vendor/里
真正复杂的地方在于:Composer 的依赖解析是动态的,composer show --tree 显示的是当前锁文件快照,但如果你刚改完 composer.json 没跑 install 或 update,结果就滞后;私有包还可能被 replace 或 provide 隐藏,这时得手动 grep composer.lock 才能看清实际来源。











