monorepo (monolithic repository) 是一种项目架构(而不是软件架构或设计模式),是一种项目管理手段,简单的来说:一个仓库内包含系统的多个开发项目(模块,包),把所有相关的 package 都放在一个仓库里进行管理,每个 package 独立发布。
通过本博客,你将了解monorepo的概念,以及进行一次采用yarn workspace+lerna的monorepo方案的实践。需要注意的是,本博客并不包含npm版本发布实践的部分。
一点题外话:关于monorepo体系国内的资料其实比较少,我在写这篇文章的时候其实本来想的是快速看一点国内的资料就上手开始做,但发现国内相关的技术博客实在质量一般,没有一篇系统性的全面介绍,因此写下这篇博客也是希望能帮到后来想要快速上手monorepo架构解决问题的同学。
来自yarn3 workspace文档中的一段话: In short, they allow multiple projects to live together in the same repository AND to cross-reference each other - any modification to one's source code being instantly applied to the others.
虽然在一些原教旨主义看来,按项目拆分仓库、拆分npm包是天然且唯一的方案;但当不同仓库/项目的内容出现关联时,创建复杂的包引用和软连接始终不如直接把源码放在一起来的高效。
工程化的最终目的是让业务开发可以 100% 聚焦在业务逻辑上,而不是将精力分散到代码复用、依赖版本管理上,因此所谓的工程化思想只是手段,而不是目的。正所谓”不论黑猫白猫,抓到耗子就是好猫“,monorepo架构虽然有着Git版本管理困难、仓库臃肿、编译时间长等原教旨主义唾弃的问题,但在有些项目之间依赖紧密的框架内部它就是最好的方案。
正因如此,许多热门的前端项目如:React, Angular, Babel, Jest, Umijs, Vue 等都是采用的这种架构模式,monorepo架构使它们可以快速迭代、修改不同组件而不必等待依赖链更新。
除了上面提到了方便不同仓库/项目的内容出现关联时的软链接过程(交给包管理器自动完成),monorepo还有以下优点:
还是那句话,还是那句话,没有银弹!没有银弹! 你需不需要使用monorepo完全取决于你自己的需求!但实际情况是,需要使用monorepo的场景,其害处(如编译时间增加、代码仓库膨胀等)远不足以让团队放弃这个方案,他们已经完全沉浸于monorepo所带来的开发体验了(如即时生效的改动)。 你需不需要使用monorepo完全取决于你自己的需求!但实际情况是,需要使用monorepo的场景,其害处(如编译时间增加、代码仓库膨胀等)远不足以让团队放弃这个方案,他们已经完全沉浸于monorepo所带来的开发体验了(如即时生效的改动)。
这里提供一个quiz,满足下面三个要求就说明你适合monorepo: