composer install --no-dev 仅当 composer.lock 存在且由 --no-dev 生成时才生效;否则退化为 update 并安装 dev 包,或报错找不到 lock 文件。

直接运行 composer install --no-dev 就能跳过开发依赖,只装 require 里的包——但前提是 composer.lock 文件存在且完整。
为什么 composer install --no-dev 有时不生效
常见现象:执行后仍安装了 phpunit、friendsofphp/php-cs-fixer 等 dev 包,或报错 Could not find a composer.lock file。
-
composer.lock缺失时,install会退化为update行为,无视--no-dev,重新解析全部依赖(含require-dev) - 本地
composer.json被改过,但没运行composer update --no-dev更新 lock 文件,导致 lock 中仍记录着 dev 包的版本信息 - 某些包在
require和require-dev中重复声明(比如symfony/var-dumper),Composer 优先按require解析,--no-dev无法排除
composer install --no-dev 的正确触发条件
这个命令不是“开关”,而是一个约束条件:它只在 lock 文件已明确区分生产/开发依赖的前提下才起效。
- 必须已有
composer.lock,且该文件由带--no-dev的update或上一次正确的install生成 - CI/CD 部署脚本中,应确保先
git pull拉取最新 lock 文件,再执行composer install --no-dev --prefer-dist - 若项目从未在 CI 上跑过,首次部署前需在干净环境中手动运行:
composer update --no-dev --lock
,生成合规 lock 文件再提交
替代方案:更稳妥的生产环境安装流程
比起依赖 install --no-dev 的状态一致性,直接控制依赖来源更可靠。
- 用
COMPOSER_DEV=false环境变量强制禁用 dev 包(比命令行参数更底层,连 autoload-dev 都不加载):COMPOSER_DEV=false composer install --prefer-dist
- 删掉
require-dev字段再 install(适合完全隔离场景,但会丢失本地开发便利性) - 在
composer.json中使用config.platform锁定 PHP 版本等,避免因平台差异导致 dev 包意外被启用
真正容易被忽略的是 lock 文件的“信任链”:它不像代码那样显式修改就能生效,而是靠生成它的那一次命令决定内容。只要 lock 里存了 dev 包,--no-dev 就只是个无效装饰。










