1. Monorepo and Multirepo?
Monorepo 和 Multirepo 是两种不同的源码管理理念,Monorepo 是把所有的相关项目都放在一个仓库中(例如:React, Angular, Babel, Jest, Umijs, ...),Multirepo 则是按模块把子项目拆分到多个仓库中(例如:Rollup, ...)。前者允许多元化发展(各项目可以有自己的构建工具、依赖管理策略、单元测试方法),后者希望集中管理,减少项目间的差异带来的沟通成本。
示例1:React 采用 Monorepo 结构组织项目代码
示例2:Babel 也采用 Monorepo 结构
Multirepo 缺点:
- repo不好找,如果你有很多子项目repo、仓库又很分散、相关负责人又请假了....呵呵;
- Issue 不知道往哪里提,项目管理混乱。
- 版本管理的日常开销大....
Monorepo 优点:
- 单个的lint,build,test和release流程。
- 统一的地方处理issue。
- 不用到处找项目的repo。
- 方便管理版本和依赖管理。
- 跨项目的操作和修改很容易。
- 方便统一生成 ChangeLog。
Monorepo 缺点:
- repo 体积变大。
- 需要额外的工具实现项目间的联合调试(例如:Jest 的 watch.js,监听子项目中文件的变化,动态编译)。
- 由于项目间的依赖通过符号链接(快捷方式)实现,对打包工具有比较高的要求。
- 多个项目集中到一起后,常用的 IDE 可能会遇到麻烦(Facebook 就自己造了IDE
)。
图文无关
2. Lerna 是啥?
Lerna is a tool that optimizes the workflow around managing multi-package repositories with git and npm. Lerna 就是用来协助管理 Monorepo 型项目的工具;
下面两张图展示了
基于 Lerna 的 Monorepo 最大优势
图:传统 Multirepo 结构项目的 bug 修正流程
图:基于 Lerna 的 Monorepo项目结构
图文无关
下面给大家展示一个
基于 Lerna 的 Monorepo 项目
完整的构建、开发、发布流程
深刻体会它的优势
3.1. Monorepo 项目搭建
采用 Monorepo 结构
各子项目代码结构最好统一
- 各子项目,源码入口统一为 src/index.js;
- 各子项目,编译出口统一为 build/index.js;
- 各子项目,IDE 辅助提示统一为 build/index.d.ts;
- 各子项目,基于 ES6 语法、使用 Babel 编译;
- 01. 创建新项目,添加 .gitignore;
图:配置 .gitignore
- 02. 全局安装 lerna;
npm install -g lerna
- 03. 初始化 lerna 项目;
lerna init
图:lerna init 命令
图:Monorepo目录结构说明
3.2. 向 packages 目录添加子项目
- 各子项目,源码入口统一为 src/index.js;
- 各子项目,编译出口统一为 build/index.js;
- 各子项目,IDE 辅助提示统一为 build/index.d.ts;
- 各子项目,基于 ES6 语法、使用 Babel 编译;
图:packages 目录中的子项目
- 构建各子项目间的依赖关系;
lerna bootstrap
图:lerna bootstrap 命令
图:lerna bootstrap 连接后效果
3.3. 编写统一构建、监控工具
图:监控脚本代码示例
图:npm scripts 示例
图:监控脚本运行效果
参考:
《Repo Style Wars: Mono Vs Multi》: http://www.gigamonkeys.com/mono-vs-multi/ 《Why is Babel a monorepo?》: https://github.com/babel/babel/blob/master/doc/design/monorepo.md 《Advantages of monorepos》: https://danluu.com/monorepo/ 《New wave modularity with Lerna, monorepos, and npm organizations》: https://macwright.org/2016/07/08/lerna-npm-organizations-new-wave-modularity.html 《syncpack 小工具》: https://github.com/JamieMason/syncpack Lerna git 仓库: https://github.com/lerna/lerna