composer remove 是唯一安全卸载方式,它原子化执行删声明、清目录、更新锁文件、重建autoload四步,失败自动回退;手动删vendor或硬改composer.json易致Class not found、autoload错乱或lock哈希不一致。

composer remove 是唯一安全卸载方式
别手删 vendor/、别硬改 composer.json 后跑 composer install——这三步操作看似直觉,实则大概率导致 Class not found、autoload 映射错乱或 composer.lock 哈希不一致。Composer 2.2+ 内置的 composer remove 才是原子化卸载:它自动识别包在 require 还是 require-dev 中,删条目、清目录、更新锁文件、重建 autoload,任一环节失败即回退。
-
composer remove monolog/monolog—— 自动判断位置,无需加--dev - 若包同时出现在
require和require-dev(极少见),才需显式指定--dev - 想先改声明、后统一处理?加
--no-update,只动composer.json,后续再composer update - 执行完立刻验证:
composer show monolog/monolog应报Package not found,ls vendor/monolog应提示No such file or directory
“required by another package” 不是报错,是保护机制
运行 composer remove guzzlehttp/guzzle 却被拦住,提示被 symfony/http-client 依赖——这不是命令失效,是 Composer 在阻止你破坏依赖树。强行绕过只会让项目进入“能装不能跑”的状态。
- 查谁在用:
composer why guzzlehttp/guzzle,输出会列出所有直接引用者 - 若上游包(如
symfony/http-client)本身也不需要了,就按提示确认移除;否则得先处理它 - 临时清理子依赖(比如
guzzlehttp/promises只被 Guzzle 引用)?加--with-dependencies,但别滥用 - 切忌删完
composer.json就跑composer install——锁文件没同步,CI 构建可能直接失败
卸载后代码里还留着 use、new、配置项,autoload 不会帮你擦屁股
composer remove 只管声明和自动加载映射,不管你的 PHP 文件是否还写着 use MonologLogger;,也不删 config/logging.php 里的驱动配置或 app/Providers/LoggingServiceProvider.php 里的注册逻辑。这些残留不清理,上线就炸。
- 全局搜
use:grep -r "use Monolog\" . --include="*.php"(注意反斜杠转义) - 检查
config/下配置文件、服务提供者、事件监听器、中间件等是否硬编码调用了该包 - 若之前在
composer.json的autoload.files或autoload.psr-4里手动加过路径,也得手动删掉 - 运行
composer dump-autoload -o强制刷新映射,尤其在 Docker 或 CI 环境里,缓存常比本地更顽固
怎么确认卸载干净?别信感觉,要看三处
类还能 new 出来,或者 composer show 还显示已安装,往往不是没删成,而是缓存或路径残留干扰了判断。
-
composer show vendor/package-name必须报错Package not found -
ls vendor/vendor-name必须提示目录不存在 -
composer dump-autoload -o后仍能new?大概率是vendor/composer/autoload_classmap.php里还留着旧类名,或opcache/APCu没清 - Laravel 9+ 默认启用
classmap-authoritative,删包后不dump-autoload,就会卡在旧映射里,连composer diagnose都可能看不出问题
最麻烦的不是卸载动作本身,而是依赖链嵌套 + 代码残留 + 缓存分层带来的多维干扰。一个包删得干不干净,得靠 show、ls、dump-autoload 三连查,少一步都可能埋雷。










