composer不支持环境感知装包,仅靠require与require-dev分离及安装时显式传参控制;默认安装含require-dev包,需--no-dev跳过,否则生产环境会误装phpunit等开发依赖。

Composer 本身不支持多环境配置,所谓“分环境”只是靠 require 和 require-dev 的职责划分 + 安装时显式传参控制,不是自动感知,更不是靠 APP_ENV 或文件名切换。
为什么 composer install 默认会装 phpunit 和 symfony/var-dumper
因为它们写在 require-dev 里,而 composer install 默认不加 --no-dev 就会照单全收——它根本不区分你是本地还是线上,只看 composer.lock 里有没有这些包的记录。
-
composer.lock文件里同时存有packages(require)和packages-dev(require-dev)两块内容 - 只要
packages-dev里有"name": "phpunit/phpunit",composer install就会解压进vendor/,除非你加--no-dev - 常见翻车点:
Dockerfile里只写RUN composer install,结果线上镜像里塞满phpunit/、sebastian/、phpstan/
composer install --no-dev 到底跳过了什么
它只跳过安装动作,但影响是连锁的:包不下载、目录不生成、autoload 映射不注册。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
-
vendor/下不会出现phpunit/phpunit、mockery/mockery等目录 -
vendor/composer/autoload_dev.php不会生成 —— 这是关键信号,漏删它会导致Class not found错误 -
autoload-dev里定义的 PSR-4 规则(如"Tests\": "tests/")不会被写入vendor/autoload.php - 但注意:
--no-dev不影响config.platform、scripts或其他字段,它只作用于依赖安装阶段
CI/CD 和 Docker 里怎么写才不出错
不能靠记忆、环境变量或默认行为,必须硬编码参数,否则缓存复用或镜像分层会把 dev 包带进生产环境。
-
Dockerfile中必须写死:RUN composer install --no-dev --optimize-autoloader --no-scripts,别用ENV COMPOSER_NO_DEV=1 - GitHub Actions / GitLab CI 的缓存 key 必须包含语义:
composer-${{ hashFiles('**/composer.lock') }}--no-dev - CI 测试阶段要用完整安装:
composer install && ./vendor/bin/phpunit;构建生产镜像那步,必须切回--no-dev,两者不能混用 - 部署前必须验证三件事:
ls vendor/ | grep -E 'phpunit|phpstan|var-dumper'(应无输出)、检查composer.lock中phpunit/phpunit只出现在packages-dev、确认vendor/composer/autoload_dev.php不存在
运行时代码引用 require-dev 包怎么办
这不是 Composer 的问题,是你把运行时依赖错误地放在了 require-dev 里。一旦用了 --no-dev,这些类就真的不存在。
- 检查方式:
grep -r "symfony/var-dumper" src/ app/ --include="*.php",如果命中,说明dump()被控制器或中间件直接调用,它就是运行时依赖,得挪到require -
topthink/think-trace、laravel/debugbar同理:只要在非tests/目录下被use或new,就不能放require-dev -
autoload-dev不是给 PHPUnit 用的,是给你自己的tests/目录用的;它不负责让 PHPUnit 跑起来——那是require-dev里包的事 - 真正需要隔离的是行为,不是包:用
if (getenv('APP_ENV') === 'dev')控制是否调用dump(),而不是指望 Composer 自动加载它
最常被忽略的点是:光加 --no-dev 不够,得确认 vendor/composer/autoload_dev.php 真的没生成,且 composer.lock 里 require-dev 包的记录没污染 packages 数组——否则命令再对,结果也是错的。










