composer show --tree是当前唯一稳定、无需插件、全版本兼容的依赖树查看命令,读取vendor/和composer.lock的真实安装快照,必须在项目根目录运行,低于2.0需先self-update。

composer show --tree 是当前唯一稳定查依赖树的命令
别再试 composer tree 或 composer show -t(短横线)——前者不是内置命令,后者在 Composer 2.5+ 已被移除;composer show --tree 在 2.0+ 全版本可用,且不依赖插件、不需额外配置。它读的是 vendor/ 和 composer.lock 的真实快照,反映“已经装进去”的结构,不是 composer.json 里写的理想状态。
必须在含 composer.json 的项目根目录运行,否则提示 No composer.json found 或直接空输出;若报错 Command "show" is not defined,说明 Composer 版本低于 2.0,先跑 composer self-update。
- 不加包名:输出全量依赖树(几百行起步,慎用)
- 查某个包:直接跟上名字,如
composer show --tree guzzlehttp/guzzle - 想看整个项目结构:就用
composer show --tree,不用点号或.(那是旧版show -t的写法,现已失效) - 输出中带
[dev-master]或[7.4.0]的括号内容,是实际安装的版本,不是约束表达式
composer why --tree 才能真正溯源到你自己项目的 require 行
composer why monolog/monolog 默认只返回一级上游(比如 laravel/framework),但你真正关心的是:“我自己的 composer.json 哪一行写了它?”这时候必须加 --tree。
正确姿势是:composer why --tree monolog/monolog。如果输出末尾出现 your-project-name dev-main,才说明源头是你自己项目的 require;若结尾带 [dev],说明来自 require-dev。
- 不加
--tree就等于白查——尤其当你想确认是不是误加了某个包时 - 如果树在某一层中断(比如停在
laravel/framework就没了),大概率是它用了provide声明虚拟包,没继续向下解析 - 未安装的包不能用
why查,得换composer why --remote monolog/monolog
composer show --who 比 composer depends 更可靠
composer depends 是 2.4+ 的实验功能,默认关闭,启用要先跑 composer config experimental.show-depends true,而且遇到 provide、replace 或本地 path 仓库时容易漏判。而 composer show --who psr/log 直接从已安装包的 require 字段里翻,干净、确定、无歧义。
-
composer show --who只显示“直接声明依赖它的包”,比如 A → B → C,它只列 B,不展开 A——这是设计,不是 bug - 过滤开发依赖:加
--no-dev,如composer show --who --no-dev psr/log - 结果为空 ≠ 没人用——可能是通过虚拟包间接提供,此时应回头看
composer show --tree全局结构 - 注意大小写和 vendor 名拼写,
monolog/monolog写成monolog会报Package not found
依赖树看不见刚 require 的包?先确认 vendor 是否已落地
composer show --tree 不读 composer.json,它读的是 vendor/composer/installed.json。所以刚运行 composer require foo/bar 后立刻执行该命令,若跳过了安装步骤,新包不会出现在树中。
- 检查
vendor/foo/bar/目录是否存在,这是最直接的验证方式 - 用了
--no-install或--dry-run,也不会写入vendor - 包被跳过安装:比如声明了
"ext-redis": "*"但本地没启用 redis 扩展,该包就不会进vendor,也不会出现在树里 - 依赖冲突时,树里显示的是
composer.lock中“已妥协”的版本,不是你写的约束——此时composer show --tree是结果,不是原因,得配合composer why和composer prohibits分析
真正复杂的地方在于:依赖树是静态快照,不体现自动替换(如 psr/log 被 monolog/monolog 提供)、不反映加载顺序、也不等同代码调用链。纯文本树在依赖超过 50 个包时基本不可读,这时候就得靠 composer global require baethon/composer-graph 配合 dot 生成图谱——但前提是本地装了 graphviz。


















