真正有效的清理必须让声明、锁文件、磁盘文件、自动加载四者同步;否则必出 class not found 或 package not found。需手动 grep 配置与服务提供者,验证 composer show 和 ls vendor/,并检查 autoload 配置残留。

直接删 composer.json 里的包名行不是清理,只是埋雷;真正有效的清理必须让声明、锁文件、磁盘文件、自动加载四者同步。否则必出 Class not found 或 Package not found。
怎么确认一个包真的没被用到
Composer 自身不扫描代码,composer-unused 工具只能捕获静态 use 和 new,对以下情况完全失效:
- Laravel 的
config/logging.php里写的'handler' => MonologHandlerStreamHandler::class字符串 -
app/Providers/下注册的TelescopeServiceProvider,删了laravel/telescope却没注释掉register() - 通过反射或
class_exists("Vendor\Package\SomeClass")动态加载的类
所以必须手动 grep -r "monolog" app/ config/ --include="*.php",重点查配置和服务提供者目录;开发依赖更要逐个看是否只在 tests/ 或 phpunit.xml 里出现。
为什么 composer remove 后 vendor/ 还有残留
这是正常行为,不是 bug:Composer 2.2+ 的 composer remove 默认会删 vendor/ 子目录,但前提是它成功更新了 composer.lock 并触发了“同步阶段”。常见中断原因包括:
- 包名大小写拼错(
monolog/monolog≠Monolog/Monolog) - 该包被其他已装包显式依赖,例如
symfony/http-clientrequireguzzlehttp/guzzle,此时composer remove guzzlehttp/guzzle会中止并提示谁在用 - 执行后没运行
composer dump-autoload -o,导致vendor/composer/autoload_psr4.php里还存着旧映射
验证是否真删干净:运行 composer show monolog/monolog 应报错 Package not found,再 ls vendor/monolog 应提示 No such file or directory。
使用ydata-profiling(前身为pandas-profiling)生成全面的数据质量报告,包含相关性分析、缺失值模式和基数检测。导出交互式HTML仪表板和JSON摘要。
批量删 require-dev 包的正确姿势
composer remove --dev 支持空格分隔多个包名,但不支持逗号或引号:
composer remove --dev phpunit/phpunit friendsofphp/php-cs-fixer behat/behat
如果某包报 Package is required by another package,别硬删,先查依赖链:composer depends phpunit/phpunit;删完必须补一步:composer install --no-dev,否则 vendor/ 里可能残留 dev-only 的传递依赖(比如 phpstan/phpstan 拉了 phpunit/phpunit 的子依赖)。
删完还要检查 autoload 配置陷阱
很多中文项目在 composer.json 的 autoload.files 或 autoload.psr-4 里硬编码了已删包的路径,比如:
"autoload": {
"psr-4": {
"App\": "app/",
"Monolog\": "vendor/monolog/monolog/src/" ← 这行必须手动删
}
}
这种残留不会被 composer remove 清理,但会导致 composer dump-autoload -o 失败或加载失败。每次删包后,务必打开 vendor/composer/autoload_*.php 文件,确认对应命名空间和路径已消失。










