Composer的path仓库是绕过网络与认证、直接链接本地目录的开发机制,必须在根composer.json的repositories数组中以相对路径声明,且require需用dev-分支名匹配本地包name,改代码后须执行composer update而非install。

Composer 的 path 仓库不是“配置私有仓库”,而是绕过仓库机制、直接链接本地目录——它不走网络,也不需要认证,但只在本地开发阶段有效,CI/CD 中必然失效。
path 仓库必须写在项目根 composer.json 的 repositories 数组里
Composer 只读取顶层 repositories 字段,且必须是合法 JSON 数组。写错位置(比如塞进 config、extra 或子目录下的 composer.json)等于没配,不会报错,也不会提示。
-
repositories必须是数组:哪怕只有一个源,也要写成[{"type":"path","url":"./packages/my-utils"}] - 不能写成对象:
"repositories": {"type":"path",...}会被完全忽略 - 不能嵌套:放在
require或config.repositories里无效
url 必须是相对路径,且目标目录含合法 composer.json
Composer 不支持 file://、~/、$HOME 或绝对路径(Windows 上尤其容易静默失败)。路径必须指向一个**目录**,该目录下必须存在语法正确、含 name 字段的 composer.json。
- 正确写法:
"url": "../my-utils"、"url": "./packages/api-client"(开头必须有./或../) - 错误写法:
"url": "/home/user/pkg"、"url": "my-utils"(缺上级路径)、"url": "../my-utils/composer.json"(指向文件而非目录) - 目标
composer.json必须有name字段,格式为vendor/name(如"acme/utils"),大小写和斜杠都不能错 - 该目录必须已执行过
git init并至少有一个 commit,否则 Composer 拒绝加载
require 时版本约束必须用 dev- 分支名,不能用版本号
path 类型仓库下,Composer 忽略 version 字段,只根据 Git HEAD 所在分支解析版本。因此 require 时不能写 "1.2.0" 或 "^1.0",必须用 dev-main 这类分支别名。
- 若本地包在
main分支,require 写"acme/utils": "dev-main" - 若本地包没有打 tag,就别写
"1.2.0";写错分支名(如要求dev-main但实际只有master分支)会导致Could not find package - 如果项目设了
"minimum-stability": "dev",还需加@dev后缀:"acme/utils": "dev-main@dev"
composer install 不生效,必须用 composer update 或 composer require
composer install 只按 composer.lock 安装,完全跳过 repositories 配置。哪怕你刚加完 path 源,执行 install 也毫无反应。
- 首次引入本地包:运行
composer require acme/utils:dev-main - 刷新已有本地包链接:删掉
composer.lock后运行composer update,或更安全地运行composer update acme/utils - 改完本地包代码后,需在主项目中运行
composer dump-autoload刷新自动加载器 - 成功后
vendor/acme/utils是符号链接(Linux/macOS 可用ls -la验证),不是复制的文件
最常被忽略的一点:path 仓库之间无 fallback,同名包只取 repositories 数组中第一个匹配项;一旦顺序写反(比如 Packagist 放前面),本地包就永远找不到。


















