Composer默认不删除间接依赖是因其“最小破坏”设计原则:仅移除composer.json中显式声明的包,避免误删其他包所需的共享依赖。
直接执行 composer remove 会删掉包,但未必清干净它的间接依赖——必须配合 --with-dependencies 或手动验证依赖图。
composer remove 默认不删依赖?Composer 的设计原则是“最小破坏”:只移除显式声明在 composer.json 中的包,不碰由其他包带进来的依赖(transitive dependencies)。否则可能意外破坏仍在使用的其他组件。
monolog/monol
og,它依赖 psr/log;后来你 composer remove monolog/monolog,psr/log 仍保留在 vendor/ 和 composer.lock 中symfony/console)也可能需要 psr/log
composer remove --with-dependencies 或后续检查分两步走更可控:先删包,再识别并确认是否可删其残留依赖。
composer remove vendor/package-name(如 composer remove guzzlehttp/guzzle)composer show --tree 查看当前依赖树,搜索被删包名,确认它是否还出现在某条路径中composer why vendor/dependency-name(如 composer why psr/log)验证该依赖是否已被其他包需要composer.json 删除后运行 composer update vendor/dependency-name 触发清理--with-dependencies 的真实作用和风险这个选项不是“智能判断哪些依赖能删”,而是“把当前包声明的所有直接依赖(require 列表)一并从 composer.json 移除”——不管它们是否被其他包共用。
composer remove --with-dependencies guzzlehttp/guzzle
guzzlehttp/guzzle,同时删掉你在 composer.json 里写的 "guzzlehttp/promises"、"psr/http-message" 等(如果有的话)symfony/http-client 也用到的 psr/http-message ——除非你显式把它写进了自己的 require
删完别急着提交,立刻验证以下三点:
git diff composer.json composer.lock:确认只有预期的包被删,没意外波及其他 require 条目vendor/autoload.php 加载是否正常:有些包提供全局函数或类别名,删掉后可能引发 Class not found 或 Call to undefined function
composer outdated 和 composer validate:确保 lock 文件结构完整,没有残留冲突版本依赖关系从来不是线性的,一个 remove 命令背后是整张图谱的重平衡。最稳妥的做法,永远是删之前看 composer show --tree,删之后跑一次 composer why 验证。