离线安装 composer 包的核心是使用 path 类型仓库:需在 composer.json 的 repositories 中声明本地目录路径,且该目录下必须有含 name 和 version 的有效 composer.json;再执行 composer require 指定匹配版本。

离线安装 Composer 包:核心是 path 仓库类型
Composer 本身不支持“下载 zip 后直接 install”的离线模式,但能用 path 类型仓库把本地目录当包源。关键不是“怎么装离线包”,而是“怎么让 Composer 认出你硬盘上的代码是合法包”。
常见错误现象:composer require vendor/name 报错 Could not find a matching version of package vendor/name,哪怕你已把代码解压到项目里——因为没告诉 Composer 去哪找它。
- 必须在
composer.json的repositories字段里显式声明一个path类型仓库,指向你的本地目录 - 该本地目录下必须有有效的
composer.json(含name、version等字段),不能只是源码文件夹 -
path值支持相对路径(如../my-local-package)和绝对路径(如/home/user/packages/my-pkg),但 Windows 下注意斜杠方向或用双反斜杠
通过本地路径安装包:两步走,缺一不可
光写 repositories 不够,还得执行 require 并指定版本约束。Composer 不会自动扫描所有本地路径,它只按你写的 name 和 version 去匹配 repositories 里注册的源。
使用场景:调试未发布的私有组件、复现线上 bug 时临时替换某依赖、无网络环境下的 CI 构建。
- 在项目根目录
composer.json中添加:
{
"repositories": [
{
"type": "path",
"url": "./packages/my-custom-lib"
}
]
}
- 然后运行:
composer require my-vendor/my-custom-lib:dev-main(注意版本号要和本地包composer.json里的version或分支名一致) - 如果本地包没有固定
version,用dev-{branch-name}(如dev-master);若用了"minimum-stability": "dev",则必须加@dev后缀,如my-vendor/my-custom-lib:dev-main@dev
path 仓库的坑:软链接、权限与更新逻辑
看似简单,但实际踩得最多的是路径解析和更新行为。Composer 默认把 path 包当作“可编辑源”,install 后会在 vendor/ 下创建符号链接(Linux/macOS)或复制(Windows),而不是拷贝一份静态副本。
性能影响:每次 composer install 都会检查本地路径是否存在、是否可读,失败则报错;兼容性上,老版本 Composer(
- 软链接失效常见于 Docker 容器内挂载路径变化,或 IDE 重命名了父目录——此时
vendor/下链接仍指向旧路径,composer update不会自动修复,需先rm -rf vendor/my-vendor/my-custom-lib - 本地包目录权限不足(尤其 macOS/Linux 上误用
sudo composer)会导致vendor/下链接属主错乱,后续普通用户操作失败 -
composer update my-vendor/my-custom-lib不会拉远程更新,而是重新软链接到当前本地路径内容——改了本地代码,不用 re-install,直接生效
替代方案:artifact 仓库适合真正离线分发
如果目标是把包打包成 zip 给其他机器用(比如内网服务器无外网),path 就不合适了。artifact 仓库才是为离线 zip 设计的,但它要求 zip 内部结构严格符合 Composer 包规范。
容易被忽略的一点:zip 文件必须解压后包含完整 composer.json,且顶层不能有多余文件夹(即 zip 打开后应直接看到 composer.json,而不是 my-pkg/composer.json)。
- 配置示例:
{
"repositories": [
{
"type": "artifact",
"url": "./packages/"
}
]
}
-
url是存放 zip 文件的**目录路径**,不是 zip 文件本身;Composer 会扫描该目录下所有.zip文件 - zip 文件名无关紧要,匹配靠内部
composer.json的name和version - 不支持子目录扫描,
./packages/subdir/里的 zip 不会被识别
真正在内网部署时,artifact 比 path 更可控——它生成的是静态副本,不会因源目录移动或删除而崩掉。










