lerna包管理

简述

目前项目使用lerna来进行包管理,已经停止维护

除了lerna以外,Rush也是一个非常不错的工具,lerna的停止维护目前看来是利好Rush

lernaRush解决的都是采用monorepo管理模式的项目

monorepo管理模式:monorepo是一种将多个package放在一个repo中的代码管理模式,摒弃了传统的多个package多个repo的模式

解决的问题:

  • 多个包多个项目难以维护和发布
  • 模块的升级需要手动修改包信息
  • 公用npm包的node_modules占用大量空间

带来的问题:

  • 单包的权限控制无法实现
  • 单项目过大的体积

使用lerna管理的包

目前Babel, React, Angular, Ember, Meteor, Jest等许多开源项目都使用该种模式来管理代码。

lerna基本使用

官方文档

官网过于简单,结合了几篇教程以及自己的实践结果来搭一个较为完整的monorepo

安装

npm install lerna -g

初始化

初始化git

在自己的github repositories中提前创建了一个空文件夹,并clone下来

初始化lerna

对应文件目录下执行lerna init, 对应生成两个文件一个文件夹

根目录的lerna.json可以用来配置一些全局性的东西,比如npmClient,项目使用yarn,这里就给他配置为yarnpnpm也是支持的,只需要正确配置包即可

lerna.json

1
2
3
4
5
6
7
8
{

"$schema": "node_modules/lerna/schemas/lerna-schema.json", // IDE 或其它工具将会根据目标地址中的 schema 定义对 JSON 文件进行检查和智能提示等等
"useNx": true, // 搭配Nx使用
"useWorkspaces": true, // 使用 Workspaces
"version": "0.0.0", // 版本
"npmClient": "yarn"
}

package.json

1
2
3
4
5
6
7
8
9
10
{
"name": "root",
"private": true, // 主包不发布
"workspaces": [ // 工作区范围
"packages/*"
],
"devDependencies": {
"lerna": "^5.5.0"
}
}

创建工具包

1
lerna create public-package

命令执行结果

代码结果

查看

根目录下执行,即可查看自己创建的包

1
lerna list

创建/导入项目

注意:导入和创建项目不会被计入lerna的包,即lerna list不会记录创建或导入的项目

全新的项目

可以直接cd packages去对应的包下创建文件夹npm init -y等等,或者直接使用脚手架npx create-react-app main-app创建新项目

已有的项目

使用如下命令

1
lerna import <project url>


装包

建立相互依赖的包之间的软连接并安装其他的依赖, 默认是npm i,因为我们指定过yarn,因此执行yarn install,会把所有包的依赖安装到根node_modules.

1
lerna bootstrap

向项目中添加依赖

1
lerna add <dependencies> --scope=<project>

组织Workspaces

通常起项目的时候,最好能在根目录配置对应的命令,这里可以参考yarn workspaces的组织方法

根目录下start命令意味着执行package.jsonnamereact-code-demostart命令

根目录package.json

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"name": "root",
"private": true,
"workspaces": [
"packages/*"
],
"devDependencies": {
"lerna": "^5.5.0"
},
"scripts": {
"start": "yarn workspace react-code-demo start"
}
}

项目react-code-demopackage.json

1
2
3
4
5
6
7
8
9
10
11
{
"name": "react-code-demo",
"version": "0.1.0",
"private": true,
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
... // 下面还有不展示了

动态更新

修改包对应的代码,无需重启,无需复制,由于对应包lerna都是软链到根目录node_modules,修改包信息会直接同步到顶层node_modules,因此刷新即可生效

发布

lerna提供两个指令

1
lerna changed

列出下次发版lerna publish要更新的包。

原理: 需要先git add,git commit 提交。 然后内部会运行git diff --name-only v版本号,搜集改动的包,就是下次要发布的,并不是网上人说的所有包都是同一个版全发布

1
lerna publish

首先对应的package.json要配置publishConfig,属于npm相关内容不再赘述,执行命令

会打tag,上传git,上传npm


基本使用如下,开发者可以根据需求自定义命令,如清理node_modules、是否需要依据package.lock.json等安装,五花八门,等发现更有价值的持续更新。

参考链接:

Lerna 中文详解教程:https://juejin.cn/post/6844903856153821198#heading-21
lerna.js:monorepos项目管理模式简单实践: https://developer.aliyun.com/article/1007301