composer remove --no-update仅修改composer.json中对应包的require或require-dev条目,不删除vendor文件、不更新composer.lock、不重建autoload映射、不解析依赖,属声明层延迟操作,需后续执行composer install或composer update才能真正卸载。

composer remove --no-update 到底做了什么
它只改 composer.json,其他什么都不碰。不删 vendor/ 下的文件,不更新 composer.lock,也不重建 autoload 映射——连依赖解析都跳过。
这命令本质是“延迟执行”,适合批量清理依赖声明后再统一处理,但容易误以为“已经卸载了”。常见错误现象包括:composer show vendor/package 仍显示已安装、ls vendor/vendor-name 还能看到目录、类照常能 use 成功(因为 autoload 没刷新)。
- 只从
require或require-dev中移除对应行,自动识别位置,无需加--dev - 若包名同时出现在两个区块(极少见),需显式指定
--dev或不加,否则只处理require - 执行后
composer.lock的哈希值不变,CI 构建时可能因锁文件与实际 vendor 不一致而失败
什么时候该用 --no-update,什么时候不该用
适合场景很窄:你明确要分阶段操作,比如在 CI 脚本里先集中修改 composer.json,再统一 composer update;或一次删多个包,避免每次触发完整依赖解析耗时。
不适合日常手动卸载:漏掉后续同步步骤是高频事故源。尤其当团队协作时,有人提交了只改 json 的 PR,却没补 update,会导致环境不一致。
- 必须搭配后续命令才生效:
composer update(推荐)或composer install -
composer update --lock只更新锁文件,不清理vendor;真正删文件得靠composer install或完整update - 不要和
composer dump-autoload -o混淆:它不重建映射,--no-update 后必须等update或install触发自动重建
删完不 update,vendor 里文件还在正常吗
完全正常,而且是设计如此。Composer 不会在 --no-update 模式下碰磁盘——它只做声明层变更。残留不是 bug,是留给你人工确认和控制节奏。
但这也意味着:你不能靠 ls vendor/ 判断是否“已卸载”,也不能靠 composer show 验证结果。这两个命令反映的是当前 vendor 和 lock 状态,而非 json 声明。
-
composer show vendor/package仍返回信息 → 因为包还在vendor/里,且lock没变 -
composer depends vendor/package可能报错或返回空 → 它查的是lock,而lock未更新 - 真正验证是否生效,得等
composer install跑完,再检查ls vendor/vendor-name和composer show
想批量删多个包,怎么写命令
composer remove 不支持空格分隔多个包名,写成 composer remove a/b c/d --no-update 会直接报错。必须逐条执行。
没有语法糖,但有可落地的操作路径:连续运行多条 --no-update 命令,或干脆手动编辑 composer.json,再跑一次 composer update。
- 安全做法:分步执行
composer remove vendor/a --no-update、composer remove vendor/b --no-update… 最后composer update - 高效做法:直接打开
composer.json,删掉require和require-dev里的目标项,保存后运行composer update,效果等价 - 别用
composer update vendor/a vendor/b来“模拟卸载”:它只会尝试降级或重装,不会移除
最易被忽略的一点:--no-update 后的 composer.json 和 composer.lock 差异必须被显式收敛。没人帮你记住哪几行删了,也没人自动补上 update——这一步永远得人工触发,且只能由你决定用 install 还是 update。











