composer monorepo 依赖本地 path 仓库实现,需严格对齐路径、包名、大小写及 repositories 顺序;改子包代码后 vendor 不更新,因 composer update 默认跳过 path 包,须用 --with-dependencies 或删 vendor 后重装。

Composer 本身不支持 Monorepo,所谓「单仓多包」完全是靠 repositories + path 类型硬凑出来的——配对稍有偏差,本地改的代码就根本不会生效,而且还不报错。
为什么改了子包代码,vendor里还是旧的
这是最常踩的坑:你改了 packages/my-sdk/src/Client.php,但运行 composer dump-autoload 或 composer update 后,vendor/myorg/my-sdk 下的文件完全没变。
-
composer dump-autoload只刷新自动加载映射,不触发任何包内容同步 -
composer update默认跳过path包,除非显式指定包名并加--with-dependencies - 最稳妥的做法是删掉
vendor/myorg/my-sdk目录,再跑一次composer install,强制重建软链接 - 如果看到
vendor/myorg/my-sdk是完整复制(不是符号链接),说明 symlink 没启用,需在repositories配置里加"options": {"symlink": true}
repositories 怎么写才不被 packagist.org 覆盖
根项目 composer.json 的 repositories 数组顺序决定一切。默认 packagist.org 是隐式存在的最高优先级源之一,一旦你没禁用它,又写了带版本约束的 "myorg/my-sdk": "^1.0",Composer 就会直接去远程找已发布的 1.x 版本,完全忽略你本地的 packages/my-sdk。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 必须把
path仓库写在repositories数组最前面 - 必须显式禁用默认源:
{"packagist.org": false} - require 中的版本必须用
"*@dev"、"dev-main"或"*",不能写"^1.0"这类语义化版本 - 每次修改
repositories或子包composer.json后,先跑composer clear-cache,否则可能读到旧缓存
子包 autoload-dev 不生效怎么办
根项目跑 phpunit 找不到子包里的测试类,不是路径问题,是 Composer 根本没加载子包的 autoload-dev 配置。
-
path类型包的autoload-dev默认不启用,哪怕子包自己的composer.json写得再全也没用 - 必须在根项目的
composer.json的autoload-dev里手动加上子包的测试路径,例如:"tests/MySdkTest.php": "packages/my-sdk/tests/" - 如果子包要独立运行测试(比如 CI 里单独验证),它自己也得有完整的
autoload-dev和require-dev,但根项目调用时仍需上面那条显式配置
通配路径和 symlink 的实际限制
别指望 "packages/*" 自动覆盖所有子目录——它只在 Composer 2.2+ 支持,且要求每个匹配目录下都有合法 composer.json;而 symlink 在 Windows 上默认失败,Linux/macOS 上也可能因挂载参数失效。
-
"packages/*"不是正则,不递归,不匹配packages/core/v2这种嵌套层级,必须显式写全路径 - Windows 用户必须以管理员身份运行终端,或开启「开发者模式」,否则
mklink被系统拦截 - Linux/macOS 若发现软链没建成功,先检查
vendor/所在文件系统是否挂载了noexec或nosymfollow - 最省心的方式:所有
path仓库都加"options": {"symlink": true},不依赖系统默认行为
Monorepo 下的 Composer 管理,本质是一连串精确到字符的配置对齐:路径、包名、大小写、版本写法、数组顺序、缓存状态——漏掉任意一环,表现都是「看起来装上了,其实没连上」。这种脆弱性恰恰是它轻量可控的前提,没有魔法,只有细节。










