浅谈monorepo,单仓库模型

502 阅读3分钟

一般来说,现在普遍管理工具用的都是git,假如你有项目A和项目B,但这两个同时依赖一个组件C,方法有如下:

  1. 将组件C分别放在项目A和项目B

灵活性大,可能经过版本迭代功能组件不同,但维护成本高,因为这样你就有

  1. 将组件C发布到npm上,项目A和项目B去使用组件C包

维护成本较小,但发布npm就有版本问题,如果版本更新项目没更新上,就有可能出现差异性

这种多个项目单个管理的,叫做multirepo

image.png

但如果,把ABC都放在一个项目呢,是的这就叫做monorepo

image.png

monorepo 并不是一种工具,它只是对于项目的一种管理手段,一种思维方式。

www.lernajs.cn/#command-pu… lerna官网

其实每一种方法都有利有弊,如何取舍需要结合自己的业务来选择

在这里我简单介绍下自己用monorepo仓库的使用场景

使用场景一

开发组件库,使用lerna初始化仓库

yarn global add lerna
git init lerna-repo && cd lerna-repo
lerna init

生成结构

lerna-repo/
  packages/
  package.json
  lerna.json

在packages里面增加两个包

lerna-repo/
  packages/
     button/
       index.js
       package.json
     input/
       index.js
       package.json
  package.json
  lerna.json
button/package.json
{
  "name": "ikun-button",
  "version": "0.0.1",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
}
input/package.json
{
  "name": "ikun-input",
  "version": "0.0.1",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
}

index文件暂时不放东西,由于lerna发布包需要又commit检测,所有项目需要与git仓库绑定,提交之后到远程分支后执行

npm login //绑定npm仓库
lerna pubulish

根据提示发布包

image.png

这样就可以再npm仓库看到你自己的包了,通过lerna管理就可以很方便的进行多包的发版管理,当然还有更深的操作和原理这个就留在后面的文章,先留个坑

lerna详解

使用场景二

用lerna进行项目管理开发,假如我们上面两个组件包没有发布到npm上,将项目结构修改一下

lerna-repo/
  packages/
   app/
     vue/
       index.js
       package.json
   lib/
     button/
       index.js
       package.json
     input/
       index.js
       package.json
  package.json
  lerna.json

修改一下lerna.json

{
  "packages": [
    "packages/*/**"
  ],
  "version": "1.0.1"
}

lib是公共包,app代表开发项目,执行lerna add ikun-input --scope=ikun-vue

{
  "name": "ikun-vue",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "ikun-input": "^1.0.1"
  }
}

这样如果你不发布包到npm上,也是可以将包挂载在项目上的,如果修改了包,可以执行lerna bootstrap,这样包的依赖就更新了,利用这些特性,封装一下命令,就可以很轻松的实现项目更新。

总结

lerna自身封装了一些功能,使得自身具有npm link的功能,可以让你不用发布就可以去管理包,并在本地测试,相比传统把组件放在文件夹里面管理,用包的形式会更加明确功能,你可以在package.json上进行详细描述,必要时候可以发布版本,进行版本管理。

monorepo相比multirepo,他可以让你同时维护多个项目的时候不用一直切换仓库,公用组件修改可以很快的更新项目,但相反他也会导致你可能只是为了解决一个项目的问题,导致了其他项目的更新,甚至造成其他项目的bug出现,这样对于测试来说压力很大,而且如果你的团队维护人很多,你会发现你每次git pull 会拉取巨多commit,我司为了解决发布版本问题,做了一些工具开发,这个后续分享。

总之,前端架构不是一成不变,还是要多尝试多对比