一、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 管理的大型项目
- babel: https://github.com/babel/babel
- vue-cli: https://github.com/vuejs/vue-cli
- create-react-app: https://github.com/facebook/create-react-app
二、lerna 开发脚手架流程
2.1 全局安装 Lerna
npm install -g lerna
2.2 创建项目
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 的安装位置。
示例:
# 创建 core package,其中 @cli-test 表示 npm 组织
lerna create @cli-test/core packages
# 创建 utils package
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 安装依赖
lerna add <package> [loc] --dev
其中:
- 第一个参数,表示要添加的 npm 包名;
- 第二个参数,表示要安装的本地 package 的路径;
- 选项(可选):
--dev
:将依赖安装到 devDependencies(注:不要弄反),不加时会安装到 dependencies。
示例:
# 给所有的 package 安装依赖
lerna add lodash
# 给指定的 package 安装依赖
lerna add axios packages/core --dev
2.6 删除依赖
# 删除所有 package 的依赖,相当于删除所有 package 下的 node_modules
lerna clean
2.7 重装依赖
# 可以帮我们做发布前的一些准备工作,比如 npm install、npm prepublish
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:
- npm install all external dependencies of each package.
- Symlink(符号链接,即软链接) together all Lerna packages that are dependencies of each other.
- npm run prepublish in all bootstrapped packages (unless —ignore-prepublish is passed).
- npm run prepare in all bootstrapped packages.
2.8 执行 npm 命令
lerna run
相当于 npm run
,可以帮我们执行 npm 命令。
# 执行单元测试
lerna run test
# 执行指定 package 的单元测试
lerna run test --scope @cli-test/core
2.9 链接 package
在 packages/core
目录下先手动添加 package 相关依赖,然后运行 lerna link
命令,即可自动创建软链接。
注:无需进入 packages/core
目录下运行该命令,在主目录下就可运行该命令。
2.10 提升版本号
# 进行版本号升级
lerna version
其中:
- 选项
Patch
表示打补丁;
2.11 查看上版本以来的所有变更
lerna changed
2.12 用来查看 commit 之间的diff
lerna diff
2.13 发布项目
lerna publish
命令用于进行项目的发布,它会执行一个标准的发布流程,在发布流程过程中会先执行lerna version
操作,然后再将项目发布至 npm 上。
在运行 lerna publish
命令发布项目的过程中,可能会出现如下 Warning 警告:
- 针对这种警告,可以先在当前项目目录下创建
LICENSE.md
文件,空白文件即可; - 执行
lerna publish
前需先完成npm login
- 如果发布的 npm 包名为
@xxx/yyy
的格式,需要先在 npm 注册名为xxx
的 organization,否则可能会提交不成功。
- 发布到 npm group 时默认情况下都是私有仓库,需将其改成公共仓库。修改package.json配置,如下所示
2.14 执行 shell 脚本
要删除所有 package 下的 node_modules。
lerna exec -- rm -rf node_modules
通过指定--scope
,则可在指定 package 目录下执行脚本,但要注意--scope
后面跟的是包名(@cli-test/core),而不是文件夹名(packages/core)。
lerna exec --scope @cli-test/core -- rm -rf node_modules
注:lerna exec
和 lerna run
这两条命令存在一些差异,其中 lerna exec --scope
的 --scope
属性后添加的是包名,而不是 package 的路径,这点和 lerna add 用法不同。