SuperAPI AI 工具集

php-monorepo-builder

编程与开发

查看项目

更新于 10-15 08:10

技能介绍

用途

php-monorepo-builder 用于管理 PHP monorepo(单一仓库多包)。其底层为 symplify/monorepo-builder,包名为 monorepo-php/monorepo(通过 Packagist 分发),语言要求 PHP 8.2+,采用 MIT 许可。它解决的核心问题是:多个 composer.json 之间的依赖聚合、包间版本约束一致性、以及跨包的版本发布。

适用场景包括:搭建新的 PHP monorepo;将多个包的 composer.json 合并到根 composer.json;校验包间依赖版本是否一致;自动化发布(版本递增、打标签、推送标签);配置包扫描目录与排除目录;合并后追加或移除数据;排查合并问题;自定义发布 worker 的执行顺序。

主要能力

安装:

composer require monorepo-php/monorepo --dev

要求 PHP 8.2+。若使用 PHP 8.1,需使用 symplify/monorepo-builder:^11.2(已不再维护)。

初始化新 monorepo:

vendor/bin/monorepo-builder init

该命令会生成基础 monorepo 结构,并在项目根目录生成一份起始的 monorepo-builder.php 配置。

核心命令:

  • vendor/bin/monorepo-builder merge:将所有包的 composer.json 合并到根目录
  • vendor/bin/monorepo-builder validate:检查包间版本是否一致
  • vendor/bin/monorepo-builder propagate:将根依赖版本回写到各包的 composer.json
  • vendor/bin/monorepo-builder bump-interdependency <version>:将互相依赖的约束统一更新到指定版本
  • vendor/bin/monorepo-builder package-alias:更新各包 composer.json 中的 branch-alias
  • vendor/bin/monorepo-builder localize-composer-paths:在拆分前测试时将互依赖路径切换为本地路径
  • vendor/bin/monorepo-builder release <version>:在所有包上打标签并发布新版本
  • vendor/bin/monorepo-builder init:搭建新的 monorepo 结构

使用方式

全部配置位于项目根目录的 monorepo-builder.php。

配置包目录:

use Symplify\MonorepoBuilder\Config\MBConfig;

return static function (MBConfig $mbConfig): void {
    // 扫描多个目录查找包
    $mbConfig->packageDirectories([
        __DIR__ . '/packages',
        __DIR__ . '/projects',
    ]);

    // 从发现范围中排除特定包
    $mbConfig->packageDirectoriesExcludes([
        __DIR__ . '/packages/secret-package',
    ]);
};

配置合并时的追加与移除:

use Symplify\MonorepoBuilder\ComposerJsonManipulator\ValueObject\ComposerJsonSection;
use Symplify\MonorepoBuilder\Config\MBConfig;
use Symplify\MonorepoBuilder\ValueObject\Option;

return static function (MBConfig $mbConfig): void {
    // 合并后向根 composer.json 追加数据
    $mbConfig->dataToAppend([
        ComposerJsonSection::AUTOLOAD_DEV => [
            'psr-4' => [
                'Symplify\Tests\\' => 'tests',
            ],
        ],
        ComposerJsonSection::REQUIRE_DEV => [
            'phpstan/phpstan' => '^2.1',
        ],
    ]);

    // 合并后从根 composer.json 移除数据
    $mbConfig->dataToRemove([
        ComposerJsonSection::REQUIRE => [
            // 版本不相关——按 key 移除
            'phpunit/phpunit' => '*',
        ],
        ComposerJsonSection::REPOSITORIES => [
            Option::REMOVE_COMPLETELY,
        ],
    ]);
};

说明(12.5.0+):dataToAppend 现在支持任意 composer.json key,不再限于 24 个硬编码 section。

执行合并:

vendor/bin/monorepo-builder merge

该命令读取已发现包目录中的所有 composer.json,并将其依赖合并到根 composer.json。

发布新版本:

vendor/bin/monorepo-builder release 1.2.0

按顺序执行所有已配置的 release worker(递增版本、创建标签、推送等)。

拆分包到独立仓库:Monorepo Builder 本身不处理包拆分。若需要拆分仓库,应配合 GitHub Actions 中的 symplify/github-action-monorepo-split 使用。

关键概念

包发现:默认扫描 ./packages 下包含 composer.json 的子目录。可通过 packageDirectories() 配置额外或替代目录。目录名中包含 tests 的包可能被排除(见 issue #59)。

合并行为:merge 命令将各包中的 require、require-dev、autoload、autoload-dev 等 section 聚合到根 composer.json。自 12.5.0 起,自定义/非标准 key(如 scripts-aliases、abandoned、readme)在合并时会被保留。

Release worker:release worker 是发布过程中按顺序执行的离散步骤,可自定义或重排。存在已知问题(#77):SetNextMutualDependenciesReleaseWorker 会固定递增次版本号,需谨慎检查 worker 顺序。

版本校验:validate 命令检查当包 A 依赖包 B(两者都在 monorepo 中)时,A 的 composer.json 中的版本约束是否与 B 的实际版本一致,从而防止包间版本漂移。

已知问题

未关闭问题:

  • #90 支持 Conventional Commit 发布(功能请求)
  • #77 SetNextMutualDependenciesReleaseWorker 总是递增次版本号
  • #76 缺少无论 monorepo 层级深浅都导入 autoloader 的辅助方法
  • #72 EventDispatcher.php 中不兼容的声明
  • #69 关于 Composer 安装行为的问题
  • #59 名称中含 tests 的包总被忽略
  • #25 预发布版本的互依赖版本更新失败

12.5.0(2026-02-13)近期修复:

  • 合并不再丢失未知/自定义 composer.json section——scripts-aliases、abandoned、readme 及任意非标准 key 不再被丢弃(#105、#106、#71、#107)
  • dataToAppend 支持任意 composer.json key——不再限于 24 个硬编码 section(#105)

近期发布:

  • 12.5.2(2026-03-26):允许 sebastian/diff ^8(#110)
  • 12.5.0(2026-02-13):保留自定义 composer.json section;dataToAppend 支持任意 key

参考文件

  • references/README.md:完整 README——安装、命令、配置项、使用示例(置信度:中)
  • references/releases.md:所有已打标签版本的发布说明(共 2 个版本)(置信度:中)
  • references/issues.md:全部 34 个 GitHub issue——7 个未关闭、27 个已关闭,含标签与日期(置信度:中)
  • references/file_structure.md:仓库目录树(813 项)(置信度:中)

使用建议

入门:运行 vendor/bin/monorepo-builder init 搭建 monorepo;在 packages/ 下添加包(每个包有自己的 composer.json);运行 vendor/bin/monorepo-builder merge 将依赖同步到根目录;查看 references/README.md 了解完整配置项。

进阶:自定义 monorepo-builder.php 以添加多个包目录和排除项;用 dataToAppend 向根 composer.json 注入共享的开发工具(PHPStan、PHPUnit);用 dataToRemove 从合并后的根文件剥离仅属于单个包的条目(如本地 repositories);在 CI 中运行 validate 以尽早发现包间版本漂移;当根与包版本约束需要同步变动时使用 propagate 或 bump-interdependency。

高级:为自定义发布流水线配置并重排 release worker;使用 Option::REMOVE_COMPLETELY 在合并后删除整个 section(如 repositories);使用 SetNextMutualDependenciesReleaseWorker 时注意 issue #77 可能意外递增次版本号;对于预发布版本(alpha/beta/RC),在依赖自动互依赖更新前参考 issue #25;若维护多个活跃主版本线,使用分支感知的标签校验。