在版本控制系统中,monorepo是一种软件开发策略,指将多项目的代码存储在同一仓库中。截止2017年,这种软件工程实践的各类形式已经存在了二十多年,可是通常概念直到最近才被命名。
Google,Facebook,Microsoft,Uber,Airbnb,以及Twitter均采用了特别庞大的monorepos,经过多样的策略去扩展用于庞大代码量和平常变动频次的构建系统和版本控制软件
---维基百科 https://en.wikipedia.org/wiki...前端
相对于单个仓库来讲开启新项目费时费事(建立仓库、项目架构(虽然有脚手架的话会方便些),多个项目汇总管理麻烦)
组件工具依赖复用及更新麻烦
重复安装公共依赖react、react-dom这些有多大都清楚
本地项目调试麻烦,这个项目依赖了另外一个项目,那么你只能用 npm link 的方式将它 link 到须要调试的项目里面。一旦 link 的项目多了,手动去管理这些 link 操做就容易心累。vue
便于代码复用
简化依赖管理
原子性提交(当一项工做分布在不一样的仓库时,发布须要按必定顺序进行,当项目足够大时管理依赖间多样的版本会形成依赖地狱)
大型代码重构,便于确保总体功能重构后的可用性
跨团队协做灵活的代码从属关系,你们均可以参与改进node
缺乏独立项目的版本信息
缺乏独立项目的权限控制
须要更多的默认存储空间react
随着前端项目的日益复杂,某些业务或者工具库一般涉及不少个仓库,时间一长,多个仓库(MultiRepo)的开发弊端日益显露,monorepo的管理方式获得了更多应用。git
目前不少开源项目都用了 monorepo,好比VUE、REACT、Babel。
你们能够看一下React和Vue3的项目结构:
https://github.com/facebook/r...
https://github.com/vuejs/vue-...github
如何使同一仓库中的各个项目保持其独立性?typescript
Lerna 是一个管理多个 npm 模块的工具,是 Babel 本身用来维护本身的 Monorepo 并开源出的一个项目。优化维护多包的工做流,解决多个包互相依赖,且发布须要手动维护多个包的问题。
yarn workspaces 是一种管理软件包的方式,与lerna在包管理上有一部分的功能重合;npm
yarn workspaces的应用: vue、react
来看看lerna的使用。babel/babel, facebook/jest, alibaba/rax 、taro、umi json
在包管理上yarn相对与lerna能够减小包的重复安装,lerna则在分包构建发布上比较有有优点。因此有的项目结合了两者的优势进行了多项目管理的方案设计babel
2.Rush Stack(微软+开源)、Bazel构建系统 (Google)、Buck构建系统 (Facebook)、Nx等,提供从初始化、开发、构建、测试到部署的全流程能力,有一套比较完整的 Monorepo 基础设施,但定制,适配成本高。
这里只根据基础功能列出了包管理生命周期中的关键命令,详细的代码以及lerna包管理实现的原理你们感兴趣的话能够点赞搜藏关注后续分析~~
需求:各package独立打包:有公用打包配置的能力
//包安装、同时安装各个子包须要的依赖 yarn install yarn workspace cli add cli-shared-utils //将cli-shared-utils做为cli的依赖进行安装 yarn workspaces add lodash //给全部的package安装依赖: yarn add -W -D typescript //给root 安装公用的依赖 //清理环境 lerna clean //清理全部的node_modules //按顺序构建(各个package之间存在相互依赖,如packageB只有在packageA构建完以后才能进行构建,不然就会出错,须要按拓扑排序的规则进行构建) lerna run --stream --sort build
两种模式:
Independent mode:结合Git,检查文件变更,只发布有改动的packge。(设置方式1:建立项目的时候 能够经过 lerna init --independent 命令,启用独立模式管理软件包。设置方式2:修改 lerna.json 的 version 字段,修改成 independent, 用来开启独立模式)
Fixed/Locked mode(默认):把工程看成一个总体来对待。每次发布packges,都是全量发布,不管是否修改
//更新版本 //找出从上一个版本发布以来有过变动的 package //提示开发者肯定要发布的版本号 //将全部更新过的的 package 中的package.json的version字段更新 //将依赖更新过的 package 的 包中的依赖版本号更新 //更新 lerna.json 中的 version 字段 //根据commit信息自动生成该版本的CHANGELOG (配置conventionalCommits) //提交上述修改,并打一个 tag //推送到 git 仓库 lerna version //更新版本 //发布新包 lerna publish //包含了lerna version