“Could not find package”在子模块中主因是未初始化Git子模块导致composer.json缺失,而非镜像缺包;须先执行git submodule update --init --recursive,再确保子模块内composer.json合法且name与require严格一致。

为什么子模块里 require 包会提示 “Could not find package”
不是镜像源真缺包,而是 Composer 在子模块路径下尝试读取 composer.json 时,发现目录为空或没初始化——它根本没走到“查镜像”这步。Git 子模块默认不自动拉取内容,modules/my-submodule/ 目录下只有空文件夹,composer.json 不存在,自然报错 Could not find package myorg/my-module at version dev-main。
- 先确认子模块是否已初始化:运行
git submodule status,若输出含-开头或无任何输出,说明未检出 - 手动初始化并更新:
git submodule update --init --recursive(必须在项目根目录执行) - 再检查子模块路径下是否有合法
composer.json(至少含name和autoload字段) - 别指望
composer install --working-dir=modules/foo能绕过这一步——它不触发 submodule 初始化
镜像配置在子模块内完全失效的真正原因
子模块是独立 Git 仓库,它的 composer.json 里如果没写 repositories 字段,Composer 就只认自己配置的全局镜像;但如果你在父项目里配了镜像,子模块运行 composer install 时并不会继承——它只读自己的配置,而多数子模块压根没配镜像。
- 子模块内执行
composer config -g repo.packagist查到的是父项目环境的全局配置,但实际请求仍走子模块本地设置(通常为空, fallback 到官方源) - 验证真实行为:进子模块目录,运行
composer diagnose,看Repo packagist.org:行输出的 URL 是不是你期望的镜像地址 - 临时修复:在子模块根目录下执行
composer config repo.packagist composer https://mirrors.aliyun.com/composer/(不加-g),它会写入该子模块自己的composer.json - 长期方案:把镜像配置写进子模块的
composer.json的repositories字段,确保可 Git 提交、团队一致
“path 类型仓库”如何绕过镜像同步延迟
当父项目通过 "type": "path" 引入子模块时,Composer 完全跳过远程源查询——它不发 HTTP 请求,不依赖 packages.json 元数据,自然不受镜像同步延迟影响。但前提是路径必须存在且含有效 composer.json。
-
url值必须是相对于父项目composer.json的路径,不能含../,也不能以/开头(如./modules/my-submodule合法,/full/path非法) - 子模块的
name字段必须与composer require的包名严格一致(包括大小写),否则报Package myorg/my-module not found - 版本号要匹配:若子模块
composer.json中"version": "dev-main",则需composer require myorg/my-module:dev-main,不能写^1.0 - 此方式下,
composer.lock记录的是软链接路径,不是下载地址——CI 中必须确保子模块已git submodule update完成,否则 vendor 目录里链接指向空目录
CI/CD 中 vendor 和 submodule 的执行顺序陷阱
顺序错了,整个部署就失败。镜像源配置、submodule 初始化、composer install 这三步必须严格串行,且不能混在同一命令中靠“运气”触发。
- 第一步永远是
git submodule update --init --recursive(在项目根目录),否则后续所有操作都基于空目录 - 第二步才是镜像配置:用
composer config -g repositories.packagist.org.type composer和composer config -g repositories.packagist.org.url https://mirrors.aliyun.com/composer/(注意 Composer 2.2+ 键名和分设要求) - 第三步执行
composer install --no-dev --optimize-autoloader,此时才真正用上镜像源 - 千万别在 CI 脚本里写
composer install && git submodule update——install 阶段已经失败,后面命令根本不执行 - Windows CI 环境特别注意:Git Bash 和 PowerShell 对
~/.composer/config.json的读取路径可能不一致,建议统一用COMPOSER_HOME环境变量显式指定
repos.packagist.org 多了个 s)。动手前先跑一遍 git submodule status 和 composer diagnose,比反复换镜像更省时间。


















