composer install --no-dev是生产环境必须加的参数,它强制跳过require-dev包及其传递依赖、autoload-dev命名空间和@dev脚本,否则phpunit等开发包会进入vendor导致运行时报错或安装卡死。

composer install --no-dev 是必须加的,不是可选
生产环境或 CI 构建时漏掉 --no-dev,phpunit/phpunit、larastan/larastan、barryvdh/laravel-debugbar 就真会进 vendor/。这不是“多装几个包而已”,而是直接导致:部署超时、Class 'PHPUnit\Framework\TestCase' not found 运行时报错、甚至因 PHP 版本不兼容卡死安装。
根本原因在于 Composer 不区分“开发”还是“生产”——它只认 composer.json 里 require-dev 写了什么,就装什么。你本地跑 composer install 没问题,是因为你有 PHPUnit;线上没装,却照样被拉进来,就崩。
-
--no-dev不只是跳过require-dev列表里的包,还跳过它们的传递依赖(比如sebastian/exporter)、autoload-dev命名空间(Tests\不注册)、以及标记为@dev的脚本(如post-autoload-dump里调的phpstan) - 如果
composer.lock是上次用composer update(没加--no-dev)生成的,那即使你加了--no-dev,friendsofphp/php-cs-fixer仍可能出现在vendor/—— 因为 lock 文件里已经记了它的版本 - 正确流程是:CI 首次构建前,在干净环境运行
composer update --no-dev --lock,提交新 lock;后续部署才用composer install --no-dev --optimize-autoloader
为什么 --no-dev 不删 tests/ 目录?
--no-dev 完全不影响你项目根目录下的 tests/、phpunit.xml 或第三方包里的 vendor/somevendor/lib/tests。它只控制“是否安装 dev 包”和“是否注册 dev autoloader”,不碰源码文件结构。
真正让测试文件不进线上环境,得从源头控制:
- 在项目根目录加
.gitattributes,写入:/tests export-ignore、/phpunit.xml export-ignore—— GitHub/GitLab ZIP 下载、git archive、Packagist dist 构建都会跳过 - 在
composer.json根级加"archive": {"exclude": ["/tests", "/phpunit.xml"]},仅对 Packagist 自动构建生效,且需打新 tag - 若依赖的第三方库自带大量测试文件(如某些 SDK),只能靠
post-install-cmd清理:"rm -rf vendor/somevendor/somelib/tests"(Windows 用rd /s /q),但注意:这破坏vendor完整性,下次composer update可能恢复
CI/CD 里怎么组合参数才安全?
单加 --no-dev 还不够。CI 构建镜像或部署脚本里,应固定使用这一组:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
composer install --no-dev --no-scripts --optimize-autoloader-
--no-scripts跳过所有post-install-cmd类脚本(如php artisan config:clear),避免因环境缺失报错中断;也防止自动清缓存干扰正在运行的服务 -
--optimize-autoloader生成vendor/composer/autoload_classmap.php,提升类加载性能,尤其适合无 OPcache 的容器环境 - 别混用
composer update和install:部署阶段永远用install,确保还原 lock 状态;update只应在开发机或 CI 的依赖更新流水线里执行
--ignore-platform-reqs 不是 --no-dev 的替代方案
有人误以为加 --ignore-platform-reqs 就能绕过测试依赖,这是错的。这个参数只跳过三类检查:php 版本、ext- 扩展(如 ext-redis)、lib- 系统库(如 lib-curl),完全不干预 require-dev 的安装逻辑。
更危险的是:它会让 Composer 装上 Laravel Octane 却不校验 ext-swoole 是否存在,结果 php artisan octane:start 运行时直接报 Class 'Swoole\Http\Server' not found。
如果真要跳平台检查,优先用精准参数:
-
--ignore-platform-req=php(只跳 PHP 版本) -
--ignore-platform-req=ext-gd(只跳 GD 扩展) - 多个可叠加:
--ignore-platform-req=php --ignore-platform-req=ext-igbinary,值必须大小写严格匹配
真正容易被忽略的点是:这些参数对 composer create-project 同样生效,且必须显式传参——--no-interaction 或 --quiet 完全无效。

















