一、Lerna 简介

Lerna 是基于 git + npm 的多 package 的项目的管理工具。也就是说项目是非 git 项目或者说非 npm 项目,则无法使用 lerna。

Lerna is a tool that optimizes the workflow around managing multi-package repositories with git and npm.

Lerna 是架构优化的产物,它揭示了一个架构真理:项目复杂度提升后,就需要对项目进行架构优化。架构优化的主要目标往往都是以效能为核心(即减少重复操作和操作标准化)。

Lerna 优势

  • 大幅减少重复操作
  • 提升操作标准化。举例:Lerna 设定了一个标准的 package 发布流程,在发布流程中 Lerna 会帮我们提升版本号(bump version)并帮我们进行很多检查,如代码是否提交。当完成所有检查之后会执行 npm 的发布流程。像这样的操作流程标准化是非常有利于我们管理大型项目。

Lerna 案例
使用 Lerna 管理的大型项目

二、lerna 开发脚手架流程

lerna 脚手架开发流程.png

2.1 全局安装 Lerna

  1. npm install -g lerna

2.2 创建项目

  1. mkdir cli-test && cd cli-test

2.3 使用 lerna 初始化项目

运行 lerna init 命令,该命令会初始化项目,并自动完成 git 初始化,但该命令不会创建 .gitignore,这个必须要手动添加,否则会将 node_modules 目录都上传到 git。

2.4 创建 Package

创建 Package 本质就是创建一个个项目的过程。

格式:

lerna create [loc]

其中:loc 表示自定义 package 的安装位置。

示例:

  1. # 创建 core package,其中 @cli-test 表示 npm 组织
  2. lerna create @cli-test/core packages
  3. # 创建 utils package
  4. lerna create @cli-test/utils packages

注:

如果 package 的 name 写成如下格式: "name": "@cli-test/core" ,则前面的 @cli-test 表示是 group name,即在 npm 上创建一个组织, core 表示组织后面创建的 package name 。

创建组织的好处是避免后面的 package name 在 npm 上出现重复,导致无法提交 npm 包。

2.5 安装依赖

  1. lerna add <package> [loc] --dev

其中:

  • 第一个参数,表示要添加的 npm 包名;
  • 第二个参数,表示要安装的本地 package 的路径;
  • 选项(可选):
    • --dev:将依赖安装到 devDependencies(注:不要弄反),不加时会安装到 dependencies。

示例

  1. # 给所有的 package 安装依赖
  2. lerna add lodash
  3. # 给指定的 package 安装依赖
  4. lerna add axios packages/core --dev

2.6 删除依赖

  1. # 删除所有 package 的依赖,相当于删除所有 package 下的 node_modules
  2. lerna clean

2.7 重装依赖

  1. # 可以帮我们做发布前的一些准备工作,比如 npm install、npm prepublish
  2. lerna bootstrap

Bootstrap the packages in the current Lerna repo. Installs all of their dependencies and links any cross-dependencies.

When run, this command will:

  1. npm install all external dependencies of each package.
  2. Symlink(符号链接,即软链接) together all Lerna packages that are dependencies of each other.
  3. npm run prepublish in all bootstrapped packages (unless —ignore-prepublish is passed).
  4. npm run prepare in all bootstrapped packages.

2.8 执行 npm 命令

lerna run 相当于 npm run,可以帮我们执行 npm 命令。

  1. # 执行单元测试
  2. lerna run test
  3. # 执行指定 package 的单元测试
  4. lerna run test --scope @cli-test/core

2.9 链接 package

packages/core 目录下先手动添加 package 相关依赖,然后运行 lerna link 命令,即可自动创建软链接
WX20210826-102343.png

注:无需进入 packages/core 目录下运行该命令,在主目录下就可运行该命令。

2.10 提升版本号

  1. # 进行版本号升级
  2. lerna version

其中:

  • 选项Patch 表示打补丁;


2.11 查看上版本以来的所有变更

  1. lerna changed

2.12 用来查看 commit 之间的diff

  1. lerna diff

2.13 发布项目

lerna publish 命令用于进行项目的发布,它会执行一个标准的发布流程,在发布流程过程中会先执行lerna version 操作,然后再将项目发布至 npm 上。

在运行 lerna publish 命令发布项目的过程中,可能会出现如下 Warning 警告:
image.png

  • 针对这种警告,可以先在当前项目目录下创建 LICENSE.md 文件,空白文件即可;
  • 执行 lerna publish 前需先完成 npm login
  • 如果发布的 npm 包名为 @xxx/yyy 的格式,需要先在 npm 注册名为 xxx 的 organization,否则可能会提交不成功。

WX20210826-140215.png

  • 发布到 npm group 时默认情况下都是私有仓库,需将其改成公共仓库。修改package.json配置,如下所示

image.png

2.14 执行 shell 脚本

要删除所有 package 下的 node_modules。

  1. lerna exec -- rm -rf node_modules


通过指定--scope,则可在指定 package 目录下执行脚本,但要注意--scope后面跟的是包名(@cli-test/core),而不是文件夹名(packages/core)。

  1. lerna exec --scope @cli-test/core -- rm -rf node_modules

注:
lerna execlerna run 这两条命令存在一些差异,其中 lerna exec --scope--scope 属性后添加的是包名,而不是 package 的路径,这点和 lerna add 用法不同