关于javascript:monorepo大型前端仓库多项目管理基础篇

6次阅读

共计 2317 个字符,预计需要花费 6 分钟才能阅读完成。

monorepo 是啥

在版本控制系统中,monorepo 是一种软件开发策略,指将多我的项目的代码存储在同一仓库中。截止 2017 年,这种软件工程实际的各种模式曾经存在了二十多年,然而个别概念直到最近才被命名。
Google,Facebook,Microsoft,Uber,Airbnb, 以及 Twitter 均采纳了特地宏大的 monorepos,通过多样的策略去扩大用于宏大代码量和日常变更频次的构建零碎和版本控制软件
— 维基百科 https://en.wikipedia.org/wiki…

monorepo 与 multi-repo

multi-repo 的窘境

绝对于单个仓库来说开启新我的项目费时费事(创立仓库、我的项目架构(尽管有脚手架的话会不便些),多个我的项目汇总治理麻烦)
组件工具依赖复用及更新麻烦
反复装置公共依赖 react、react-dom 这些有多大都分明
本地我的项目调试麻烦,这个我的项目依赖了另一个我的项目,那么你只能用 npm link 的形式将它 link 到须要调试的我的项目外面。一旦 link 的我的项目多了,手动去治理这些 link 操作就容易心累。

monorepo 劣势与局限

劣势

便于代码复用
简化依赖治理
原子性提交(当一项工作散布在不同的仓库时,公布须要按肯定程序进行,当我的项目足够大时治理依赖间多样的版本会造成依赖天堂)
大型代码重构,便于确保整体性能重构后的可用性
跨团队合作灵便的代码从属关系,大家都能够参加改良

局限

短少独立我的项目的版本信息
短少独立我的项目的权限管制
须要更多的默认存储空间

随着前端我的项目的日益简单,某些业务或者工具库通常波及很多个仓库,工夫一长,多个仓库(MultiRepo)的开发弊病日益露出,monorepo 的治理形式失去了更多利用。

目前很多开源我的项目都用了 monorepo,比方 VUE、REACT、Babel。
大家能够看一下 React 和 Vue3 的我的项目构造:
https://github.com/facebook/r…
https://github.com/vuejs/vue-…

monorepo 要解决的问题

如何使同一仓库中的各个我的项目放弃其独立性?

  1. 独立构建、打包、公布
  2. 公共模块及依赖间包的版本升级治理

常见解决方案

  1. 较根底的 Lerna+Yarn Workspaces,提供根本的多包依赖治理及独立公布性能

Lerna 是一个治理多个 npm 模块的工具,是 Babel 本人用来保护本人的 Monorepo 并开源出的一个我的项目。优化保护多包的工作流,解决多个包相互依赖,且公布须要手动保护多个包的问题。
yarn workspaces 是一种治理软件包的形式,与 lerna 在包治理上有一部分的性能重合;

yarn workspaces 的利用:vue、react
来看看 lerna 的应用。babel/babel, facebook/jest, alibaba/rax、taro、umi

在包治理上 yarn 绝对与 lerna 能够缩小包的反复装置,lerna 则在分包构建公布上比拟有有劣势。所以有的我的项目联合了二者的长处进行了多项目管理的方案设计

2.Rush Stack(微软 + 开源)、Bazel 构建零碎 (Google)、Buck 构建零碎 (Facebook)、Nx 等,提供从初始化、开发、构建、测试到部署的全流程能力,有一套比拟残缺的 Monorepo 基础设施,但定制,适配老本高。

Lerna+Yarn Workspaces 实际

这里只依据根底性能列出了包治理生命周期中的要害命令,具体的代码以及 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
正文完
 0