composer require --dev仅将包写入require-dev字段并安装,不自动配置autoload-dev或修改require;线上报Class not found是因代码越界调用dev类,且部署未加--no-dev导致类缺失。

composer require --dev 命令本身不决定“是否只在开发环境生效”,它只是把包写进 composer.json 的 require-dev 字段——真正起隔离作用的,是后续部署时是否加 --no-dev。
为什么加了 --dev 还是线上报 Class not found
这不是命令没起作用,而是代码越界调用了 dev 包里的类。典型表现:
- 在
AppServiceProvider或中间件里直接用了symfony/var-dumper的dump() -
config/app.php里写了'providers' => [BarryvdhDebugbarServiceProvider::class],但没套if (app()->environment('local')) - 迁移文件
up()方法中用了DoctrineDBALTypesTypes,而该包只在require-dev里
这些情况,哪怕你本地 composer require --dev 写得再准,线上执行 composer install --no-dev 后,类就根本不存在于 vendor/ 和 autoloader map 中。
composer require --dev 实际改什么、不改什么
它只做两件事:修改 composer.json 的 require-dev 字段,并立即安装(除非加 --no-install)。其他都不碰:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 不会动
require字段,也不会删已有包 - 不会自动加
autoload-dev配置 —— 如果包自带测试类(如phpunit/phpunit的src/Framework/TestCase.php),它们默认不被 autoload,除非你手动在composer.json里配了"autoload-dev": {"psr-4": {"PHPUnit\": "vendor/phpunit/phpunit/src/"}} - 如果包已存在
require-dev中,再跑composer require --dev foo/bar不会升级版本;必须显式指定版本号,或改用composer update foo/bar
CI/CD 里 --no-dev 漏了会怎样
不是“多装几个包”那么简单:
- 镜像体积多出 40–60MB(
phpunit+phpstan+mockery等依赖树) -
vendor/autoload.php会加载更多类,启动变慢 - 调试工具如
barryvdh/laravel-debugbar可能暴露/_debugbar入口,引发安全审计失败 - 某些 dev 包(如旧版
php-cs-fixer)带 runtime 依赖冲突,导致composer install在生产环境失败
CI 流水线要分阶段:测试阶段用 composer install(不加 --no-dev),部署阶段必须用 composer install --no-dev --optimize-autoloader。
怎么确认一个包该放 require 还是 require-dev
只看一个事实:这个包的类或函数,是否会在 APP_ENV=production 下被业务代码直接执行?
-
guzzlehttp/guzzle→ 放require,因为控制器里$client->get()是运行时必需 -
phpunit/phpunit→ 放require-dev,因为./vendor/bin/phpunit是 CLI 工具,不参与 HTTP 请求生命周期 -
doctrine/dbal→ 看用途:如果只用于php artisan migrate,那它其实是运行时依赖(迁移要执行),应放require;如果只用于本地 schema diff,则放require-dev
最危险的边界是那些“看起来像工具,实则被 runtime 调用”的包,比如 laravel/sail(纯 CLI,require-dev)和 laravel/framework(永远只能在 require)——名字相似,语义完全不同。

















