Skip to content
On this page

Monorepo 迁移指南

迁移前评估

1. 项目分析

在开始迁移之前,需要全面评估现有项目:

  • 项目依赖关系: 分析项目间的依赖关系,确定哪些项目可以合并到一个 monorepo 中
  • 团队结构: 评估团队的组织结构,确定哪些团队将共享代码库
  • 技术栈一致性: 检查项目使用的技术栈,确保迁移后能保持一致性
  • CI/CD 复杂性: 评估当前的 CI/CD 流程,确定迁移后的复杂性

2. 迁移收益评估

  • 代码复用: 确定有多少代码可以复用
  • 开发效率: 评估跨项目协作的改进潜力
  • 构建时间: 分析合并后可能的构建优化
  • 维护成本: 估算长期维护成本的变化

迁移策略选择

1. 渐进式迁移

适用场景: 大型项目或多个团队协作

步骤:

  1. 选择一组相关性高的项目开始迁移
  2. 建立基础 monorepo 结构和工具链
  3. 逐步迁移其他项目
  4. 完善流程和自动化

优点:

  • 降低风险
  • 允许逐步学习和调整
  • 保持业务连续性

缺点:

  • 迁移周期较长
  • 需要维护两套系统一段时间

2. 全量迁移

适用场景: 小型项目集或紧密相关的项目

步骤:

  1. 完整规划 monorepo 结构
  2. 一次性迁移所有相关项目
  3. 立即启用新流程

优点:

  • 迁移周期短
  • 避免双系统维护
  • 立即可获得全部收益

缺点:

  • 风险较高
  • 需要充分的前期准备
  • 对业务可能有短暂影响

工具链设置

1. 选择合适的工具

根据项目需求选择 monorepo 工具:

  • Lerna: 适合需要复杂版本管理的 JavaScript 项目
  • Yarn Workspaces: 适合已使用 Yarn 的项目
  • pnpm Workspaces: 适合注重性能和磁盘使用效率
  • Nx: 适合需要完整开发体验的大型项目
  • Rush: 适合企业级项目

2. 项目初始化

以 pnpm 为例进行初始化:

bash
# 创建 monorepo 根目录
mkdir my-monorepo
cd my-monorepo

# 初始化 pnpm 工作区
pnpm init

# 创建 pnpm-workspace.yaml
echo "packages:
  - 'packages/*'
  - 'apps/*'" > pnpm-workspace.yaml

3. 配置文件设置

创建必要的配置文件:

json
// package.json
{
  "private": true,
  "scripts": {
    "build": "pnpm --recursive run build",
    "test": "pnpm --recursive run test",
    "lint": "pnpm --recursive run lint"
  },
  "devDependencies": {
    "typescript": "^4.9.0"
  }
}

项目结构设计

1. 标准目录结构

monorepo/
├── apps/                 # 应用程序
│   ├── web-app/
│   │   ├── src/
│   │   ├── package.json
│   │   └── tsconfig.json
│   └── mobile-app/
│       ├── src/
│       ├── package.json
│       └── tsconfig.json
├── packages/            # 可复用的包
│   ├── ui-components/
│   │   ├── src/
│   │   ├── package.json
│   │   └── tsconfig.json
│   ├── utils/
│   │   ├── src/
│   │   ├── package.json
│   │   └── tsconfig.json
│   └── data-access/
│       ├── src/
│       ├── package.json
│       └── tsconfig.json
├── tools/               # 构建和开发工具
├── docs/                # 文档
├── scripts/             # 自定义脚本
├── .github/             # GitHub 配置
│   └── workflows/       # CI/CD 工作流
├── package.json
├── pnpm-workspace.yaml
├── pnpm-lock.yaml
└── tsconfig.base.json   # 基础 TypeScript 配置

2. 共享配置管理

创建共享配置文件:

json
// tsconfig.base.json
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "moduleResolution": "node",
    "esModuleInterop": true,
    "strict": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  }
}

依赖管理

1. 依赖提升策略

  • 将共享依赖提升到根目录
  • 使用工作区协议引用内部包
  • 定期审查和同步依赖版本

2. 内部包引用

在包的 package.json 中引用内部包:

{
  "name": "@myorg/web-app",
  "dependencies": {
    "@myorg/ui-components": "workspace:*",
    "@myorg/utils": "workspace:*"
  }
}

迁移实施步骤

第一阶段:准备工作

  1. 建立迁移团队: 指定负责人和核心团队成员
  2. 制定详细计划: 包括时间表、里程碑和回滚计划
  3. 设置测试环境: 建立与生产环境相似的测试环境
  4. 备份现有代码: 确保所有项目都有完整备份

第二阶段:基础设施搭建

  1. 创建 monorepo 骨架: 建立基本目录结构
  2. 配置工具链: 设置包管理器、构建工具等
  3. 建立 CI/CD 管道: 配置自动化构建和测试流程
  4. 设置代码质量工具: 配置 ESLint、Prettier 等

第三阶段:项目迁移

  1. 迁移第一个包: 选择最简单的包进行试点
  2. 测试迁移结果: 确保功能完整性和构建成功
  3. 逐步迁移其他包: 按优先级和依赖关系迁移
  4. 更新依赖关系: 调整包间的依赖引用

第四阶段:流程优化

  1. 完善工作流程: 优化开发、测试和部署流程
  2. 性能调优: 优化构建和测试性能
  3. 文档更新: 更新开发文档和操作手册
  4. 团队培训: 对团队进行新流程培训

CI/CD 流程调整

1. 工作流配置

# .github/workflows/ci.yml
name: CI
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: pnpm/action-setup@v2
        with:
          version: 7
      - uses: actions/setup-node@v3
        with:
          node-version: 18
          cache: 'pnpm'
      - run: pnpm install
      - run: pnpm --recursive test
      - run: pnpm --recursive lint

2. 影响分析

实施基于更改的智能构建:

# 只构建受影响的包
pnpm --filter "...[origin/main]" build

常见问题和解决方案

1. 依赖冲突

问题: 不同包需要不同版本的相同依赖 解决方案:

  • 仔细分析依赖需求
  • 使用 resolutions 字段强制版本
  • 考虑升级相关包以兼容

2. 构建时间增加

问题: 合并后构建时间显著增加 解决方案:

  • 实施增量构建
  • 使用分布式缓存
  • 优化构建脚本

3. 权限管理复杂

问题: 多团队共享代码库后的权限管理 解决方案:

  • 使用 CODEOWNERS 文件
  • 设置分支保护规则
  • 实施适当的访问控制

迁移后优化

1. 性能监控

  • 监控构建时间
  • 跟踪测试执行时间
  • 分析开发体验指标

2. 持续改进

  • 定期审查项目结构
  • 优化依赖管理
  • 改进自动化流程

3. 团队反馈

  • 收集开发者反馈
  • 调整工作流程
  • 提供持续培训

回滚计划

在迁移过程中,始终准备回滚计划:

  1. 保持原仓库: 在迁移完成前保留原始仓库
  2. 版本标签: 在迁移前后打上清晰的版本标签
  3. 数据备份: 定期备份迁移过程中的数据
  4. 回滚步骤: 准备详细的回滚操作步骤

总结

Monorepo 迁移是一个复杂但有价值的项目。成功的关键在于:

  • 充分的前期评估和规划
  • 选择合适的工具和策略
  • 分阶段实施,降低风险
  • 关注团队协作和流程优化
  • 持续监控和改进

记住,迁移不是终点,而是开始。迁移后需要持续优化流程,以充分发挥 monorepo 的优势。