composer install --no-dev 仅跳过安装 require-dev 包,但不清理 composer.lock 中已存在的 dev 依赖;若 lock 文件含 dev 包,则仍会安装——需配合 --no-dev 首次生成 clean lock 或用 update --no-dev 彻底移除。

只安装生产环境依赖,就用 composer install --no-dev,但它的行为取决于当前 composer.lock 文件是否已存在、是否由带 --dev 的命令生成,以及你有没有手动删过 dev 相关字段 —— 很多“没生效”的问题其实出在这儿。
为什么 composer install --no-dev 有时像没加参数?
根本原因:这个参数只控制「是否安装 require-dev 里的包」,但它不修改 vendor/autoload.php 的自动加载逻辑,也不影响 composer.lock 中已记录的 dev 包。如果你之前运行过 composer install(无参数)或 composer update,composer.lock 里很可能已经存了 require-dev 的包信息,此时再加 --no-dev,Composer 会照着 lock 文件“精准还原”,包括那些 dev 包 —— 它以为你在复现之前的环境。
- ✅ 正确前提:lock 文件本身不含
require-dev包(比如由composer install --no-dev或 CI 环境首次生成) - ❌ 常见误操作:本地开发完 push 到服务器,直接在服务器跑
--no-dev,但 lock 文件是开发机生成的,含 dev 包 - ? 解决办法:上线前在 CI 或部署脚本中先运行
composer install --no-dev --prefer-dist,确保 lock 文件干净
composer install --no-dev 和 composer update --no-dev 的本质区别
前者是“按 lock 文件安装”,后者是“重算依赖并写入 lock”。如果你的目标是彻底剔除 dev 依赖,install 只能帮你跳过安装,而 update --no-dev 才能真正从 lock 文件里删掉它们 —— 但代价是可能触发版本变动,不适合线上直接执行。
-
composer install --no-dev:安全、快,前提是 lock 文件可信且不含 dev 包 -
composer update --no-dev:会删掉 lock 中所有require-dev条目,并重新解析非 dev 依赖树,适合构建新环境或清理历史残留 - ⚠️ 注意:
update --no-dev不会自动删掉composer.json里的require-dev字段,只是让它在 lock 中失效
CI/CD 部署时怎么确保 100% 不装 dev 包?
别只靠一个参数。真实部署链路里,要组合使用几个关键点,否则容易漏掉 autoload 或缓存导致的“假干净”。
- 部署前清空
vendor/和composer.lock(如果允许),然后用composer install --no-dev --prefer-dist --optimize-autoloader - 加上
--optimize-autoloader:它会生成扁平化 classmap,同时自动跳过autoload-dev配置,避免测试类被意外加载 - 检查
vendor/autoload.php是否还包含autoload-dev路径 —— 如果有,说明上一次 install 没走--no-dev,或者用了旧 lock - 在 Docker 构建中,建议把
composer install --no-dev放进 final stage,且不挂载本地 vendor 缓存(避免污染)
最常被忽略的一点:哪怕命令执行成功,也要验证 vendor/bin/ 下没有 phpunit、phpcs 这类典型 dev 工具 —— 因为有些包会把 bin 脚本放在 require 里,而非 require-dev,这时候 --no-dev 就管不住了。










