私有包能被安装的前提是require字段与私有包composer.json中name字段逐字符精确匹配,包括大小写、连字符、斜杠位置等;常见错误如"MyOrg/utils"与"myorg/utils"不匹配导致Could not find package。

composer.json 的 require 字段必须精确匹配私有包 name
私有包能被安装的前提,是 Composer 在解析依赖时能把它和 require 里的字符串严格对上。这不是模糊匹配,而是逐字符比对——大小写、连字符、斜杠位置全算在内。
常见错误现象:执行 composer install 报 Could not find package myorg/utils,但你确认仓库地址没错、网络通、认证也通过了。问题大概率出在这里。
- 私有包自己的
composer.json中"name"是"MyOrg/utils",而你在主项目中写了"myorg/utils"→ 不匹配 - 私有包
name是"company-name/logger",但require写成"company_name/logger"或"company/name/logger"→ 不匹配 - Git 仓库 URL 是
https://gitlab.example.com/group/subgroup/pkg.git,但 Composer 推断的默认包名是"group/subgroup-pkg"(不是路径直译),得靠私有包自己声明name来覆盖
satis.json 中 require 和 require-all 的行为差异
require-all: true 会把所有扫描到的 VCS 仓库里所有 tagged/branched 的包全收进来,适合小团队快速起步;但一旦仓库变多、分支变杂,packages.json 体积暴涨,composer update 解析变慢,甚至触发内存溢出。
更可控的做法是显式 require:
{
"require": {
"acme/logging": "1.2.*",
"acme/auth": "dev-main",
"acme/utils": "^3.0"
}
}
注意点:
-
require里的版本约束必须和私有包自身composer.json中的version字段或 Git tag 一致;如果包没打 tag,dev-main这类开发分支引用才有效 -
require-all和require不能共存,Satis 会报错退出 - 运行
php bin/satis build satis.json web/后,生成的packages.json里只会出现require列出的包,其他一概不收录
私有包的版本发布必须靠 Git tag 或明确分支
Composer 本身不“发布”版本,它只读取 Git 仓库的 tag 或分支名来解析版本号。Satis 也是基于这个机制做索引的。
所以你不能指望改完代码 push 一下就自动更新线上依赖。必须主动管理:
- 正式发布走语义化版本:用
git tag v2.1.0 -m "release",然后 push tag:git push --tags - 主干开发用
dev-main(假设默认分支叫main);若分支名是develop,就得写"acme/pkg": "dev-develop" - 不要在私有包里写
"version": "2.1.0"字段 —— Composer 会忽略它,只认 Git 元数据 - Satis 构建时默认跳过带
-dev后缀的 tag(如v2.1.0-dev),除非配置"skip-dev": false
composer.lock 锁定的是 dist URL,不是 Git 地址
当你用 Satis 搭建私有仓库并配置了 archive 段(比如 tar 包托管在 CDN),composer install 实际下载的是 dist.url 对应的压缩包,而不是去 Git 服务器 clone。这点影响很大:
- 如果 Satis 配置了
"archive": {"format": "tar", "prefix-url": "https://cdn.example.org"},构建后每个包的packages.json里会多出dist字段,指向 CDN 上的 tar 包 -
composer.lock会记录这个dist.url和dist.shasum,下次 install 直接下 tar,不碰 Git —— 这是加速关键,但也意味着:Git 仓库删了 tag、CDN 文件被清空,composer install就会失败 - 调试时可用
composer show acme/pkg --all查看当前解析到的dist和source信息,确认走的是哪条路径
最易被忽略的一点:Satis 构建生成的静态文件必须部署到 Web 可访问路径,且 packages.json 要能被直接 HTTP GET 到;否则 Composer 根本不会尝试读取你的私有源,而是静默 fallback 到 packagist.org。


















