随着公司业务的拓展,项目体积逐渐变得庞大,为了减少线上bug出现率和提升核心业务场景的稳定性,我们需要对一些核心业务和公共方法进行抽取拆分为独立的包的方式进行维护管理。这个时候我们就面临着新的难题:拆分项目多,项目之间依赖引用关系复杂,项目之间第三方依赖版本不一致,开发调试困难。
经过一番技术调研之后,我们最终决定采用 Lerna 管理的多仓模式来替换之前的单一仓库模式。(下面我们的介绍的内容本质上与模块提取没有直接关联,只是基于这样的背景来展开)。
什么是Lerna
开始之前,我们先对Lerna来一个简单的自我介绍。
Lerna 是一种工具,针对 使用 git 和 npm 管理多软件包代码仓库的工作流程进行优化
看完官方的解释之后,我们用大白话来解释一下,Lerna是一个辅助我们对多个依赖包统一进行管理的工具,借助于git和包管理工具(NPM、Yarn、pnpm)将我们本来面临的多个git项目之间的操作流程进行优化,方便我们对多个项目进行开发与管理。
Lerna实战
初始化项目
兵马未动,粮草先行。我们在初始化项目之前,需要先进行一些准备工作。
- 全局安装Lerna依赖
csharp
yarn add lerna global
npm install --global lerna
- 创建git仓库,用来进行代码管理
csharp
git init lerna-demo
ok,准备工作完成了,我们就开始初始化Lerna项目了。
bash
lerna init [--independent/-i]
参数说明
Lerna的工作模式有两种:固定模式和独立模式。如果init的时候传入参数 --independent 的话,表明使用独立模式,不添加任何参数的时候默认采用固定模式。
那如果项目已经初始化,但是由于某些原因需要调整工作模式的话,我们应该怎么操作呢?其实很简单,我们只需要调整lerna.json文件中version配置就可以了,如果version设置为independent的话,表示我们使用独立模式,如果改为 x.x.x
这样的版本号的话,表示我们使用固定模式。
Lerna两种工作模式的差异
- 固定模式
当我们进行发布依赖的时候,只会根据lerna.json中的version字段进行增加,确认一次版本号,所有改动的包都会使用这个版本号进行发布。
- 独立模式
独立模式跟固定模式的不同就在于版本号,独立模式会在发布的时候跟根据每个有改动的包的package.json中的version进行版本号的确认,也就是说,我们可以对每个包发布不同的版本号。
创建包
我们通常都会将多个包放置到packages文件夹下,假设我们有三个包,分别是A、B、C,那么我们就先通过Lerna命令进行创建包。
lua
lerna create A
lerna create B
lerna create C
当包创建好之后,我们的目录结构会如下:
go
├── lerna.json
├── package.json
└── packages
├── A
| └── package.json
├── B
| └── package.json
└── C
| └── package.json
我们也可以通过 lerna ls
来查看我们的Lerna仓库中的所有包(设置了private:false的包除外)。
css
info cli using local version of lerna
lerna notice cli v6.0.3
A
B
C
lerna success found 3 packages
安装依赖
包创建好了,接下来我们就需要添加依赖,然后进行功能开发了。
假设我们三个包都依赖于rollup的话,那么我们需要lerna add
的方式为每个包统一添加依赖:
sql
lerna add rollup
如果我们的B包额外还需要使用dayjs这个第三方依赖,那么我们就需要使用lerna add --scope
的方式为B包单独安装依赖:
css
lerna add dayjs --scope=B
运行
依赖安装完成之后,这个时候我们就需要运行包,然后进行具体的功能开发了。
在普通的项目中,我们需要进入到项目的package.json所在的位置执行 npm run xxx
来运行项目。如果Lerna项目也要这样操作的话,就会很麻烦,需要启用多个命令行。幸好Lerna为我们提供了 lerna run xxx
的命令,我们可以通过这个命令为每一个包执行同一个script命令。
arduino
lerna run start
发布包
我们经过一番辛苦开发之后,功能终于开发完成了,接下来我们就要将代码发布到仓库中。
在发布之前我们需要先构建一下包,这里我们通过前面说到的lerna run
命令来进行统一打包构建。
css
lerna run build
lerna publish [--force-publish] [package]
Lerna发布包是基于git的,所以我们在发布到仓库的时候需要先将本地代码推送到远程仓库中。如果没有推送的话,Lerna会告诉我们没有变动,没有任何依赖需要进行发布。
有的时候我们有特殊需求,需要保证所有的包下的依赖的版本号保持一致。但是,Lerna默认的机制只会发布我们发生变动的包,这个时候我们就需要用到强制发布包lerna publish --force-publish
。如果我们只需要重新发布某个包的话,我们只需要在最后添加上package包名就行了。
结尾
Lerna对于我们进行多仓管理非常好用。自从使用了一次Lerna之后,真香。
希望上面有关Lerna的内容对大家有所帮助,如果大家有疑问或者其它观点,可以在下方进行留言交流。