不会。composer 不感知 .gitmodules,也不执行 git submodule 命令;需通过 path 类型仓库配置本地子模块路径,并用 composer require 安装;子模块应独立维护 vendor 和 autoload;ci/cd 中须先 git submodule update --init --recursive 再 composer install。

Composer 会自动初始化或更新 Git submodule 吗?
不会。Composer 完全不感知 .gitmodules,也不会执行 git submodule init 或 git submodule update。哪怕你用 git clone --recursive 拉下整个项目,后续运行 composer install 时,它仍可能因子模块目录为空而报错,比如 Could not find package myorg/my-module at version dev-main——因为 Composer 尝试读取 modules/my-module/composer.json,但该路径下只有空文件夹。
怎么让 Composer 正确加载子模块里的 PHP 包?
核心是绕过 Git 协议,把子模块当本地路径对待。前提是子模块目录已存在且含合法 composer.json(含 name 字段)。
- 在根项目
composer.json的repositories中添加path类型源:"repositories": [ { "type": "path", "url": "./modules/my-module" } ] -
url必须是相对于根composer.json的路径,不能含../ - 然后运行
composer require myorg/my-module:dev-main(版本需与子模块composer.json中的version或分支别名一致) - Composer 会软链接该目录到
vendor/myorg/my-module,并参与 autoload 合并
为什么子模块里执行 composer install 常失败?
子模块是独立 Git 仓库,但它的 vendor/ 和 autoload.php 容易被父项目污染。
- 进入子模块目录后,先确认
pwd输出路径正确,避免误在父项目根目录操作 - 删掉子模块内残留的
vendor/和composer.lock(尤其从别人 clone 来的) - 不要用
composer install --working-dir=modules/foo:Composer 不保证跨目录 autoload 正确加载 - 子模块的
autoload配置必须用独立命名空间(如"Vendor\Module\"),不能和父项目重叠
CI/CD 中如何可靠同步 submodule 并安装依赖?
顺序错误是部署失败的主因。Git submodule 和 Composer 的执行必须严格分步。
- 先执行
git submodule update --init --recursive(确保所有子模块目录存在且内容就位) - 再运行
composer install --no-dev --optimize-autoloader - 若用钩子自动触发,推荐在
composer.json中写:"scripts": { "post-install-cmd": [ "@php -r "if (is_dir('.git')) system('git submodule update --init --recursive 2>/dev/null || true');"" ] } - 注意:脚本中
system()调用依赖系统已安装 Git,且 CI 环境需有 submodule 所需的访问权限(如 SSH 密钥或 token)
最易忽略的是子模块的递归深度——如果某个 submodule 本身还嵌套了 submodule,--recursive 缺失会导致深层依赖缺失,这类问题只在生产环境暴露,本地开发常因缓存掩盖。











