生产环境部署必须使用 composer install --no-dev --optimize-autoloader 跳过 require-dev 包安装并优化自动加载,同时确保 COMPOSER_NO_DEV 环境变量未启用,并通过检查 vendor/ 目录、composer.lock 和 composer show --dev 验证生效。

生产环境部署时,composer install 默认会安装 require-dev 中的包(如 PHPUnit、PHPStan),这不仅增大部署体积、拖慢安装速度,还可能引入安全风险或运行时冲突。必须显式禁用 dev 依赖安装。
使用 --no-dev 参数跳过 require-dev 包
这是最直接、最可靠的方式,适用于所有 Composer 版本(包括 2.x 和 1.x):
composer install --no-dev --optimize-autoloader
关键点:
-
--no-dev会完全忽略require-dev字段,不解析、不下载、不安装任何 dev 包 -
--optimize-autoloader(可选但强烈推荐):生成扁平化、类映射式的vendor/autoload.php,提升加载性能,且不依赖文件系统扫描 - 该参数只影响当前命令执行,不影响
composer.json或锁文件内容
确保 COMPOSER_NO_DEV 环境变量未被意外启用
Composer 会读取环境变量 COMPOSER_NO_DEV,若其值为 1、true 或非空字符串,等效于全局启用了 --no-dev。这在 CI/CD 流水线中容易被误设:
检查是否被覆盖:
echo $COMPOSER_NO_DEV
临时禁用(调试用):
COMPOSER_NO_DEV=0 composer install
常见踩坑场景:
- Docker 构建时在
Dockerfile中写了ENV COMPOSER_NO_DEV=1,但后续又想本地复现 dev 安装行为,却忘了清理环境变量 - 某些部署脚本用
export COMPOSER_NO_DEV=1后未及时 unset,导致后续手动调试失败
验证是否真的没装 dev 包:检查 vendor/ 和 composer.lock
仅靠命令参数不够,需实锤验证:
- 执行后检查
vendor/目录下是否存在典型 dev 包,例如:vendor/phpunit/phpunit、vendor/nunomaduro/collision—— 若存在,说明--no-dev未生效 - 打开
composer.lock,搜索"require-dev"对应的包名,确认它们的dist或source字段未出现在packages列表中(注意:lock 文件仍会保留require-dev的原始声明,但实际安装的包只来自packages数组) - 运行
composer show --dev,若提示 “No dependencies installed for development”,说明成功隔离
真正要注意的是:有些项目把“工具类”包(如 symfony/console)同时写在 require 和 require-dev 里,或者用了 config.platform 模拟 PHP 版本导致依赖解析异常——这种情况下,--no-dev 能屏蔽 dev 块,但无法解决逻辑层面的误配。得回头改 composer.json,而不是加更多参数。










