生产环境必须用 composer install --no-dev --optimize-autoloader:前者跳过 phpunit 等 dev 依赖安装与 autoload-dev 注册,杜绝体积膨胀、安全风险及 class not found;后者生成精简 classmap,将类加载耗时从 0.8ms 降至 0.05ms,二者缺一不可。

生产环境不加 --no-dev,就别谈体积优化——它不是“锦上添花”,而是防止 vendor 膨胀、autoload 崩盘、线上 Class not found 的底线操作。
为什么 composer install 默认会把 phpunit 装进线上环境
因为 Composer 没有“环境感知”逻辑,默认按开发场景处理:只要 composer.json 里 require-dev 区块存在,它就会拉取所有包(如 phpunit、phpstan、roave/security-advisories),连带加载 autoload-dev 映射。这些类文件根本不会在运行时被调用,却占着几十 MB 空间、拖慢 autoload 解析、甚至触发内存溢出。
常见错误现象:
-
Class 'PhpCsFixerFinder' not found—— 你没写任何 CS Fixer 代码,但误装了friendsofphp/php-cs-fixer,它的 autoload 规则被载入后,ClassLoader 尝试解析未用到的类路径,报错延迟到运行时才暴露 - Laravel 报
Class AppProvidersTestHelperServiceProvider not found—— 这个服务提供者只在某个 dev 包中注册,而那个包根本没装,类文件物理不存在
验证方式:部署后立刻执行 ls -la vendor/phpunit,如果目录存在,说明 --no-dev 没生效。
composer install --no-dev --optimize-autoloader 到底做了什么
这不是两个独立优化,而是一体动作:--no-dev 决定“装什么”,--optimize-autoloader 决定“怎么加载”。前者跳过 require-dev 及其 autoload-dev 映射;后者将 PSR-4 路径转为 classmap 查找,并剔除动态 require 逻辑。
实操要点:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 必须显式传参,不能只靠
"config": {"optimize-autoloader": true}—— 这个配置只是开关,不触发实际生成 - 执行后检查
vendor/composer/autoload_classmap.php是否显著缩小;若仍很大,说明有包在autoload(非 dev)段硬编码了过多路径 - 对比命令:
composer install --optimize-autoloadervscomposer install --no-dev --optimize-autoloader,后者生成的 classmap 通常小 30%~60%
为什么加了 --no-dev 还是报 Class not found
问题不在参数失效,而在代码依赖了 dev-only 的东西:比如 new TestsHelpersStub()、在 AppServiceProvider::boot() 中绑定了只存在于 dev 包里的接口实现、或误把 symfony/var-dumper 放进了 require-dev 却在生产代码里用了 dump()。
排查步骤:
- 检查
composer.json是否含"autoload-dev": {"psr-4": {"Tests\": "tests/"}}—— 如果有,且没加--no-dev,这些路径会进autoload_classmap.php,白占内存 - 运行
composer install --no-dev后,确认vendor/composer/autoload_static.php里没有Tests开头的映射项 - 若仍报错,用
grep -r "Tests\Helper" vendor/composer/看是否残留未清理的 autoload 规则
CI/CD 流水线里漏掉 --no-dev 的真实后果
本地开发能跑通,线上炸锅,90% 是因为 CI 脚本写了 composer install 而非 composer install --no-dev --optimize-autoloader。这不是兼容性问题,是物理缺失:dev 包根本没下载,它的类文件压根不存在于 vendor/ 里。
更隐蔽的风险:
- Docker 构建后镜像体积暴涨 ——
vendor/多出几十 MB,突破 AWS Lambda 250MB 解压限制 - Serverless 冷启动变慢 30% 以上 —— 因为本地 macOS/Windows 执行
composer install会混入平台路径、.git目录、测试文件,而 Lambda 实际运行在 Amazon Linux 上,autoload 逻辑错配 - 误信
"discard-changes": true能自动清理 —— 它只对后续安装生效,已有vendor不会自动删.git,必须先rm -rf vendor再重装
真正关键的不是“删得够不够狠”,而是“从安装那一刻起,就只让运行时必需的东西落地”。--no-dev 是起点,不是终点;后面所有瘦身动作(如 archive.excludes、--remove-vcs)都建立在这个前提之上。










