roave/composer-unused 可识别未被代码引用的包,安装后运行 vendor/bin/composer-unused 即可报告疑似冗余包,需人工确认动态加载、cli 工具等场景,不可依赖不存在的 composer show –unused。

如何用 composer unused 找出未被引用的包
Composer 本身不自带检测冗余依赖的功能,但社区工具 roave/composer-unused 能有效识别 vendor/ 中安装了却没在代码里 use、new 或调用的包。它扫描整个项目(含 src/、tests/ 等),比单纯看 composer.json 更可靠。
安装后运行:
composer require --dev roave/composer-unused</code><br><code>vendor/bin/composer-unused
它会列出所有疑似“死包”的名称,并标注是否被自动加载器注册、是否出现在 autoload 配置中。
- 注意:它不会误删,只做报告;若某包仅用于 CLI 工具(如
phpunit)或配置驱动(如symfony/dotenv),需人工确认是否真冗余 - 某些包通过字符串动态加载(如
class_exists('SomeClass')或 DI 容器反射),会被误判为未使用,要结合业务逻辑判断 - 建议搭配
--no-dev参数跑一次生产环境视角:vendor/bin/composer-unused --no-dev
为什么 composer show --unused 不可用
很多人搜到 composer show --unused,但这个命令根本不存在——这是对 Composer 命令的常见误解。官方 composer show 只支持 -i(已安装)、--platform(PHP 扩展)等参数,没有内置冗余检测逻辑。
- Composer 的设计原则是“声明式依赖”,它只管按
composer.json安装,不管代码里有没有用 - 所谓“未使用”是静态分析问题,必须借助外部工具,比如
roave/composer-unused或composer-require-checker - 试图用
composer depends <package></package>查谁依赖某个包,只能看到直接依赖链,无法反推该包是否被实际调用
删包前必须检查的三个地方
盲目 composer remove xxx 可能导致运行时错误,尤其在框架或插件生态中。删之前务必确认:
-
composer.json的require和require-dev是否真不需要它——有些包虽未直接调用,却是其他包的间接依赖(composer show -t可查依赖树) - 项目中是否存在
include/require绝对路径引入(如require __DIR__.'/vendor/autoload.php'后又手动加载某类),这类写法绕过 Composer 自动加载,工具无法识别 - 是否被 PHP 扩展、.env 配置、CLI 脚本或部署脚本隐式依赖(例如
doctrine/migrations可能只在部署时用,但代码里不出现)
composer update --with-dependencies 不等于瘦身
有人以为执行 composer update --with-dependencies 能清理无用包,其实它只是更新指定包及其子依赖,和“删除未用包”完全无关。真正瘦身的关键动作只有两个:识别 + 移除。
-
composer update默认只会更新已声明的包,不会自动卸载未声明的包(哪怕它们是旧版本残留) - 如果曾手动
composer require过测试工具但没加--dev,它会留在require里,成为隐形膨胀源 - 定期运行
composer validate和composer outdated是辅助手段,但不能替代冗余检测
实际项目里最常被忽略的是 autoload 配置残留:比如删了包却忘了从 composer.json 的 autoload 或 autoload-dev 中移除对应 psr-4 映射,会导致 composer dump-autoload 失败或产生无效扫描路径。