branch-alias必须写在被依赖包的composer.json的extra字段下,且目标分支需已推送并被索引;仅当require使用语义化版本(如"^2.0")时生效,搭配镜像源需同步更新composer.lock确保dist.url一致。

branch-alias 必须写在被依赖包的 composer.json 里
很多人把 branch-alias 加到自己项目的 composer.json,结果完全没用——它只对“被 require 的那个包”生效。比如 A 项目 require B 包,branch-alias 必须写在 B 包自己的 composer.json 中,且只能放在 extra 字段下。
常见错误配置:
- 写在根项目(A)里 → Composer 直接忽略
- 写成顶级字段
"branch-alias": {...}→ 不解析,无报错但无效 - 分支名拼错,比如 B 包实际是
dev-main,却配了"dev-master": "1.0.x-dev"→ 别名不触发
正确结构示例:
{
"name": "myorg/utils",
"extra": {
"branch-alias": {
"dev-main": "2.0.x-dev",
"dev-develop": "1.9.x-dev"
}
}
}
跨团队协作时,dev- 分支必须真实存在且已推送
别名生效的前提是:目标分支不仅存在于本地 Git,还必须已 git push origin main(或对应分支),且被 Packagist、私有 VCS 或 Satis 索引到。否则即使配置正确,Composer 仍会报 Could not find package 或 fallback 到其他版本。
尤其注意:
- CI/CD 构建机拉取的是远程仓库,不是你本地的未推送分支
- 私有 GitLab/GitHub 仓库需确保 token 权限足够读取该分支
- 如果用的是 SSH 地址(如
git@gitlab.example.com:acme/utils.git),构建机必须预置对应 SSH key - 分支名严格区分大小写:
dev-Main≠dev-main;含斜杠分支(如feature/login)必须写成dev-feature/login
require 方式决定别名是否参与解析
branch-alias 只在版本约束匹配时起作用。如果你直接写 "myorg/utils": "dev-main",Composer 就按字面拉取分支,不查别名;只有写成语义化约束(如 "^2.0" 或 "2.0.x-dev"),才会去查被依赖包的 branch-alias 映射。
所以跨团队联调时,建议统一约定:
- 开发阶段用
"myorg/utils": "^2.0"→ 触发别名,指向dev-main - 发布稳定版后,打 tag
v2.0.0,无需改 require 行,Composer 自动切到正式版本 - 避免混用:
"dev-main"和"^2.0"同时存在会导致行为不一致
镜像源和 lock 文件共同决定实际下载路径
别名解决的是“版本解析”,不解决“下载地址”。如果团队用了国内镜像(如阿里云),但 composer.lock 是 A 地成员生成的,里面 dist.url 还是 https://api.github.com/,B 地执行 composer install 时仍会直连 GitHub,绕过镜像。
因此首次切换别名或镜像时,必须:
- 删掉
composer.lock和vendor/ - 确认项目级
repositories已正确写入composer.json(不是全局 config) - 运行
composer install重新生成 lock 文件,确保dist.url域名与镜像源一致 - 提交新的
composer.lock到 Git,所有成员同步
这点在跨国团队中极易被忽略:别名映射成功了,但下载慢或失败,问题不在别名,而在 lock 文件里的 dist URL 没刷新。











