生产环境必须加--no-dev,否则phpunit等dev包必然进入vendor,导致体积膨胀、性能下降、调试入口暴露甚至Fatal error;其生效前提是composer.lock中无dev包记录,需先用composer update --no-dev --lock生成合规lock文件。

生产环境必须加 --no-dev,否则 phpunit、phpstan、symfony/var-dumper 会进 vendor/——不是“可能出问题”,是必然体积膨胀、启动变慢、暴露调试入口,甚至因扩展缺失直接 Fatal error。
composer install --no-dev 真的能跳过 require-dev 吗?
能,但前提是 composer.lock 里没存 dev 包的记录。如果上次是 composer update(没加 --no-dev)生成的 lock 文件,那它里面就含 packages-dev 条目;此时 composer install --no-dev 才真正跳过安装。
-
composer install永远只读 lock 文件,不改它;composer update才会重写 lock - CI 构建前应先跑
composer update --no-dev --lock,并提交新composer.lock - 本地开发用完整安装:
composer install;部署镜像必须用composer install --no-dev --optimize-autoloader - 漏掉
--no-dev,vendor/里就会多出 PHPUnit、Faker、PHPStan,且它们的 PSR-4 映射仍会写入vendor/autoload.php
autoload-dev 配了但测试类还是找不到?
autoload-dev 不是“配了就生效”,它只在 composer install 或 composer update 且未加 --no-dev 时,才被合并进 vendor/autoload.php。手动改了配置后不执行命令,等于白改。
- 改完
autoload-dev必须运行composer dump-autoload --dev(dump-autoload默认不处理 dev 部分) -
autoload-dev必须放在composer.json顶层,键名严格为autoload-dev(大小写、缩进、嵌套都错不得) - 常见错误:把
"Tests\": "tests/"写成"Tests": "tests/"(缺反斜杠),Composer 解析失败且静默忽略 - 检查是否生效:看
vendor/composer/autoload_dev.php是否存在,以及vendor/autoload.php末尾是否包含require __DIR__ . '/autoload_dev.php';
Docker 和 CI 里怎么防踩坑?
不能靠环境变量“默认生效”,--no-dev 必须显式、硬编码、不可省略。缓存 key 不带语义,一次污染,全盘皆崩。
- Dockerfile 中写死:
RUN composer install --no-dev --optimize-autoloader,别用ENV COMPOSER_NO_DEV=1 - GitHub Actions 缓存 key 必须体现 dev 状态:
composer-${{ hashFiles('**/composer.lock') }}--no-dev - CI 测试阶段用完整安装:
composer install && ./vendor/bin/phpunit;部署阶段切回--no-dev - 验证是否真隔离:部署后进容器执行
ls vendor/ | grep -E 'phpunit|mockery|phpstan',有输出即失败
最常被忽略的是 autoload-dev 和 require-dev 的耦合关系:删了 require-dev 里的包,却不清理 autoload-dev 的映射,或者测试类被某处生产代码硬引用(比如 CI 脚本里写了 new TestsFooTest()),这时候再严格的 --no-dev 也救不了。


















