composer install --no-dev 不能单独用作部署命令,因为它不校验锁文件一致性、不清理已安装的开发依赖、也不阻止 autoload-dev 中类被意外加载,需配合 git clean、--optimize-autoloader、--no-scripts 等严格组合使用。

生产环境执行 composer install --no-dev 并不总是安全或足够——它只跳过 require-dev,但不校验锁文件一致性、不清理冗余包、也不阻止意外加载开发依赖。
为什么 composer install --no-dev 不能单独用作部署命令
这个命令只是「不安装」require-dev 里的包,但它默认仍会:读取 composer.lock(如果存在)、重装所有 require 包、保留已存在的 vendor/ 中的 dev 包(如果之前装过)、甚至可能因缓存或本地配置导致 --no-dev 被忽略。
-
composer.lock若被手动修改或生成于不同平台(如 Windows vs Linux),可能导致实际安装版本与预期不符 - 若之前运行过
composer install(无--no-dev),vendor/里可能残留phpunit、fakerphp/faker等包,--no-dev不会删它们 - 某些插件或脚本(如
composer-plugin-api)可能在autoload-dev中注册类,即使没 require,也可能被自动加载触发
真正安全的生产部署命令组合
必须强制锁定行为、清理残留、并验证环境一致性。推荐这组命令(按顺序执行):
-
git clean -xffd vendor/—— 彻底清空vendor/,避免旧包残留 composer install --no-dev --prefer-dist --optimize-autoloader --no-scripts-
--no-dev:跳过require-dev -
--prefer-dist:优先用压缩包而非 Git 克隆,更快更轻量 -
--optimize-autoloader:生成 classmap,提升class_exists()和自动加载性能 -
--no-scripts:禁用post-install-cmd等钩子,防止开发用脚本(如生成 mock、运行 lint)意外执行 - 上线前加一句
composer validate --strict,确保composer.json和composer.lock版本兼容且未被篡改
composer install --no-dev 在 CI/CD 流水线中的典型误用
很多 CI 脚本写成:composer install --no-dev && php artisan config:cache,看似干净,实则隐患明显:
- CI 环境常复用容器或缓存
vendor/,--no-dev无法保证上一次构建没留下symfony/var-dumper这类包 - 若
composer.lock没提交,或用了composer update生成的 lock 文件,生产环境实际装的可能是 dev 分支代码 -
php artisan config:cache会把.env配置固化进 PHP 字节码,但如果vendor/里混入了依赖vlucas/phpdotenv的调试工具,可能绕过环境隔离
最易被忽略的一点:Composer 的 --no-dev 不影响 autoload-dev 的 PSR-4 映射——只要类被加载(比如通过反射、测试辅助函数、或第三方包调用),哪怕没 require,也会触发 autoload,进而暴露开发专用类。真要杜绝,得配合 composer dump-autoload --no-dev 或在 autoload 段显式拆分命名空间。










