path仓库必须写在项目根composer.json的repositories数组里,且需为合法json数组结构;url用相对或绝对路径(禁用file://、~/等),本地包composer.json中name须为vendor/name格式、version建议设dev-main,require时必须用dev-分支名而非版本约束。

path仓库必须写在项目根composer.json的repositories数组里
很多人把repositories配置塞进require、config甚至extra字段,结果完全不生效。Composer只认根级repositories数组,且必须是合法JSON数组结构。
常见错误现象:执行composer require vendor/name时仍报Could not find package,但composer config --list里根本看不到你配的源——说明配置压根没被加载。
-
repositories必须是数组,哪怕只有一个源也要写成[{ "type": "path", "url": "./packages/my-utils" }] -
url值必须是相对路径(推荐)或绝对路径,不能带file://前缀,也不能用~/或$HOME这类变量 - Windows下路径分隔符用
/或\都行,但统一用/更稳妥(如"./packages/my-utils")
本地包的composer.json必须有合法name和version
Composer扫描path仓库时,会逐个读取目标目录下的composer.json,只要语法错误、缺name、或name格式不合规(比如没带/),就直接跳过,不报错也不提示。
使用场景:你改完本地包代码后运行composer update,发现vendor里还是旧版本——大概率是本地包的composer.json里name写成了my-utils,而项目require里写的是acme/my-utils,两边不匹配。
-
name必须包含vendor名,格式为vendor/name(如acme/my-utils),不能省略斜杠 -
version字段不是必须的,但建议设为"dev-main"或"dev-master",方便require时对齐 - 本地包目录必须已执行过
git init并至少有一个commit,否则Composer拒绝识别该路径
require时必须用dev-分支名,不能用*或^约束
path仓库下的包,Composer默认忽略version字段,只按Git HEAD所在分支解析。如果你本地包在main分支,但项目require写的是"acme/my-utils": "^1.0",就会失败。
错误信息典型表现:Could not find a matching version of package acme/my-utils,其实包就在隔壁文件夹,只是版本约束不匹配。
- require字段必须显式写
"acme/my-utils": "dev-main"(或"dev-develop"等实际分支名) - 不要用
"*",它在path源下会被解释为“任意稳定版”,而本地包没有tag,自然找不到 - 执行更新时优先用
composer update acme/my-utils,避免全量update触发其他依赖意外升级
生产部署时path仓库会直接中断构建
CI/CD流程跑composer install时,如果repositories里还留着"./packages/my-utils"这种路径,而构建机上根本不存在该目录,Composer会立即报错退出,不会fallback到Packagist或其他源。
这不是bug,是Composer的明确性设计:它要求你清楚知道每个依赖来自哪里。所以开发时便利的配置,恰恰是上线前最危险的隐患。
- 绝不能把开发专用的path配置提交到Git主干分支
- 推荐用
composer config repositories.<name> --unset</name>在CI脚本开头动态移除,或用Studio工具管理(它不修改composer.json) - 确保所有本地包都有对应的远程源(GitHub + Packagist),生产环境只依赖这些可公开访问的地址











