【前端架构】大型前端项目的组织设计 - monorepo, lerna


首先介绍multirepo, monorepo概念。

multirepo

multirepo, 顾名思义,就是将应用按照模板分别在不同的仓库中进行管理。

monorepo

而monorepo就是将应用中的所有模块一股脑儿全部放在同一个项目中,不需要单独发包,测试,且所有代码都在一个项目中管理,一同部署上线,能够再开发阶段最早的发现bug, 发现问题。

Babel和React都是典型的monorepo, 其issues和Full Request都集中在唯一的项目中,changelog可以简单第从一份commits列表中梳理出来。

使用lerna实现monorepo

初始化

mkdir new-monorepo
cd new-monorepo
npm init -y
npm - -g monorepo
lerna init

以上初始化成功以后,会出现以下文件
packages
lerna.json
packages.json

新建子模块

mkdir module-1
cd module-1
npm init -y
mkdir module-2
cd module-2
npm init -y
mkdir module-3
cd module-3
npm init -y

然后,退回主目录,安装依赖。

cd 
lerna bootstrap

lerna bootstrap命令会简历整个项目内子应用和模块之前的依赖关系,这种建立关系不是通过硬安装,而是通过软链指向相关依赖的。

如果需要发布到npm中, 可以通过lerna publish来实现。

lerna publish

至此,你可能觉得lerna还挺简单,但其实里面还有更多学问。如Lerna支持以下两种模块。

Fixed/Locked模块

Independent模块

我们可以通过Lerna安装依赖,该命令可以再想买下的任何文件中执行。

Lerna add dependancyName

比如:Lerna add jquery

这种方式会在父文件夹的node_modules中高效安装dependencyName依赖(Node.js 会向上在祖先文件中查找依赖)。对于未开启hoist的情况。执行lerna add后执行以下命令。

lerna bootstrap --hoist

如果我们想选择的升级某个依赖,比如只想为module-1升级dependencyName依赖的版本,就可以使用scope参数。

lerna add dependencyName --scope-module-1

项目迁移至monorepo

步骤1: 使用lerna构建monorepo项目

mkdir my-new-monorepo && cd my-new-monorepo
git init
lerna init

步骤2:导入已有项目

lerna import ./demo --flatten

步骤3:依赖维护与发布

lerna bootstrap

在这里,并不是每次都需要执行lerna bootstrap, 在第一次切换到项目,安装所有依赖时执行一次即可。
受益于monorepo, 所有项目得以集中管理在一个仓库中,这样我们便可以将所有package中公共的npm脚本移到./scripts文件中,且可以再单一monorepo项目的不同包之间构建脚本了。

依赖关系简介

说到项目中的依赖关系,我们往往会想到使用yarn/npm解决依赖关系。依赖关系大体上可以分为嵌套依赖和扁平依赖。

对于嵌套依赖和扁平依赖,npm给出了不同的处理方案。npm3以下的版本在安装依赖时非常直接,它会按照包依赖的树形结构将其下载到本地node_modules目录中,也就是说,每个包会将该包的依赖放到当前包所在的node_modules中。

npm3 采用了扁平结构,在安装依赖包时更加智能,具体体现在:在安装依赖包时, npm3会按照package.json中声明的顺序依次安装包,遇到新的包就把它放在第一级node_modules目录中。后面再进行安装时,如果遇到一级node_modules目录已经存在的包,就会先判断包版本,如果版本一样则跳过安装,否则会按照npm2的方式安装在树形目录结构下。

npm3这种安装方式只能够解决依赖重复的问题,对于一些复杂场景,依然无法做到将依赖去重,这时候就用了 npm dedupe命令。

使用yarn workspace管理依赖关系

monorepo项目找那个的依赖管理问题知得重视。现在来看一下非常流行的yarn workspace是如何处理这种问题的。

待续。

posted @ 2021-04-12 07:02  攀登高山  阅读(721)  评论(0编辑  收藏  举报