Composer install --no-dev 是标准部署做法,它跳过 require-dev 仅按 lock 文件安装生产依赖,需配合 --optimize-autoloader 和 --classmap-authoritative,并确保 lock 文件无 dev 条目且 autoload 配置已清理。

Composer 默认会安装 require 和 require-dev 里的所有包,但上线部署时你确实不该装 phpunit、mockery 或 larastan 这类开发依赖——它们不仅浪费磁盘和网络,还可能引入安全风险或 autoload 冲突。
为什么 composer install --no-dev 是标准做法
这个命令会跳过 require-dev 区块,只加载 require 中声明的生产依赖,并且仅当 composer.lock 存在时才生效。它不是“忽略 dev”,而是“严格按 lock 文件还原生产环境”。如果你没提交 composer.lock,或者本地 composer.json 和 lock 不一致,--no-dev 可能导致行为异常。
- CI/CD 流水线里必须加
--no-dev,否则测试工具可能意外进入生产镜像 - PHP-FPM 容器启动前应执行
composer install --no-dev --optimize-autoloader - 若项目用
autoload-dev注册了测试辅助类,这些类在--no-dev下不会被自动加载,运行时调用会直接报Class not found
composer install vs composer update 的 --no-dev 行为差异
composer install --no-dev 是安全的、可重复的操作;而 composer update --no-dev 会重新解析 require 并更新 lock 文件,但不会触碰 require-dev 的版本约束——这容易造成 lock 文件里残留旧的 dev 包信息,后续再执行 composer install(不带 --no-dev)时仍可能装上它们。
- 永远不要在生产环境跑
composer update,无论是否加--no-dev -
composer update --no-dev适合在开发机上清理掉 dev 依赖后生成纯生产 lock,但需手动确认 lock 文件中已无require-dev相关条目 - 检查 lock 是否干净:用
grep -A 5 "require-dev" composer.lock,输出为空才真正干净
autoload 优化与 --no-dev 的配合要点
--no-dev 本身不改变 autoloading 行为,但它让 --optimize-autoloader(-o)更有效:因为去掉 dev 类后,生成的 vendor/composer/autoload_classmap.php 更小,PHP require 路径查找更快。
- 推荐组合:
composer install --no-dev --optimize-autoloader --classmap-authoritative -
--classmap-authoritative告诉 autoloader “所有类都在 classmap 里,别再去文件系统找”,这对无autoload-dev的场景尤其稳妥 - 如果项目用了
psr-4映射到tests/目录(比如 Laravel 的"Tests\": "tests/"),即使加了--no-dev,这些映射仍保留在 autoloader 中——得手动删掉或用"autoload-dev"拆分出去
真正容易被忽略的是:很多团队把 --no-dev 当成“防错开关”,却没同步清理 autoload 配置或验证 lock 文件内容。一旦某次 composer update 意外写入了 dev 包版本,下次 deploy 就可能悄悄带上它们。


















