Composer install --no-dev有时无效的根本原因是composer.lock文件已记录dev包,导致即使加参数仍会安装;需配合--optimize-autoloader、清理autoload-dev映射及确保lock文件纯净。

composer install --no-dev 为什么有时没效果
根本不是参数失效,而是 composer.lock 文件里已经存了 packages-dev。只要 lock 文件里有 "phpunit/phpunit" 这类条目,composer install --no-dev 就会照装——它只跳过安装动作,不改 lock 结构。
常见翻车场景:
- Docker 构建时复用旧
vendor/缓存,或没清掉旧 lock 文件 - 本地开发执行过
composer update(没加--no-dev),导致 lock 被污染 - CI 脚本先跑了一次无参
composer install,再跑--no-dev,后者不会自动清理前者装的包
验证方式:grep -A5 '"packages-dev"' composer.lock | head -20,输出非空就说明 lock 已含 dev 包。
生产镜像构建必须固化 --no-dev 参数
Dockerfile 里写 RUN composer install 是高危操作,哪怕设置了 COMPOSER_NO_DEV=1 也不可靠——该环境变量在 Composer 2.9.6 中已被弃用,行为不稳定。
正确写法(带优化):
RUN composer install --no-dev --optimize-autoloader --no-scripts
关键点:
-
--no-dev:跳过require-dev所有包,vendor/下不会出现phpunit/、mockery/等目录 -
--optimize-autoloader:生成 classmap,避免运行时 PSR-4 查找开销 -
--no-scripts:防止执行post-install-cmd里的测试或 lint 命令
注意:--no-dev 不影响 config.platform,所以仍需配好 "ext-xdebug": "3.0.0" 防依赖冲突。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
autoload-dev 残留会导致 Class not found 假阳性
--no-dev 只控制包是否安装,不控制 autoloader 是否注册路径。只要 composer.json 里还存在 autoload-dev 块,composer dump-autoload 就会把 "Tests\": "tests/" 这类映射写进 vendor/autoload.php。
结果就是:class_exists('PHPUnitFrameworkTestCase') 返回 true,但实际 vendor/phpunit/phpunit 根本不存在——运行时一 new 就报错。
解决方法只有两个:
- 删掉
composer.json中的autoload-dev块,再跑composer dump-autoload - 保留
autoload-dev,但每次部署后补一句composer dump-autoload --no-dev
漏掉这步,vendor/autoload.php 里就会残留测试路径映射,autoload 冲突风险极高。
require-dev 里的包真能“只在开发用”吗
不能靠字段名判断。有些包表面在 require-dev,实际被主逻辑间接调用,比如:
-
symfony/var-dumper放在require-dev,但控制器里写了dump($data)—— debug 模式下线上请求一触发就 500 -
monolog/monolog同时被require和require-dev引用,它仍会被安装,属于正常行为
判断一个包是否纯 dev 依赖,得查代码:
-
grep -r "PHPUnit\Framework\TestCase" src/—— 如果命中,它就不是 dev-only -
grep -r "dump(" src/或grep -r "var_dump" src/ - 运行
composer show --dev,对每个包执行grep -r "vendor/name" src/ tests/
最危险的不是误装,是误删:一旦运行时代码真用了 dev 包里的类,--no-dev 就会直接崩。

















