composer本身不支持monorepo,需在根composer.json中用path类型仓库“欺骗”其将本地目录视为包源;必须满足四条件:type为"path"、url为精确相对路径、子包name与require键完全一致、版本约束用"@dev"。

Composer 本身不支持 Monorepo,所谓“中文环境下的多包单仓”,和英文环境没有任何区别——它只认 composer.json 的结构、路径的大小写、name 字段的格式,以及你有没有在根项目里骗过它。中文目录名、中文注释、中文 README 都不影响,但一旦你在 url 或 name 里用了中文字符(比如 "包名/日志"),Composer 就会直接失败或静默跳过。
repositories 必须写在根 composer.json 顶层,且顺序决定优先级
子包自己的 composer.json 里写再多 repositories,Composer 完全无视。它只扫描当前工作目录(即你运行 composer install 的地方)下的 composer.json 文件。
-
repositories必须是索引数组,不能是关联数组;写成{"my-sdk": {"type":"path",...}}会直接被忽略 - 必须把 path 类型仓库放在
repositories数组最前面,否则默认隐含的packagist.org会抢先匹配 - 要彻底禁用 Packagist,得显式加
{"packagist.org": false},光靠顺序不够保险 - 改完
repositories后,立刻执行composer clear-cache,否则旧缓存可能让新路径不生效
require 中的包名必须和子包 name 字段一字不差
大小写、斜杠方向、连字符全部敏感:"acme/logging" ≠ "Acme/Logging" ≠ "acmelogging"。写错一个字符,Composer 就放弃本地路径,转头去 Packagist 找同名包——不报错,但你调试的永远是旧代码。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 子包
composer.json中的name必须是非空字符串,格式为"vendor/name"(如"myorg/http-client") - 根项目的
require键必须完全一致,不能省略 vendor 段,也不能颠倒顺序 - 版本约束只能用
"*@dev"、"@dev"或"dev-main";写"^1.0"会触发远程版本匹配,本地路径被跳过 - 子包若依赖其他本地包,那些包也必须出现在根项目的
repositories中,否则依赖解析失败
symlink 不生效?不是 Composer 问题,是环境没配对
预期中 vendor/myorg/http-client 应该是指向 packages/http-client 的符号链接,结果却是完整复制——说明软链根本没建成功,Composer 已退化为 copy 模式。
- 必须在
repositories条目中显式加"options": {"symlink": true};默认值是false - Windows 用户需确认终端以管理员身份运行,或已开启“开发者模式”(否则
mklink被禁用) - Linux/macOS 上检查
vendor/所在文件系统是否挂载了noexec或nosymfollow - CI 环境常禁用 symlink,此时
@dev仍能工作,只是变成复制而非链接,开发时要注意区分
autoload-dev 和测试类找不到的根本原因
根项目跑 phpunit 找不到子包里的测试类,不是路径写错了,而是 Composer 根本没加载子包的 autoload-dev 配置——path 类型包的 autoload-dev 默认不启用,哪怕子包自己写得再全也没用。
- 必须在根项目的
composer.json的autoload-dev里手动加上子包的测试路径,例如:"tests/MySdkTest.php": "packages/my-sdk/tests/" - 子包若要独立运行测试(比如 CI 中单独验证),它自己也得有完整的
autoload-dev和require-dev,但根项目调用时仍需上面那条显式配置 -
composer dump-autoload只刷新自动加载映射,不触发任何包内容同步;改了子包代码后 vendor 不更新,是因为composer update默认跳过 path 包
最隐蔽的坑永远藏在大小写、斜杠方向、缓存残留和 symlink 权限里——它们不会报错,只会让你以为代码没生效,实际早被 Packagist 覆盖了。每次怀疑配置失效,先清缓存、删 vendor 子目录、重装,再看符号链接是否存在,比反复检查 JSON 格式更有效。










