composer show --root-reqs 仅显示 composer.json 中 require 和 require-dev 声明的顶层包名及已安装版本(非版本约束),不递归、不展示间接依赖,适合 ci 检查与依赖变更比对。

composer show --root-reqs 只显示顶层依赖,但默认不包含版本约束
它输出的是当前 composer.json 里 require 和 require-dev 声明的包名+已安装版本,不展示你在 composer.json 中写的版本号(比如 "monolog/monolog": "^2.0"),只显示实际装上的 2.10.0 这类。这点容易误以为“没变”,其实约束可能已更新但尚未重装。
- 想看真实声明的版本约束,得用
composer show --platform --no-dev或直接读composer.json -
--root-reqs不递归,不会出现symfony/polyfill-php80这种被间接引入的包 - 加
--tree就失效了——这两个参数互斥,--root-reqs本身就是为了跳过树形展开
对比 composer show 和 composer show --root-reqs 的典型差异
执行 composer show 默认列出全部已安装包(含传递依赖),动辄上百行;而 composer show --root-reqs 通常就 10–30 行,聚焦你亲手按下的“确认键”。适合 CI 检查、PR 描述依赖变更、或快速验证 composer.json 修改是否生效。
- CI 场景下建议加
--format=json:输出结构化数据,方便脚本提取name和version - 若项目用了
replace或provide,--root-reqs仍只按require字段列,不会自动映射虚拟包 - 它不区分稳定/开发版——哪怕你写了
"dev-main",输出里也只显示dev-main,不会标红或警告
为什么 --root-reqs 不显示 require-dev 里的包?它其实会显示
默认情况下,composer show --root-reqs 同时包含 require 和 require-dev 中的包。但如果你在运行时加了 --no-dev,它就会过滤掉 dev 依赖——这个行为常被忽略,导致你以为“没装上”或“配置没生效”。
- 检查是否意外加了
--no-dev:运行composer show --root-reqs --help看默认行为说明 - CI 中常用
--no-dev节省安装时间,但此时--root-reqs输出也会缩水,需同步调整预期 - 若只想看生产依赖,明确加
--no-dev;若要完整顶层依赖,确保命令里没这个开关
配合 diff 查看直接依赖变更的实用组合
真正有用的是把 --root-reqs 当作 diff 的输入源,而不是单独执行。比如在 PR 流程中,先存一份 baseline:
composer show --root-reqs --format=json > before.json
改完 composer.json 并 composer update xxx 后再跑:
composer show --root-reqs --format=json > after.json
- 用
diff before.json after.json能清晰看到哪些顶层包升/降级、新增或移除 - 注意 JSON 输出字段顺序不固定,建议用
jq -S . before.json | diff -u - 避免格式干扰 - 如果只关心包名变化(忽略版本),可用
composer show --root-reqs --format=plain | cut -d' ' -f1 | sort提取并比对
真正的坑在于:composer update 没加具体包名时,即使只改了 composer.json 里一个依赖,也可能触发传递依赖的版本漂移——--root-reqs 看不到这点,得靠 composer show --tree 或锁文件比对来补全视角。










