5W1H 带你入门 Monorepo

lxf2023-04-05 20:09:01

概述

无论是为了更高效的团队协作,还是改进代码管理,Monorepo 都是一种有效的方案。本文用「5W1H」带你了解以下内容:

  • 「What」什么是 Monorepo ?

  • 「Why」为什么会有 Monorepo ? 它的优势是什么 ?

  • 「Who」谁正在用 Monorepo ?

  • 「When」什么时候用 Monorepo ?

  • 「Where」去哪学习 Monorepo ?

  • 「How」如何从零构建 Monorepo?

正文

「What」什么是 Monorepo ?

随着大前端崛起,初始的 Polyrepo 方案承载不了日益复杂的业务场景。那什么是 Polyrepo?

什么是 Polyrepo?

Polyrepo 也称 multiple repostories。指多 Git 仓库结构,这与 Monolith 完全相反,只要能独立运行命令项目就切分成单独 git 仓库,井水不犯河水。在 Monorepo 概念浮现在大众之前,Polyrepo 是唯一的选择。

还有一个 Polyrepo 的进阶版:新建一个文件夹,将所有 Git 仓库都套进去,治标不治本。

那什么是 Monorepo ?

Monorepo 全称 Monolithic Repository,指单个仓库可包含许多相关但独立的项目,可以由同一个团队或多个团队管理。如下图可清晰看出 Polyrepo 与 Monorepo 区别。

5W1H 带你入门 Monorepo

我对 Monorepo 的浅薄理解:

  • 子项目间可独立运行、共享代码,但没有强依赖,剥离出来照样能运行,只是引入方式从 workspace 转变成 Npm,遵循高内聚,低耦合理念
  • 开发环境下应尽量少依赖或不依赖全局变量以及根路径下 node_module,如若违背该点,则第一点不成立

「Why」为什么会有 Monorepo ? 它的优势是什么?

每件新事物的出现必然是为了补充旧事物的不足。当我们用 Polyrepo 架构不断迭代时,达到一定数据量级时会出现以下问题:

  1. 大型项目被割裂成多个 Git 仓库:

    • 需要 git clone 多个仓库,并运行不同的命令来共同跑起完整的服务(典型:前端+后端+ SDK 项目分离)。
  2. 代码复用率严重下降:

    • 公共函数或组件只能通过 duplicate 或 npm 方式共享。
    • 当某个公用组件(对应 npm 包)修改时,需要人为确认该 NPM 包所依赖的各个项目升级情况
  3. 相同类型项目却有着千奇百怪的开发工具和周边库:

    • jest、java 的版本不一致,导致 API 写法不一
    • React 组件库以及状态管理库不一致,新人接手学习成本提高
    • ESlint 、CommitLint、prettier 配置 和 Changelogs 生成规则不一致
  4. 新建项目时有额外心智负担:

    • 如果有需要,可能要复制多套 CI 文件

    • 出于好奇,可能会找更符合当下的 cli 来新建项目(耗时且可能有坑)

    • 完美主义的人可能会配置更多的 eslint、prettier(耗时)

    • 需要在其他项目中 Readme 中添加新项目的 git 地址,在表面上报保持 Connection

那么 Monorepo 是如何一一解决上面的问题呢?

Monorepo 的优势

我们开发新项目时,必经的几个步骤依次是:「安装依赖」->「本地开发与调试」->「CI构建」->「发布与上线」

那么就从这四个视角来看看相对于 Polyrepo, Monorepo 有哪些优势。

安装依赖

ActionPolyrepoMonorepoMonorepo 收益 & 缺点
install 依赖次数项目个数即次数一次- 减少 install 命令次数

本地开发与调试

ActionPolyrepoMonorepoMonorepo 收益 & 缺点
服务关联启动在不同项目下的终端运行启动命令在当前项目下启用多个终端会话一键启动多项目服务
统一工具选型撰写新人入门文档,并在文档中说明工具选型方案
开发脚手架 cli,预设工具依赖
提取工具和其配置至独立包(推荐)或 root
减少团队其他成员接手成本
收敛三方包版本人为将所有项目 package.json 的版本统一