Composer支持用"path"类型仓库本地开发包,需主项目composer.json中配置repositories指向含合法composer.json的本地目录,name须一致且优先于packagist;默认软链实现热更新,可配symlink:false关闭。

composer.json 里用 "path" 类型仓库引入本地包
直接在项目根目录的 composer.json 中声明一个本地路径仓库,就能让 Composer 把你正在写的包当作可安装源。这不是软链接,也不是 require-dev 的临时方案,而是正式支持的本地开发模式。
关键点是:必须把本地包目录里也存在合法的 composer.json(含 name、version),且项目主 composer.json 中的 repositories 要优先于 packagist。
{
"repositories": [
{
"type": "path",
"url": "../my-awesome-package"
}
],
"require": {
"vendor/my-awesome-package": "*"
}
}
-
url支持相对路径(推荐)或绝对路径,但不能以./开头(会报错Invalid repository type "path") -
vendor/my-awesome-package必须和本地包的composer.json中的name完全一致 - 如果本地包没打 tag,
"*"会匹配dev-main或dev-master—— 此时要确保其composer.json里有"minimum-stability": "dev"或显式设"stability": "dev"
为什么 composer install 不拉取本地代码?常见卡点
最常遇到的是明明配置了 path 仓库,但 composer install 仍从 packagist 下载远程版本。原因通常有三个:
- 本地包的
name和require中写的不一致(比如大小写、vendor 名拼错) -
repositories没放在主composer.json顶层,而是塞进了config或extra字段 - 本地包的
composer.json缺少version字段,且没设"minimum-stability": "dev",导致 Composer 认为它“不可用”
验证是否生效:运行 composer show vendor/my-awesome-package,输出中应包含 source: path ../my-awesome-package,而不是 source: git https://...。
path 仓库的符号链接行为与热更新逻辑
Composer 对 path 类型仓库默认启用符号链接(symlink),也就是说:vendor/vendor/my-awesome-package 实际是一个指向 ../my-awesome-package 的软链。这意味着:
- 你在本地包目录里改代码,项目里
require的地方立刻可见,无需composer update - 但如果你在项目里修改了
vendor/...下的文件,实际改的是源目录 —— 这不是 bug,是设计如此 - 如需关闭 symlink(例如某些 IDE 或部署环境不支持),加配置:
"config": { "preferred-install": "dist", "symlink": false }
注意:symlink: false 会让 Composer 每次 update 都复制一份完整文件,失去热更新能力,仅建议 CI 或只读场景使用。
多个本地包共存时的路径管理技巧
当同时开发 3–4 个相互依赖的包时,硬编码一堆 ../xxx 很容易出错。更稳的方式是用变量替代:
"repositories": [
{
"type": "path",
"url": "${env:PACKAGE_ROOT}/my-awesome-package"
},
{
"type": "path",
"url": "${env:PACKAGE_ROOT}/my-utils"
}
]
然后在 shell 中执行:PACKAGE_ROOT=/Users/me/projects composer install。这样既避免路径写死,又不用改 composer.json 就能切换开发环境。
真正麻烦的不是配置,而是忘记提交本地包的 composer.json 变更 —— 比如加了个新 require 却没同步到主项目,composer update 会静默忽略,直到 runtime 报 Class not found 才发现。










