artifact仓库是本地或内网的压缩包集合目录,Composer直接从中读取.zip/.tar.gz并解压安装;它不走HTTP源逻辑,要求包名与内部composer.json的name严格一致、压缩包平铺于同一级目录、url配置不能以/结尾。

什么是artifact仓库,它和packagist有什么区别
artifact仓库不是远程源,而是本地或内网的“压缩包集合目录”,Composer会直接从指定文件夹里找.zip或.tar.gz包,解压后当作包安装。它不走composer.json里的repositories常规HTTP源逻辑,也不需要包本身有composer.json在根目录——只要压缩包里带就行。
常见错误现象:Package your-vendor/your-package could not be found in any version,其实包文件就在本地,只是配置没对上路径或结构。
- 必须把所有zip包放在同一级目录下,不能嵌套子文件夹
- 包名(
vendor/name)必须和压缩包内部composer.json里声明的name字段完全一致,包括大小写 - 压缩包内路径无所谓,但
composer.json必须在顶层(解压后直接能看见)
怎么配置composer.json启用artifact源
在项目根目录的composer.json中添加repositories段,类型设为artifact,值是包含zip包的**绝对路径或相对路径**(推荐绝对路径,避免CI或不同人执行时出错)。
示例配置:
{
"repositories": [
{
"type": "artifact",
"url": "/path/to/my-zips/"
}
],
"require": {
"acme/utils": "dev-main"
}
}
注意点:
-
url末尾**不能加/**,否则某些版本Composer会拼出//导致路径解析失败 - 如果用相对路径(如
"url": "zips/"),它相对于composer.json位置,不是当前工作目录 - artifact源优先级低于packagist.org,除非显式禁用默认源:
"packagist.org": false
安装时为什么找不到zip包里的版本
Composer不会自动扫描zip包内容并提取版本号,它依赖压缩包内部composer.json里的version字段,或者更常见的是靠文件名推断——比如acme-utils-1.2.3.zip会被识别为acme/utils的1.2.3版。
容易踩的坑:
- zip包名不含版本号?Composer就只认
dev-main或dev-develop这类分支别名,不认latest或stable -
composer.json里写了"version": "1.2.3",但包名写成"acme/utils",而require里写的是"acme/utils-dev"→ 名字对不上,直接忽略 - 用了
composer install --no-cache,但本地zip被更新过,旧缓存还在 → 清掉~/.composer/cache/对应key再试
artifact和path仓库混用时要注意什么
artifact适合分发已构建好的、不可变的zip包;path仓库("type": "path")适合本地开发调试未打包的代码。两者可共存,但行为完全不同:path会软链接或复制整个目录,artifact只解压一次,之后就当普通包用。
关键差异:
- artifact包一旦安装,后续
composer update不会重新拉取zip,除非你删了vendor/重装,或改了composer.lock里对应条目的dist.url - path仓库每次update都会检查源目录变动,artifact不会
- 如果你在CI里用artifact,确保zip包在构建机上路径固定,且权限允许读取
最常被忽略的一点:artifact不支持composer require交互式添加新包——你得先放好zip,再手动改composer.json的require,再composer update。它不是“即装即用”的本地源。


















