私有包需显式配置仓库源并满足元数据要求:在根项目composer.json中声明repositories,私有包必须含name、type、autoload及version或tag;Git仓库需打语义化版本tag或设branch-alias。

私有包不是“上传到 Packagist”就能用的
Composer 本身不托管包,它只负责按 composer.json 里的源去拉代码。所谓“私有包”,本质是你自己控制代码存放位置 + 让 Composer 知道怎么找它。常见错误是:写完 composer.json 就直接 composer require,结果报错 Could not find package xxx at any version——因为默认只查 Packagist.org,你的私有仓库根本没告诉它。
必须显式配置仓库源,且类型要匹配实际存放方式:
- Git 仓库(推荐):用
"type": "vcs",支持 GitHub、GitLab、自建 Git(如 Gitee、Gitolite),Composer 会自动探测分支和 tag - 本地路径(仅开发调试):用
"type": "path",指向本地文件夹,注意路径必须是绝对路径或相对于composer.json的相对路径 - 私有 Packagist 兼容服务(如 Satis、Private Packagist):用
"type": "composer",需额外部署服务
composer.json 必须包含这 4 个字段才被识别为可安装包
很多人把项目根目录的 composer.json 改一改就当私有包用,结果 require 失败。关键在于:Composer 只认满足最低元数据要求的包定义。缺一不可:
-
"name":格式必须是vendor/name(如myorg/utils),不能带下划线或大写字母;这个 name 是你在require时写的字符串 -
"version"或"autoload":二者至少其一。如果没写version,Composer 会尝试从 Git tag 推断;但若连autoload都没配,就算装上了也没法use类 -
"type":建议设为"library"(默认值),避免被当成project导致安装行为异常 -
"autoload":至少配"psr-4"或"files",否则composer dump-autoload不会生成对应映射
示例最小可用配置:
{
"name": "myteam/logger",
"type": "library",
"autoload": {
"psr-4": { "MyTeam\Logger\": "src/" }
}
}
require 私有包时,必须在根项目 composer.json 里声明仓库
不是在私有包自己的 composer.json 里写,而是在你打算使用它的那个项目(比如 Laravel 应用)的 composer.json 顶层加 "repositories" 字段。漏掉这步,Composer 根本不会去你指定的 Git 地址找包。
常见错误写法:
- 把仓库配置写在私有包的
composer.json里(无效,Composer 不读依赖项的仓库配置) - 用了 HTTPS Git 地址但没配 SSH key,导致 clone 失败,报错
Failed to clone https://xxx.git - Git 仓库没打 tag,又没在
require时指定dev-main这类分支别名,结果提示No matching package found
正确做法(以 GitHub 私有库为例):
{
"repositories": [
{
"type": "vcs",
"url": "https://github.com/myteam/logger"
}
],
"require": {
"myteam/logger": "^1.0"
}
}
Git tag 和版本约束必须对得上,否则找不到安装版本
Composer 默认只认 Git tag 当作正式版本。如果你的私有包仓库里只有 main 分支,没打任何 tag,那么即使代码存在,composer require myteam/logger:^1.0 也会失败——因为 ^1.0 暗示要找 v1.x 的 tag。
解决方式有两种,选一个就行:
- 打符合语义化版本的 tag:
git tag -a v1.0.0 -m "release",然后git push --tags - 不用 tag,改用分支别名:在私有包的
composer.json里加"extra": {"branch-alias": {"dev-main": "1.0.x-dev"}},然后require时写"myteam/logger": "1.0.x-dev"
注意:dev-main 这种写法只在 "type": "vcs" 下有效,且每次更新需手动 composer update myteam/logger 拉最新提交,不适合生产环境稳定依赖。
私有包最难绷的点其实是权限和缓存:公司内网 Git 服务器没配好 OAuth 或 SSH,或者本地 Composer 缓存了旧的包信息,删了 vendor 和 composer.lock 还不行,得跑 composer clear-cache 才生效。这些细节不踩一遍,很难信。











