私有仓库必须显式声明为vcs类型,仅写URL无效;正确配置为{"type":"vcs","url":"https://gitlab.example.com/myorg/mylib.git"},且URL须指向裸仓库并含.git后缀。

私有仓库必须显式声明为 VCS 类型,不能只靠 URL
直接在 composer.json 里写 "https://gitlab.example.com/myorg/mylib.git" 是无效的。Composer 不会自动识别这是 Git 仓库,它默认只从 Packagist 或配置的 Composer 类型仓库拉包。不声明类型,composer require 会报 Could not find a matching version of package myorg/mylib。
正确做法是在 repositories 段显式添加:
{
"repositories": [
{
"type": "vcs",
"url": "https://gitlab.example.com/myorg/mylib.git"
}
]
}
-
type: "vcs"是强制要求,支持git、svn、hg,但绝大多数用git - URL 必须指向裸仓库(bare repo),不能是带 Web UI 的路径(如
.../mylib/-/tree/main) - 若仓库需要认证,得配
http-basic或用 SSH key(git@...格式),否则 clone 失败
多项目共享时,版本约束必须用稳定分支或语义化标签
私有库没发到 Packagist,Composer 默认只认 dev-main 这类开发分支,不会自动解析 1.0.0 这样的 tag —— 除非你明确告诉它哪些分支可当版本用。
在私有库自己的 composer.json 里加 minimum-stability 和 prefer-stable 不起作用;真正生效的是主项目的 config 段:
{
"config": {
"minimum-stability": "stable",
"prefer-stable": true
}
}
- 否则
composer require myorg/mylib可能装上dev-main,而别人composer install时却因 stability 不一致失败 - 更稳妥的做法:私有库打
v1.2.0标签,并在主项目中写死"myorg/mylib": "^1.2",避免隐式依赖dev-分支 - CI 构建中若用
--no-interaction,未锁定版本会导致行为不可控
子项目用 Git subtree 同步时,composer install 必须隔离 vendor 和 autoload
把私有库以 git subtree add 拉进主项目子目录(如 lib/mylib)后,直接在主项目根目录运行 composer install,会把它装进主项目的 vendor/,导致命名空间冲突、Class not found、CI 构建失败——这不是 bug,是 Composer 本身没有“作用域”概念。
必须在子目录下单独操作:
- 进入
lib/mylib,执行composer install --no-autoloader --no-scripts - 在
lib/mylib/composer.json的config段指定"vendor-dir": "vendor"(路径相对于该子目录) - 其
autoload必须用唯一 PSR-4 前缀,比如"MyOrg\MyLib\": "src/",绝不能和主项目共用App\ - 主项目的
composer.json中,autoload和autoload-dev绝对不能包含lib/mylib/src/路径
团队协作中最容易忽略的点:composer.lock 不跨项目复用
多个项目都 require 同一个私有库,但各自生成的 composer.lock 文件互不兼容。A 项目锁了 myorg/mylib 的 v1.2.0,B 项目却锁了 dev-main 的 commit hash,哪怕源码完全一样,composer install 行为也会不同。
解决方法不是共享 lock 文件,而是统一源头:
- 私有库自身要发布带完整
composer.lock的 release(尤其含require-dev工具链时) - 主项目只管
require版本号,不提交私有库的 lock 文件到主项目仓库 - CI 中用
composer install --no-interaction --ignore-platform-reqs前,先确认 PHP 版本与私有库config.platform.php一致
真正难处理的从来不是怎么拉代码,而是当私有库改了 autoload 映射、又没同步更新所有下游项目的 composer dump-autoload 时,那个深夜三点的 Class not found 错误。


















