path仓库必须写在依赖方的composer.json里,如apps/web/composer.json;url须为相对路径(如"../packages/utils"或"packages/*"),require版本必须匹配Git分支名(如"dev-main"),且目标包需有合法composer.json和正确name字段。

path仓库必须写在依赖方的composer.json里
Monorepo 里每个包(比如 packages/utils)自己有 composer.json,但它的路径声明不能放在这里——Composer 只读取执行命令时所在项目的根 composer.json。你得在 Laravel 应用(如 apps/web/composer.json)顶部加 repositories 块,否则 composer install 完全无视本地路径。
常见错误是把 repositories 放进 packages/utils/composer.json,这等于对空气说话。正确做法是:
-
url必须是相对路径,例如"../packages/utils"或通配"packages/*"(支持 glob) - 不能用
~/、绝对路径或 Windows 风格反斜杠(\),一律用正斜杠/ - 目标目录下必须存在合法的
composer.json,且含name字段(如"acme/utils"),否则报No valid composer.json was found
require 版本号必须匹配 Git 分支名,不是 package version
用 path 类型仓库时,Composer 不看目标包 composer.json 里的 version 字段,而是强制以当前 Git 分支名为版本依据。如果你的 packages/utils 在 main 分支,require 就得写 "acme/utils": "dev-main";写成 "1.0.0" 或 "*" 会直接失败,报错:Could not find package acme/utils at version *。
注意:
- Git 默认分支现在是
main,不是master;改过默认分支的,dev-main就不能硬套 - 不要加
-dev后缀(如dev-main-dev),那是 Composer 1.x 的旧写法,2.4+ 会忽略或报错 - 目标包如果还没任何 commit(空仓库),也会触发
No valid composer.json错误,哪怕路径完全正确
软链接生成后,autoload 不自动更新
执行 composer install 或 composer update acme/utils 后,vendor/acme/utils 会变成指向 ../packages/utils 的符号链接,但 PSR-4 自动加载映射不会自动重载。Laravel 下常出现 Class not found,尤其自定义 Artisan 命令或 Service Provider。
解决办法只有两个:
- 手动运行
composer dump-autoload(推荐,在应用目录下执行) - 删掉
vendor/和composer.lock重新composer install(适合结构大改后)
别指望 composer update 自动刷新 autoload —— 它只管依赖图,不碰自动加载缓存。
多个子包共存时,通配路径和 name 冲突要小心
想一次性引入所有 packages/ 下的包,可以用 "url": "packages/*",但前提是每个子包的 composer.json 中 name 字段互不重复,且符合 Composer 包命名规范(小写字母、短横线、点,不能有下划线或空格)。
容易踩的坑:
- 两个包都叫
myorg/core,Composer 会随机选一个,不报错但行为不可控 - 某个包
name写成MyOrg/Core(含大写或斜杠),会导致 autoload 失败或安装中断 - 通配路径不支持嵌套(如
"packages/**/src"),只认一级子目录
真正麻烦的点不在配置本身,而在于团队协作时:有人改了本地包的分支名但没同步更新 require 版本,或者忘了 dump-autoload 就提 PR,CI 一跑就挂。这些细节不写进 README,新人三天内必踩两次。











