composer install --no-dev 不能直接用于生产环境,因 require-dev 中常含运行时依赖(如 sebastian/environment、symfony/var-dumper),移除会导致 class not found;需先试装再检查 autoload,必要时迁移至 require。

为什么 composer install --no-dev 不能直接用在生产环境?
因为很多项目在 composer.json 的 require-dev 里塞了实际运行时依赖,比如 phpunit 自带的 sebastian/environment 被某些 SDK 暗戳戳 require;更常见的是 symfony/var-dumper 被日志组件或调试中间件间接引用,删掉就报 Class not found。
实操建议:
- 先跑
composer install --no-dev,再用composer dump-autoload -a触发一次自动加载检查,看是否报错 - 如果失败,用
composer depends(需 Composer 2.5+)查谁在偷偷依赖它 - 临时方案:把真需要的包从
require-dev移到require,哪怕只是“运行时可选” - CI/CD 中别只信
--no-dev,加一行php -d display_errors=1 -m | grep opcache确认没因扩展缺失导致 autoload 失败
composer install 时怎么跳过文档、测试、示例这些“视觉垃圾”?
Composer 默认不删源码里的 docs/、tests/、examples/,但它们占 vendor 体积常超 30%——尤其 monolog/monolog 或 guzzlehttp/guzzle 这类大包。
实操建议:
- 全局启用
composer config -g discard-changes true,避免 patch 冲突干扰清理逻辑 - 在项目根目录加
.gitattributes,写入:* export-ignore /docs export-ignore /tests export-ignore /examples export-ignore /phpunit.xml export-ignore
,再执行composer install --prefer-dist --no-dev - 注意:部分包(如
laravel/framework)把stubs/放进 dist zip,删了会导致php artisan vendor:publish找不到模板 - 验证是否生效:装完后
du -sh vendor/* | sort -hr | head -5对比前后大小
vendor 里那些 .git 目录和 composer.lock 是不是能删?
不能删 composer.lock,它是安装确定性的唯一依据;但 .git 目录确实可以清——前提是没用 --prefer-source 安装,否则删了下次 update 会重 clone。
实操建议:
- 确认当前全是 dist 安装:
grep -r '"source"' vendor/*/composer/installers.json 2>/dev/null || echo "ok",无输出才安全 - 删
.git:用find vendor -name ".git" -type d -prune -exec rm -rf {} + - 顺手删掉
vendor/composer/installed.json以外的冗余元数据(如vendor/composer/ClassLoader.php是生成的,但vendor/composer/autoload_classmap.php等文件可被dump-autoload重建) - 警告:Docker 构建中若用
COPY . .再composer install,.git可能来自宿主机,得在 COPY 前用.dockerignore过滤
PHP 8.2+ 下 opcache.preload 能不能替代 vendor 压缩?
不能。preload 是把 PHP 文件编译后载入内存,不减少磁盘体积,反而可能因预加载全部 vendor/autoload.php 依赖树,让首次请求更慢;且 preload 文件必须绝对路径硬编码,vendor 一更新就得重生成,CI 流水线容易漏。
实操建议:
- 只对核心框架类(如
Laravel的Application、Container)做 selective preload,用opcache_compile_file()手动控制范围 - 别把
vendor/autoload.php整个 preload——它会递归加载所有 psr-4 映射,包括你根本不用的tests/下的 mock 类 - 真正省空间的组合是:
--no-dev+.gitattributes export-ignore+ 清理.git+ 用composer archive打包发布版(它默认 exclude 所有非必要文件)
最麻烦的其实是私有包——它们往往没配 archive 规则,也没发 dist zip,只能靠 repositories + package type 硬指定 dist URL,否则每次 install 都 source clone,体积和时间全崩。










