真正起效的是重建 + 过滤 + 关扫描;光删依赖或 vendor 目录易留坑,需用 composer remove 安全卸载,配合 --no-dev、--prefer-dist、--remove-vcs 及 classmap-authoritative 优化自动加载。

删掉没用的依赖,不等于 vendor 就变小了;真正起效的是重建 + 过滤 + 关扫描。光跑 composer remove 或手动删 vendor/ 目录,大概率留坑、报错、CI 失败。
怎么确认一个包到底能不能删
废弃提示(abandoned)只是预警,不是删除指令。先查它是不是被你项目直接 require,还是被其他包拖进来的:
- 运行
composer show monolog/monolog,看输出里有没有abandoned和推荐替代项 - 执行
composer depends monolog/monolog:如果只返回你的项目名,说明是直接依赖;如果返回laravel/framework或symfony/console,说明它是上游硬依赖,不能硬删 - 全局搜代码:
grep -r "use Monolog\" . --include="*.php",再检查config/、app/Providers/里有没有类名字符串残留
用 composer remove 安全卸载包
这是唯一推荐方式——它会同步删声明、删目录、更新 composer.lock、重建 autoload 映射,失败即回退:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 执行
composer remove monolog/monolog,不用管它在require还是require-dev里,命令自动识别 - 想先改
composer.json再统一处理?加--no-update:它只删条目,不碰vendor/和锁文件 - 遇到
required by another package报错,别硬删,先跑composer why guzzlehttp/guzzle看谁在用,再决定是否连带删上游
为什么删完包,vendor/ 还是很大
因为 remove 只清依赖图,不裁文件内容。真正占空间的是每个包内部的 tests/、docs/、.git/,这些必须从安装源头控制:
- 必须先
rm -rf vendor,再跑composer install --no-dev --prefer-dist --remove-vcs——update不会重解压,不会触发裁剪 - 加
archive.excludes配置(在composer.json的config.archive.excludes下):["/tests/", "/docs/", "/examples/", "/.github/", "/CHANGELOG.md"],它在 zip 解压时就跳过,不是事后扫雷 - 别用
find vendor -name tests -type d -exec rm -rf {} +:旧版monolog/monolog把StreamHandler示例放tests/下,删了直接Class not found
--classmap-authoritative 是瘦身生效的关键
前面所有操作都只是“删文件”,但如果不关 autoload 扫描,PHP 仍会遍历整个 vendor/ 目录找类——哪怕 tests/ 已删,扫描失败也可能导致加载异常,尤其在容器或 NFS 环境下:
- 确保
composer.json里有"optimize-autoloader": true - 运行
composer dump-autoload --optimize --classmap-authoritative --no-dev - 后续
install命令必须带--optimize-autoloader --classmap-authoritative,autoloader 才只认vendor/composer/autoload_classmap.php里的路径
这步不减体积,但决定了前面所有清理会不会白做。最容易被忽略的点就在这儿——删完不关扫描,等于裸奔。

















