本地包必须用 dev-* 分支别名(如 dev-main),不可用 1.0.x-dev 或 ^1.0;path 仓库需在根级 repositories 配置相对路径并启用 "symlink": true,更新代码后须运行 composer update my-vendor/my-package。

本地包必须用 dev-* 分支别名,不能写 1.0.x-dev 或 ^1.0
Composer 对 path 类型仓库不做语义化版本解析,只认 dev- 开头的分支别名。你本地包的 composer.json 里写了 "version": "dev-main",require 时就必须写 "my-vendor/my-package": "dev-main"。写成 "1.0.x-dev" 或 "^1.0" 都会失败——不是报错,而是直接 fallback 到 Packagist 找,然后提示 Could not find package。
常见错误包括:
-
dev-master但本地包根本没master分支(比如默认是main) -
dev-feature/auth但分支名实际是feature/auth(漏了dev-前缀) - 分支名含大写字母或特殊符号,而
name字段大小写不一致(acme/Utils≠acme/utils)
repositories 配置必须在主项目 composer.json 根级,且 url 是相对路径
repositories 不能塞进 require、autoload 或 config 里,必须和它们平级。否则 Composer 完全忽略。
url 必须是相对于主项目 composer.json 的路径,例如 "./packages/my-pkg"。以下写法全部无效:
-
"/home/user/my-pkg"(绝对路径) -
"file:///path/to/my-pkg"(带file://) -
"../my-pkg/"(结尾带/)
正确示例:
"repositories": [
{
"type": "path",
"url": "./packages/my-pkg"
}
]
必须显式启用 symlink 并验证链接是否生效
Linux/macOS 默认尝试创建符号链接,Windows 默认复制文件。你不加 "options": {"symlink": true},就等于没开调试模式。
配置要这样写:
"repositories": [
{
"type": "path",
"url": "./packages/my-pkg",
"options": {
"symlink": true
}
}
]
验证方式:
- 进
vendor/my-vendor/my-package,运行ls -l—— 应该看到指向../packages/my-pkg的软链 - 改
./packages/my-pkg/src/Helper.php,立刻在 vendor 里cat同一文件,内容应同步 - Windows 用户务必以管理员权限运行终端,否则
symlink创建失败且无提示
更新本地包代码后,必须运行 composer update my-vendor/my-package
改完本地包源码,vendor 下的链接不会自动刷新。别删 vendor/ 再 install——那会把代码复制进去,失去“改即生效”的意义。
正确做法只有这一种:
- 执行
composer update my-vendor/my-package(推荐,只重映射该包) - 或者
composer dump-autoload(仅刷新自动加载,不重建链接)
容易忽略的关键点:Composer 的 path 映射是一次性硬链接,不是监听式热更新。你以为在跑最新代码,其实可能还在用上次 update 时的快照。每次改完本地包,都要手动触发一次 update。


















