Composer仓库优先级由repositories数组从上到下的顺序决定,首个匹配包即被采用,后续仓库包括packagist.org全被跳过;私有包需置数组最前,且须显式禁用packagist.org。

repositories 数组顺序决定包从哪拉,不是“多个源一起查”
Composer 查包是线性短路逻辑:从 repositories 数组第一个元素开始,匹配到同名包就立刻停止,后面所有仓库(包括 packagist.org)全被跳过。这不是 fallback,是硬性截断。
- 想让私有包
acme/logger优先走内部镜像,就得把它的源放在repositories最前面 - 如果两个源都声明了
acme/logger,只有数组靠前那个生效,后一个完全无效 - 写成对象形式(如
"my-mirror": { "type": "composer", ... })会导致只读最后一个——必须用索引数组:[{...}, {...}] - 全局配置(
~/.composer/config.json)里的repositories会被合并进来,但项目级composer.json中的永远优先
type 选 composer 还是 vcs,直接影响包发现方式
type: "composer" 指向一个完整索引服务(如 Satis、Private Packagist),能自动列出所有可用包;type: "vcs" 只针对单个 Git 仓库,且仅当你在 require 中明确写了该仓库里存在的包名时才触发拉取。
- 用
vcs时,Composer 不会扫描整个 Git 服务器,它只看那个仓库根目录下的composer.json文件内容 - 如果你
require了一个vcs仓库里没有声明的包(比如拼错名、或没在name字段写对),Composer 就当它不存在,不会继续往后找 - 多个
vcs源可以共存,但每个只负责自己 URL 对应的那个仓库,不共享元数据 - 不要混用
type: "vcs"和type: "package"去“补漏”,它们解析逻辑完全不同,容易导致Package not found
packagist.org 必须显式禁用,否则永远兜底
默认情况下,Composer 把 packagist.org 当作隐式最后一个仓库。即使你在 repositories 里写了十个私有源,只要没加 "packagist.org": false,同名包仍可能从官方源安装——尤其当你本地 lock 文件里记录的是旧版本时。
- 禁用语句必须是顶层字段,和
repositories同级:"packagist.org": false,不能塞进repositories里 - 禁用后,若你还想保留部分公开包能力,得手动把
packagist.org显式加回repositories数组末尾(type 为 composer,url 为https://packagist.org) - CI 环境中建议彻底禁用并显式添加镜像源(如阿里云),避免因开发者本地未禁用导致构建结果不一致
- 执行
composer install不会更新repositories配置的影响,必须跑composer update --lock或删掉composer.lock再重装
认证信息不能写在 composer.json 里,必须分离到 auth.json
HTTP Basic、OAuth Token、SSH 密钥等认证凭据严禁出现在 composer.json 中,否则极易泄露。Composer 会自动读取项目根目录或全局 auth.json 文件中的配置。
- VCS 类型(Git)推荐用 SSH:确保
git@gitlab.company.com:team/repo.git能本地git clone成功即可 - HTTPS + Token 方式要 URL 编码,例如:
"https://oauth2:abc123@gitlab.company.com/team/repo.git" - Composer 类型仓库用
http-basic字段,格式严格:{"http-basic": {"your-mirror.example.com": {"username": "u", "password": "p"}} - CI 中建议用环境变量注入 token,并通过
composer config http-basic.your-mirror.example.com $USER $TOKEN动态写入auth.json
composer.lock 里锁着旧源地址、auth.json 权限不对、或者以为改了 repositories 就能立刻生效——其实 install 不重解析元数据,非得 update --lock 不可。


















