子目录执行 composer install 会走官方源,因为 composer 不自动继承父目录配置;每个含 composer.json 的子目录被视为独立项目,必须显式声明 repositories 数组,首项为 {"packagist.org": false},后续为镜像地址,且末尾需带 /,否则 fallback 至 packagist.org。

为什么子目录执行 composer install 会走官方源
因为 Composer 不会自动向上查找父目录的 composer.json,每个子目录只要自己有 composer.json(哪怕空的),就视为独立项目,完全忽略上级配置。常见于 monorepo 结构:根目录配了镜像,但 packages/foo/composer.json 一存在,cd packages/foo && composer install 就退回 https://packagist.org。
子目录项目必须显式继承或重写 repositories 数组
不能指望“上级配置自动生效”,子目录项目的 composer.json 必须包含完整、有效的 repositories 声明——否则 Composer 2.2+ 会硬编码回退到官方源。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
-
"repositories"必须是数组([]),不是对象({}) - 第一项必须是
{"packagist.org": false},独立成项,不可合并 - 第二项起才是镜像地址,例如:
{"type": "composer", "url": "https://mirrors.aliyun.com/composer/"} -
url值末尾必须带/,否则请求路径拼接错误,404 后静默 fallback
monorepo 场景下避免重复维护的实操方式
手动在每个子包里复制粘贴 repositories 容易漏、难同步。更可靠的做法是:用脚本生成 + Git hooks 强制校验。
- 在根目录放
scripts/sync-repos.php,读取统一镜像配置,批量注入所有子目录composer.json的repositories字段 - 提交前用
pre-commithook 运行该脚本,并检查所有composer.json是否含有效{"packagist.org": false} - CI 脚本中加一步:
grep -r '"packagist.org": false' packages/ --include="composer.json" || exit 1,防止遗漏
不要依赖全局 config 或环境变量来“兜底”
子目录项目一旦有 composer.json,就会完全忽略 composer config -g repos.packagist 和 COMPOSER_REPO_PACKAGIST 环境变量。所谓“兜底”在多级结构里根本不存在。
- 验证方式:进任意子目录,运行
composer config repos.packagist(不加-g),输出应为空;再运行composer config -g repos.packagist,即使有值也不生效 - 删掉子目录
vendor/和composer.lock后,只靠全局镜像无法触发元数据拉取——composer install会直接报Could not find package - 唯一确定性方案:每个可独立安装的
composer.json都必须自带完整、合规的repositories数组
composer.json 只要存在,它就彻底接管整个依赖解析生命周期——包括元数据来源、dist URL 构造、provider 加载。此时任何外部配置都形同虚设。一致性不来自“继承”,而来自“每处声明都严格一致”。










