Composer如何查看某个包的依赖树?(依赖关系分析)

6次阅读

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

Composer如何查看某个包的依赖树?(依赖关系分析)

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 installRoot 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 在冲突场景下只能辅助验证,不能替代 whyprohibits

想导出为文本或搜索特定依赖怎么办

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 解析,它的缩进空格数不规范,容易因版本更新导致脚本断裂

实际用的时候,最常踩的坑不是命令记不住,而是忘了它只反映 lock 文件现状——尤其在多人协作、分支合并后 lock 文件没更新时,show --tree 显示的和别人环境根本不一样。

text=ZqhQzanResources