--prefer-dist能减少vendor体积,因为它绕过Git克隆,直接下载预构建归档,天然不含.git、tests、examples等冗余目录,主流包dist版比source小40%~70%。

为什么--prefer-dist能减少vendor/体积
--prefer-dist本身不删除文件,但它让 Composer 绕过 Git 克隆流程,直接下载 Packagist 提供的预构建归档(如 monolog/monolog-3.5.0.tar.gz)。这类归档由包作者发布时生成,天然不含:.git/目录、tests/(除非显式打包)、examples/、bin/(部分 SDK 除外)、历史提交和未合并分支。
- 不是所有包都“精简”——有些作者把
phpunit测试用例也塞进 dist 归档里,但绝大多数主流包(laravel/framework、symfony/*、guzzlehttp/guzzle)dist 版本比 source 小 40%~70% -
du -sh vendor/* | sort -hr | head -5能快速定位“体积大户”,进去看有没有.git或tests/目录,有就说明没走 dist - 如果某个包的
installed.json里"source"字段存在且非空,那它就是 source 模式安装的,--prefer-dist没生效
--prefer-dist在哪些情况下会失效
加了参数却还是看到 .git/ 目录?不是参数错了,而是环境或配置阻断了 dist 路径:
- 项目中用了
"dev-main"、"dev-feature/x"这类开发版约束——Packagist 不为 dev 分支生成 dist,Composer 只能 fallback 到 source -
composer.json里配置了"prefer-source": true或"preferred-install": {"*": "source"},会覆盖--prefer-dist - 私有包仓库(如内网 GitLab)没启用 archive 功能,或者
repositories配置里漏写了"dist"字段 -
composer.lock文件里已记录该包为 source 安装方式,composer install默认复用 lock 中的安装策略,不会重新选 dist - 环境变量
COMPOSER_PREFER_SOURCE=1已设置,它优先级高于命令行参数
如何确认当前安装是否真的走了 dist
别只看命令有没有加,要验证结果是否符合预期:
- 进入任意依赖目录(如
vendor/monolog/monolog),执行ls -A | grep git—— 输出为空才说明没.git/ - 查看
vendor/composer/installed.json,搜索该包名,检查"source"字段是否为{}或不存在;若存在且含"type": "git",那就是 source 模式 - 运行
composer show monolog/monolog,看输出里source行是否显示type : git;如果是,说明当前安装方式是 source - 在 CI 日志里搜
Downloading @#@#@#@#@#@#@#@#@#@0—— 出现这条代表成功走了 dist;如果看到Cloning <git-url></git-url>,那就失败了
生产部署前必须做的三件事
--prefer-dist只是起点,单靠它不能保证干净、轻量、可复现:
- 删除
composer.lock和vendor/后,用完整命令重装:composer install --prefer-dist --no-dev --optimize-autoloader --quiet - 检查镜像源是否生效:
composer config repo.packagist应返回国内地址(如@#@#@#@#@#@#@#@#@#@1),否则 dist 包可能拉不到 - 验证私有包:如果用了自定义
repositories,确保每个包的dist字段在composer show -a输出中可见,否则它根本不会被考虑
真正容易被忽略的是 lock 文件的“惯性”——它会固守上次安装方式,哪怕你改了全局配置或加了 --prefer-dist。想彻底切换,就得清 lock + 清 vendor + 显式指定参数。











