monorepo仓库的概念
monorepo是一种仓库管理方式,与之对应的还有multirepo,那么这二者有何区别呢?
multirepo是我们平常最常使用的仓库管理方式,每一个项目都有单独的git仓库进行代码的管理,不与其它仓库进行混杂,优势在于代码的划分界限比较清晰,各项目之间代码独立不互相影响,实现高度自治,不同的项目可以由不同的团队管理,可以选择不同的依赖,库等。 但也有问题存在。
- 代码共享困难
例如当一个项目中提炼出了可以公用的组件后,需要通过复制粘贴或者单独发布npm包等手段来实现跨仓库的代码共享,较为繁琐。
- 重复代码过多
多个项目中可能有相同的依赖,相同的工具函数,导致多个项目中有许多重复的代码,造成不必要的浪费。
- 不一致的项目结构及操作方式。
不同的团队间有自己的一套技术方案和独特的操作方式,比如package.json里的命令,项目的启动方式等,会让不同的项目之间的运作变得不同,维护成本相对增加。
monorepo是一种将所有项目都放到同一仓库中的管理方式,虽然是所有项目混杂在一起,有很快成长为巨石仓库的麻烦,不过也带来许多好处。
- 代码共享方便
所有项目都在同一个仓库,不同的项目之间可以直接相互引用,并且当调试某些npm包时可以不用再使用npm link,可以直接将npm包的引用修改为项目中的代码,方便调试,并且可以有共同的第三方依赖,方便同时对所有项目的依赖进行版本控制。
- 低成本新建项目
项目所需的架构和基本配置都在仓库中已存在,可以以更低的成本新建项目,无需考虑太多配置。
- 减少多个项目之间来回切换的成本
相信很多朋友都有同时接到过多个需求的时候,有时候这边催你赶紧做,那边也在催你修一下紧急bug,并且需要分开提交,然后在多个窗口和命令行之间来回切换,有时候都找不到对应的窗口。在使用monorepo之后,所有项目集中在一个仓库,并且可以集中提交,也可以一键启动多个项目,减少了来回切换的时间成本。
- 统一的项目操作
monorepo中通常可以通过一些工具,例如lerna来实现一条命令启动多个项目,那要实现这样的操作,项目中的命令语句就必须相同了,那既然保持相同之后,在使用这方面就保持了基本统一。
monorepo的应用场景
- 有大量重复代码的项目,比如说一些活动页,技术架构和第三方依赖基本一致,可以使用monorepo管理,减少依赖项增加的同时实现统一的版本控制。
- npm包的联调,可能npm包在许多项目中都有使用,但使用npm link的方式来调试可能会遇到许多问题,不太方便,而使用monorepo会大大简化npm包的联调,只需将Npm包的引入改为项目中的包。
- 同时存在前端和node端的项目,使用monorepo可以实现更好的版本控制,前后端可以同时发布新的版本和版本回退,并且本地开发时可以同时启动,减少操作成本和管理成本。
本文的实现就以第三种情况为例,将应用的前后端放在一个monorepo仓库中,实现统一管理和开发。
前后端实现
- 前端采用vue-cli直接生成项目,此处省略具体生成命令。
- 后端采用node框架koa生成服务端。
import Koa2 from 'koa';
import koaBody from 'koa-body';
import koaRouter from 'koa-router';
const router = new koaRouter();
const app = new Koa2();
app.use(
koaBody({
multipart: true,
}),
);
app.use(router.allowedMethods());
app.listen(3001);
console.log('服务器运行在端口 3001');
实现Monorepo
monorepo的实现一般借用了工具,来对monorepo仓库实现更方便的管理及发布等。
本文主要采用yarn + lerna对monorepo仓库进行管理。
yarn global add lerna // 全局安装lerna
lerna init //在monorepo仓库根目录执行
lerna add frontend //导入刚刚生成的前端项目
lerna add server //导入刚刚生成的后端项目
此时目录结构应为
然后将两个项目的package.json中的启动命令都改为通过yarn dev启动
lerna bootstrap // 为packages下的所有子项目安装依赖
lerna run dev //同时为packages下的所有子项目执行yarn dev 命令,实现一条命令直接启动前后端
lerna clean // 为packages下的所有子项目清除依赖
至此,已经完成了应用前后端和monorepo仓库的基本配置,之后应用的前后端都可以在这一个仓库里开发,可以一键安装和启动,以及同时发布和部署,解决前后端分离管理的版本不一致,以及开发时需要来回切换的问题,并且提高开发便捷性。
总结
本文介绍了monorepo以及一些具体实践,并不是说monorepo一定比multirepo要好用,更好,而是它们各有各的优点和缺点,根据自己的使用场景选择一个更优的方案。比如同时开发前端和后端的时候,monorepo就是一个不错的选择。