--prefer-dist 是 Composer 优先使用预构建压缩包而非 Git 克隆的选项,适用于无 Git 环境、CI/CD 加速及只读文件系统;它不强制 dist,仅在包提供 dist URL 时生效,否则自动回退 source。

什么是 --prefer-dist?它不是强制,而是“优先选压缩包”
--prefer-dist 告诉 Composer:只要某个包提供了预构建的压缩包(比如 monolog/monolog-3.5.0.zip),就别去克隆 Git 仓库了,直接下这个 ZIP 解压完事。它不禁止 source,只是“能 dist 就 dist”。如果包没配 dist URL(例如私有 GitLab 项目没开启 archive 功能),加了也白加,Composer 会自动 fallback 到 source。
什么时候必须用 --prefer-dist?三类典型场景
它真正起作用的地方,是那些「不能有 Git、不能慢、不能乱改」的环境:
- 服务器上没装
git—— 比如某些精简版 Docker 镜像或老旧生产机,--prefer-dist是唯一能跑通composer install的方式 - CI/CD 流水线里追求构建速度 —— 克隆一个带历史的仓库可能要 10 秒,下载解压一个 ZIP 只要 2 秒,且 CDN 缓存命中率高
- 部署到只读文件系统或容器临时目录 ——
vendor/xxx/.git不但没用,还可能触发权限错误或占用额外空间
--prefer-dist 和 "preferred-install": {"*": "dist"} 有什么区别?
命令行加 --prefer-dist 是一次性的;而写进 composer.json 的 "preferred-install" 是长期策略。后者更灵活:
-
"preferred-install": {"*": "dist"}→ 全局默认走 dist -
"preferred-install": {"myorg/private-sdk": "source", "*": "dist"}→ 只有这个包必须源码,其余照常 dist - 注意:它不会覆盖
composer.lock里已记录的安装方式 —— 如果 lock 文件里某包之前是 source 安装的,install仍会沿用,除非加--force-reinstall
常见踩坑点:为什么加了 --prefer-dist 还在报 git 错?
这不是参数失效,而是你没切断所有 source 路径:
- 某个包在
composer.json里写了"dev-main"或"dev-feature/x"—— 这类开发版通常不发 dist,Composer 只能 clone - 用了
path类型仓库(比如本地开发联动)—— 它天生就是 source 模式,--prefer-dist对它无效 - 私有包配置了
"type": "git"但没提供"dist"字段 —— 即使加了参数,Composer 也找不到压缩包地址 - 缓存被污染或 lock 文件版本不匹配 —— 比如本地生成的 lock 记的是 source hash,离线部署时却想靠 dist 缓存,校验直接失败
最稳的做法:生产部署前,先在有网环境跑一遍 composer install --prefer-dist --no-dev,确认 vendor 里没出现任何 .git 目录,再把 composer.lock 和缓存一起打包带走。










