composer show --tree 显示已安装包的树形依赖结构,仅展示 composer.lock 中的版本快照,不自动安装;漏写包名、大小写错误或未安装均会报错;依赖冲突时显示妥协后版本,需配合 why/prohibits 分析原因。

composer show --tree 查看包的依赖树
直接运行 composer show --tree vendor/package-name 就能看到该包及其所有下游依赖的层级结构。它本质上是把 composer show 的扁平列表转成缩进式树形,不改依赖图本身,只改变展示方式。
常见错误是漏写包名,比如只输 composer show --tree,结果报错 Not enough arguments;或者输错 vendor 名(如把 monolog/monolog 写成 monolog),会提示 Package not found。
- 必须指定完整包名,格式为
vendor/name,大小写敏感 - 如果项目未安装该包,命令会失败——
--tree不会自动拉取,只查已安装或已锁在composer.lock中的版本 - 输出里带
[dev-master]或[1.2.3]的括号内容,表示实际解析出的版本,不是composer.json里写的约束
composer depends -r 查谁依赖了某个包
想反向排查:是哪个包把 symfony/polyfill-php80 拖进来的?用 composer depends -r symfony/polyfill-php80。它列出所有直接或间接依赖该包的顶层包,对定位“幽灵依赖”特别有用。
注意 -r(recursive)不能省,否则默认只查直接依赖;而且它不显示路径深度,只列包名+版本,没法一眼看出嵌套层级。
- 输出中的
root表示你当前项目(即composer.json根目录)直接 require 了它 - 如果某包出现在结果里但你没手动 require,说明它是某个依赖的子依赖,可能被高版本升级意外引入
- 不支持通配符,不能查
symfony/*,只能精确到具体包名
依赖冲突时 tree 输出不可信
当 composer install 报 Root composer.json requires xxx, but xxx is locked to yyy 这类冲突时,composer show --tree 仍会输出,但展示的是 lock 文件里“已妥协”的版本,不是你期望的版本约束。这时候看到的树,其实是 Composer 实际妥协后的快照,不是声明意图。
比如你写了 "guzzlehttp/guzzle": "^7.0",但 tree 里显示 guzzlehttp/guzzle v6.5.8,说明有别的包强制要求 v6,Composer 做了降级——此时 tree 是结果,不是原因。
- 先运行
composer why guzzlehttp/guzzle看谁在拉旧版 - 再结合
composer prohibits guzzlehttp/guzzle:7.*找阻止升级的具体约束 -
--tree在冲突场景下只能辅助验证,不能替代why和prohibits
想导出为文本或搜索特定依赖怎么办
composer show --tree 输出是纯文本,可直接管道给 grep,比如 composer show --tree myorg/mylib | grep "psr/log" 快速确认是否引入了日志接口。但注意它不支持 JSON 输出,也没法导出为 dot 或 mermaid 格式做可视化。
- 需要图形化?得靠第三方工具,比如
composer-visualize(需额外安装,且只支持较老 Composer 版本) - 想批量分析多个包?可以用
composer show --format=json获取原始数据,再自己解析依赖字段,比--tree更可靠 - CI 场景下别依赖
--tree解析,它的缩进空格数不规范,容易因版本更新导致脚本断裂
show --tree 显示的和别人环境根本不一样。










