生产环境必须加--no-dev,否则会安装phpunit、symfony/debug等开发包,导致暴露调试接口、Class not found错误、镜像膨胀及安全风险;它仅跳过require-dev安装,不自动禁用autoload-dev映射。

生产环境必须加 --no-dev,否则会把 phpunit、symfony/debug 这类开发包一起装上——不是“可能出问题”,是大概率直接暴露调试接口或引发 fatal error。
为什么 composer install 默认装 dev 依赖?
Composer 的设计逻辑是“本地开发优先”:只要没明确说不要,就全装。它不读 .env,也不看 APP_ENV,更不会自动识别 Docker 或 CI 环境。所以 composer install 在生产服务器上跑,和在你本机跑,行为完全一致——除非你加参数干预。
常见错误现象:
- 线上报
Class 'SymfonyComponentDebugDebug' not found,但代码里根本没用它——因为symfony/debug被装了,且某些旧版框架的启动逻辑会无条件尝试加载 - Docker 镜像体积比预期大 200MB,
vendor/里多出phpunit/、php-cs-fixer/整个目录 - 安全扫描告警:生产环境发现
roave/security-advisories被绕过,原因正是require-dev里的包触发了间接依赖升级
--no-dev 和 autoload-dev 是两回事
很多人以为加了 --no-dev 就万事大吉,结果上线后还是 Class not found。这是因为:
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
-
--no-dev只控制「是否安装 require-dev 里的包」,不影响autoload-dev配置本身 -
autoload-dev里的 PSR-4 映射(比如"Tests\": "tests/")只在composer install且未加--no-dev时写入vendor/autoload.php - 但如果你在生产代码里写了
new TestsFooTest(),哪怕没装包,也会因命名空间未注册而报错
所以关键不是“装不装”,而是“会不会被 autoload”。检查点:
- 所有放在
autoload-dev下的路径,对应类不能出现在生产执行链路中 -
composer dump-autoload --dev才会刷新 dev 映射;只跑dump-autoload不生效 - 命名空间末尾必须带反斜杠,比如
"AppConfigDev\": "config/dev/",少一个就解析失败
Docker 和 CI 里怎么写才不出错?
别依赖环境变量自动切换,COMPOSER_DEV_MODE=0 几乎没人用,也难调试。直接写死命令最可靠:
- Dockerfile 构建阶段:
RUN composer install --no-dev --optimize-autoloader --no-progress - CI 脚本(如 GitHub Actions):
composer install --no-dev --prefer-dist,加--prefer-dist避免源码克隆拖慢构建 - 如果项目用了平台配置(如线上 PHP 8.1,本地 8.2),必须在
composer.json里写死:"php": "8.1.0",不能写^8.1 - 绝对不要搞
composer-prod.json替换主文件——composer.lock会和开发环境不一致,导致“本地能跑,线上报错”
最容易被忽略的一点:autoload-dev 的路径必须真实存在,且不能和 autoload 下的路径重叠。Composer 不校验,但 phpunit 找不到测试类时,只会静默失败,而不是报错提示。

















