composer remove 不会自动清理冗余依赖,仅移除显式声明且无其他包复用的直接依赖;残留需靠 composer-unused 检测、手动排查配置/注解调用,并推荐重建 vendor 目录彻底清理。

composer remove 不会自动清理冗余依赖,它只删你明确指定的包,且仅当该包在 composer.json 中被显式声明时才生效。想靠它“一键瘦身”基本行不通。
为什么 composer remove 总是删不干净
它不是扫描工具,而是反向安装命令:只负责移除目标包及其未被其他任何已装包复用的直接子依赖。但以下情况它完全不管:
-
psr/log还在vendor/里?因为它正被symfony/consolerequire,composer remove monolog/monolog不会动它 - 你删了
guzzlehttp/guzzle,但guzzlehttp/promises残留——除非它只被 Guzzle 引用,否则不会被连带清除 -
composer remove默认不物理删除vendor/目录(尤其老版本或中断后),得靠后续composer install或composer update触发同步
真正能识别“冗余包”的只有 composer-unused
它静态扫描 src/、tests/、config/ 等目录里的 use、new、class_exists 调用,再比对 composer.json 的 require 和 require-dev,找出没被代码直接引用的包。但注意边界:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 它不分析配置文件中的字符串驱动(如
'driver' => 'some-package') - 不处理注解(如 Doctrine 的
@ORMEntity)、PHPStan 扩展、或服务提供者注册 - 运行前必须先装插件:
composer require --dev composer-unused/composer-unused - 执行
composer unused后,列表里标[unused]的才建议删,标[used]的别碰
composer remove 执行后必须补的三件事
命令退出成功 ≠ 清理完成。残留常藏在 autoload 映射、配置、或框架注册点里:
- 搜全项目:
grep -r 'SomePackage\Class' . --include="*.php",尤其检查config/、app/Providers/、routes/ - 删掉
config/app.php(Laravel)或config/app.php(ThinkPHP)里的服务提供者和别名 - 强制刷新自动加载:
composer dump-autoload -o;ThinkPHP 还要跑php think clear
最彻底的清理方式:重建 vendor/
当不确定哪些是历史遗留孤儿包时,重建比猜更可靠:
- 先确认
composer.json的require和require-dev已手动清空目标包(grep -n "package-name" composer.json双重验证) - 删掉整个
vendor/和composer.lock:rm -rf vendor composer.lock - 执行
composer install—— 它只装composer.json显式声明的包 + 它们必需的子依赖,所有“未声明也未被依赖”的包都会消失 - 对比旧
vendor.bak(如有)可直观看到哪些包被真正剔除
真正难的从来不是删包,而是那些没写在 composer.json 里、却活在配置或注解里的隐式调用——它们不会报错,直到某个请求路径走到那里才抛出 Class not found。










