从Nuxt项目变化了解到monorepo

从Nuxt项目变化了解到monorepo

大约两三个月之前拜读过Nuxt.js 1.4.2源码及2.1.0 的大版本更新,那时候Nuxt的核心功能都在nuxt package中,包含了模板、配置、构建及核心 renderer、中间件等模块。 

直到最近闲暇准备分享Nuxt,在搜集资料的过程中再次拜读了其源码。 

这时的版本已是 2.3.x。刚一入眼突然感觉这与之前似乎已完全不是同一个项目,在Nuxt发布到npm的package中只剩下对@nuxt/core、@nuxt/builder、@nuxt/generator这些包的引用,我意识到Nuxt项目是把核心功能拆解成各个功能不同的依赖包了,包括其cli。 

在源码仓库里,之前的lib源码目录不见了,整体翻看了一遍后才在packages中找到了Nuxt模块源码,根据不同功能它被分成了多个不同的模块目录。沿着package.json中的构建命令,在scripts下的构建脚本中了解到packages目录下每一个目录都会被作为一个独立的rollup构建。发布package时将这些目录以@nuxt 作为namespace发布,最终以@nuxt为namespace的npm依赖包呈现。 在其Github仓库的release记录中提到了`mono-repo`这个词,我这才了解到,项目管理的两种方案:monorepomultirepo

monorepo和multirepo的概念

通常,当我们的项目不断的迭代更新的时候,我们会根据业务或者是功能又或者是方便复用某些代码模块,把一个大的codebase拆成一些独立的package或是module,再将这些功能独立的package分别放入单独的repository中进行维护。可以简单地称这种方式为multirepo(multiple repositories)。

monorepo则是一种相反的做法,它提倡将所有的相关package都放入一个repository来管理。显然,把辛苦抽出来的代码再放回一个repository中,会让repository变得臃肿,你可能认为这是一个很糟糕的做法。但是这样做的开源项目和公司并不算少。

Multirepo的问题

在实践中Multirepo经常会遇到这样的问题:

  • 项目或者 module 因为功能或者属性或者历史的原因我们不得不拆分到不同的repository中,这导致了后期如果涉及人员交接,或者自己项目管理时就会陷入到不知道哪里去找repository的境地。
  •  issue 不知道往哪里提,导致项目管理混乱。
  • 版本管理,当其中一个依赖包的版本更新时,其他相关的依赖包也可能必须要一同更新,这就会变成一场灾难。在日常开发中,可能我们一次迭代会涉及多个 repository,一方面需要用 npm link 的方式 hack 到本地仓库,另外一方面,每次都需要手动切换到对应的各个仓库进行 lint test 等操作,要完成这些我们不得不在 terminal 中开启多个 tab,这绝对是个眼力和体力活

  • changelog 梳理又是一场灾难,在 Multirepo 管理项目的情况下,我们需要人工同步所有变动的仓库最终列出一个 changelog。如果全部是由一个人开发还能理得清楚,但实际上一般正常迭代都是多人开发协同开发的模式,这个情况下我们很难统计到仓库依赖的 module 是否有更新,做了什么样的工作。

monorepo的优缺点

使用monorepo以上问题都可以迎刃而解:

  • 单个的lint,build,test和release流程
  • 统一的地方处理issue
  • 不用到处去找自己项目的repo
  • 方便管理版本和dependencies
  • 跨项目的操作和修改变得容易
  • 方便生成总的changelog

但同时,monorepo也有其问题: 

  • repository的体积变得很大
  • 安全问题,如何管理权限

monorepo相关工具

lerna

最后编辑于 2018-12-07 13:07