composer show --tree 展示的是实际安装包的直接 require 关系快照,缩进表示层级依赖而非加载顺序;同一包多路径出现或版本不一致提示潜在冲突,括号内版本(如[2.9.2])为真实安装版本。

composer show --tree 展示的是 require 声明层级,不是加载顺序、调用链或重要性排序。它只反映每个包在 composer.json 中被谁直接 require 了。
缩进到底代表什么
每级缩进(通常两个空格或一个制表符)= 一层直接 require 关系:
-
guzzlehttp/guzzle下缩进出现psr/http-client→ 表示 Guzzle 的composer.json明确写了"psr/http-client": "^1.0" - 同一包在不同缩进深度重复出现(如
monolog/monolog出现在 2 级和 6 级)→ 很可能被laravel/framework和spatie/laravel-ignition分别引入,版本不一致时易冲突 - 缩进不表示“谁先加载”——
autoload行为由classmap/psr-4注册顺序决定,和树无关
为什么你常看错深度
终端输出不是为“看清”设计的,而是为“快速定位路径”服务的纯文本快照:
- 终端宽度不足时换行错位,视觉缩进失真 → 必须加
| less -S或重定向到文件查看 - 同名包不同版本并存,但默认不显示版本号 → 仅靠
composer show --tree无法判断是否真有冲突,得配合composer show vendor/package查实际安装版 - 深度超 4 层后人眼数空格极易出错 → 别硬盯,改用
grep -A5 -B5 "vendor/package"锚定上下文
怎么查清某条依赖的真实路径
聚焦比全量更有用:
- 查整个项目依赖链:必须写
composer show --tree .(点号不能省,否则默认查 root 包) - 只看生产环境:
composer show --no-dev --tree .(--no-dev必须放在--tree前面才生效) - 查某个包的下游:直接
composer show --tree guzzlehttp/guzzle,它从 Guzzle 开始向下展开,不扫全量 - 查未安装包的潜在依赖:加
--remote,如composer show --remote --tree monolog/monolog
真正需要可视化图的时候
当 composer show --tree 输出超过 200 行,或你发现同一包从 5 个不同路径进来、且版本混杂时,纯文本已失效:
-
composer show --tree不生成图,也不支持交互折叠 → 它只是快照,不是分析工具 - 可靠替代是
composer-unused --format=dot | dot -Tpng -o deps.png,但注意:dot默认箭头方向是“被依赖”(A → B 表示 B 用了 A),容易读反 - 私有包或
"type": "path"引入的本地包,默认不会出现在composer-unused图中,需手动加--scan-path
依赖层级不是静态结构,它受 minimum-stability、平台配置、甚至本地 config.json 影响。同一份 composer.lock 在不同环境下解析出的树可能不同——这点最容易被忽略。











