lerna管理好你的packages

前言

最近在研究包管理相关的东西,于是发现了lerna

什么是Lerna

Lerna是一个管理多个node模块的工具,是Babel自己用来维护自己的Monorepo并开源出的一个项目。Lerna现在已经被很多著名的项目组织使用。

Monorepo

Monorepo的全程是monolithic repository,即单体式仓库,与之对应的是Multirepo(multiple repository)。以下是两者的区别。

Monorepo是把所有相关的module放在一个仓库中进行管理,每个module独立发布,优缺点总结如下:

优点
* 版本更新简单便捷,core repo 以及各模块版本发生变化后可以简便的同步更新其他对其有依赖的module
* 管理简单,issue readme pr 都放在一起维护
* changelog 方便维护,所有的修改基于一个commit列表

缺点
* 仓库体积增长迅速,随着module的增多,仓库的体积也会变得庞大。
* 自由度不高,对统一的配套工具要求较高,要适配每个module的要求。

Multirepo相对来说比较传统,没一个组件都单独用一个仓库来维护管理,优缺点如下:

优点
* 每个模块可自行管理,自由度高,可自行选择构建工具等相关工具。
* 每个仓库体积较小

缺点
* 项目管理混乱,issue 经常出现针对其他module的问题,需要更多精力维护。
* changlog 无法关联,无法很好的自动关联各个 module 与 core repo 之间的变动联系
* 版本更新繁琐,如果 core repo 的版本发生了变化,需要对所有的 module 进行依赖 core repo 的更新
* 测试复杂,对多个相关联 module 测试繁琐

Babel为了解决上面的问题,于是诞生了Lerna,Lerna可以通过git和npm帮助我们来优化管理Monorepo的工作流,同时较少开发和构建环境中对大量依赖包复制的时间和控件需求。

初始化一个Lerna工程

一个基本的Lerna仓库结构如下

.
├── lerna.json
├── package.json
└── packages
    ├── module-1
    ├── module-2
    └── module-3

首先要创建一个Lerna项目
我们要全局安装Lerna

npm i -g lerna
mkdir lerna-demo && cd $_
lerna init

Lerna提供两种不同的方式来管理你的项目:Fixed或Independent,默认采用Fixed模式,如果你想采用Independent 模式,只需在执行init命令的时候加上–independent或-i参数即可。

Fixed/Locked 模式(默认)

固定模式下Lerna项目在单一版本线上运行。版本号保存在项目根目录下lerna.json文件中的version下。当你运行lernapublish时,如果一个模块自上次发布版本以后有更新,则它将更新到你将要发布的新版本。这意味着你在需要发布新版本时只需发布一个统一的版本即可。

Independent 模式(–independent)

独立模式下Lerna允许维护人员独立地的迭代各个包版本。每次发布时,你都会收到每个发生更改的包的提示,同时来指定它是patch,minor,major还是自定义类型的迭代。

Lerna 实践

为了能够使lerna发挥最大的作用,根据这段时间使用Lerna的经验,总结出一个最佳实践。下面是一些特性。

  • 采用Independent模式
  • 根据Git提交信息,自动生成changelog
  • eslint规则检查
  • prettier自动格式化代码
  • 提交代码,代码检查hook
  • 遵循semver版本规范

工具整合

在这里引入的工具都是为了解决一个问题,就是工程和代码的规范问题。
* husky
* lint-staged
* prettier
* eslint