答案是某些包仅提供 source(Git 仓库)而缺失 dist(zip/tar 包),故必须加 --prefer-source 才能完整安装;否则 Composer 因找不到 dist 而跳过或留空 vendor 目录。

如果 composer install 后发现某些包的 vendor/ 目录里只有 composer.json、没有 PHP 文件,大概率是该包只提供了 source(Git 仓库),没提供 dist(zip/tar 包)。这时加 --prefer-source 不是“可选优化”,而是唯一能装成功的办法。
为什么有些包必须用 --prefer-source 才能装全?
Composer 默认走 dist,但不是所有包都配了 dist 字段。私有仓库、内部 fork、或未正确发布到 Packagist 的包,常只声明 "source": { "type": "git", "url": "...", "reference": "..." },而 "dist" 为空或缺失。这种情况下,不加 --prefer-source,Composer 就会卡在“找不到 dist 包”或静默跳过——vendor 里只剩空目录或仅有 composer.json。
- 执行
composer show vendor/package,输出里若没出现source行,说明该包根本不支持--prefer-source - 若出现
source行但仍是空目录,检查 Git URL 是否可访问(比如是否指向git@而非https://,且本地没配 SSH key) - 部分包在
composer.json中显式禁用了dist(如"dist": false),此时--prefer-dist会直接失败
已安装的包怎么从 dist 切成 source?
composer install --prefer-source 对已存在的包无效——Composer 会跳过。必须触发重装:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 删掉对应包:
rm -rf vendor/vendor-name/package-name - 再运行
composer install --prefer-source或composer update vendor-name/package-name --prefer-source - 不要只删
vendor/下的代码却不删composer.lock:lock 文件记录了上次安装类型,不清 lock,Composer 仍按旧方式还原
CI 环境下用 --prefer-source 的实际代价
它会让每次构建都重新 git clone,而不是复用缓存的 zip 包。后果很实在:
- PHP Alpine 镜像默认没装
git,临时apk add git是补救,但不如一开始就用--prefer-dist - GitHub 对未认证请求有速率限制,CI 机器若没配
GITHUB_TOKEN或 SSH key,clone可能失败或超时 - 私有 GitLab/GitHub Enterprise 地址若用了自签名证书,还得额外配置
git config --global http.sslVerify false(不推荐)或导入 CA
只想让某一个包走 source,其他照常 dist
不用全局开 --prefer-source,也不用改 preferred-install 配置:
- 新包:直接
composer require vendor/package --prefer-source - 已有包:先删
vendor/vendor/package,再composer update vendor/package --prefer-source - 确认生效:进
vendor/vendor/package目录,执行git rev-parse --git-dir,返回.git说明是 source 模式
最易被忽略的一点:哪怕你只对一个包用了 --prefer-source,只要它依赖的子包也只提供 source,那些子包也会被连带 clone——你得一并确保它们的 Git 地址可访问、权限够用,否则整个安装链会在中途断掉。

















