必须显式声明每个私有 Git 仓库为 vcs 类型并按优先级顺序写入 repositories 数组;vcs 是唯一支持自动探测 Git/SVN/Hg 中 composer.json 的类型,写错类型(如 git)或省略 type 会导致 Composer 静默忽略该源,即使 URL 和认证正确,也会报“Could not find package”。

必须显式声明每个私有 Git 仓库为 vcs 类型,并按优先级顺序写入 repositories 数组;不声明、类型写错或顺序放反,composer require 就会直接报 Could not find package。
为什么 vcs 类型不能省略或写成 git
Composer 不识别 "type": "git" 这种写法——它只认 vcs。填错类型会导致 Composer 完全忽略该仓库,哪怕 URL 正确、认证无误,也不会尝试 clone 或解析 composer.json。
-
vcs是唯一支持自动探测 Git/SVN/Hg 仓库中composer.json的类型 - URL 必须是可直接
git clone的地址(如https://gitlab.example.com/team/utils.git或git@gitlab.example.com:team/utils.git) - 如果用 HTTPS 带 token,格式必须是
https://token:x-oauth-basic@gitlab.example.com/team/utils.git,否则 401 - SSH 地址依赖系统级 SSH 配置(
~/.ssh/id_rsa),不是 Composer 自己管认证
多个私有 Git 仓库怎么排顺序?
Composer 按 repositories 数组从上到下扫描,**命中即停**。同名包(比如都叫 myorg/core)只取第一个匹配的源,后面的完全不查。
- 把高优先级、临时 fork 或开发中版本放在最前面
- 不要把
{"type": "composer", "url": "https://packagist.org"}放在开头——它会屏蔽所有同名私有包 - 想彻底禁用 Packagist,必须加
{"packagist.org": false}到repositories数组里,不能只删掉它 - 数组必须是索引形式(
[{...}, {...}]),写成对象({"repo1": {...}})会导致只生效最后一个
为什么 composer require myorg/mylib 还是走 Packagist?
因为包名没对上,或者私有仓库根目录的 composer.json 里 "name" 字段和你 require 的字符串不完全一致(大小写、斜杠方向、vendor 名拼写)。
- Git 仓库必须在根目录放
composer.json,且其中"name"必须等于myorg/mylib - 如果分支叫
main,要装它得写composer require myorg/mylib:dev-main,不是dev-master - 默认 stability 是
stable,未打 tag 的dev-版本需显式设"minimum-stability": "dev"或带@dev后缀 - 运行
composer clear-cache再试——旧缓存可能记住了 Packagist 返回的 404
auth.json 配错了会怎样?
auth.json 只负责认证,不参与包发现。但它配错会导致 composer update 卡住或报 401/403,尤其在 CI 环境里容易漏配。
- 文件权限必须是
600(Linux/macOS),否则 Composer 直接忽略 - GitHub:用
"github.com": {"oauth-token": "ghp_..."} - GitLab:用
"http-basic": {"gitlab.example.com": {"username": "token", "password": ""}}(password 可为空,部分版本要求非空) - 路径必须正确:项目级
auth.json在项目根目录;全局级在$COMPOSER_HOME/auth.json - CI 中建议统一用项目级
auth.json,避免因开发者本地配置不同导致构建结果不一致
最常被忽略的一点:即使所有配置都对了,composer.lock 仍会锁死旧的 dist URL 和 commit hash。改了仓库地址或切换了 vcs 源后,composer install 不会重新解析——必须 composer update --lock 或删 lock 文件重装。


















