Lerna 是一个管理工具,用于管理包含多个软件包(package)的 JavaScript 项目。在许多大型项目中我们都能看到 Lerna.js 的身影,比如前端知名的工具库 React 就是使用 Lerna.js 管理多个软件包的。

下面创建了一个简单的项目,我们就通过这个项目来了解 Lerna.js 是如何管理多个软件包的。

项目初始化

这里分 3 小节来初始化一个 lerna 项目。

初始化 npm 项目

创建一个项目文件夹 smpower-cli-dev,执行 npm init -y 来初始化一个 npm 项目。

npm init -y

此时,npm 会在项目根目录创建一个 package.json 文件,文件中描述了该项目的一些基础信息。

安装 Lerna

安装 Lerna.js 有两种方式,一种是在项目内安装 Lerna.js,另一种是以全局的形式安装。两种方式各有利弊,项目内安装 Lerna.js 能保证多个项目之间 Lerna.js 的版本能各自隔离开来,不会互相影响,但使用 lerna 命令会稍微麻烦一点。全局安装 Lerna.js 则会使多个项目的 lerna 版本统一为一个,在任何项目都能访问到 lerna 的命令,缺点是不能在各项目之间分别管理 lerna。根据开发经验来开,这里推荐使用全局安装的方式,各项目见不必单独维护 lerna 的版本。

要在全局安装 Lerna.js,可在终端执行以下命令:

npm i -g lerna # or `npm i -g --global-style lerna`

lerna init 初始化项目

全局安装 Lerna.js 完成后,便可以初始化一个多软件包的项目了。初始化 lerna 项目的命令如下:

lerna init

执行上面的命令后,lerna 会帮我们在项目根目录做两件事:

  1. 创建 lerna.json 配置文件以及创建一个用于存放软件包的 package 文件夹;
  2. 自动执行 git init 的操作,帮助我们初始化 git 项目。

lerna.json 配置文件中默认会有一个 version 的属性,表示 lerna 项目的版本号。除此以外或许也会有一些其他的配置项,初始化 Lerna 项目后会因平台的不同略有差异。

管理 package(软件包)

完成项目初始化工作后,即可使用 Lerna 来创建 package 了。

lerna create 创建 package

在终端工具中,可通过 Lerna.js 的 lerna create 命令来创建由 Lerna.js 管理的软件包。命令如下:

$ lerna create core
info cli using local version of lerna
lerna notice cli v6.0.3
lerna WARN ENOREMOTE No git remote found, skipping repository property
package name: (core) @smpower-cli-dev/core
version: (0.0.0) 1.0.0
description: smpower-cli-dev core
keywords:
homepage:
license: (ISC)
entry point: (lib/core.js)
git repository:
About to write to E:\repos\smpower-cli-dev\packages\core\package.json:

{
  "name": "@smpower-cli-dev/core",
  "version": "1.0.0",
  "description": "smpower-cli-dev core",
  "author": "Randal <randal@foxmail.com>",
  "homepage": "",
  "license": "ISC",
  "main": "lib/core.js",
  "directories": {
    "lib": "lib",
    "test": "__tests__"
  },
  "files": [
    "lib"
  ],
  "publishConfig": {
    "registry": "https://registry.yarnpkg.com/"
  },
  "scripts": {
    "test": "node ./__tests__/core.test.js"
  }
}


Is this OK? (yes)
lerna success create New package @smpower-cli-dev/core created at ./packages\core

上面创建了一个名为 core 的软件包,在执行 lerna create 命令时,Lerna.js 会让我们填写一些关于 core 软件包的描述信息,比如:包名、版本号、软件包描述等。当成功创建 core 软件包后,Lerna 会在项目根目录的 packages 文件夹内创建一个叫做 core 的项目。core 项目与我们常见的 npm 项目没什么不同,同样都可以安装依赖,不过在这里我们通常不把它叫做项目,而是一个由 Lerna.js 管理的软件包。并且在我们安装第三方依赖时不再使用 npm 或 yarn 来管理了,而是使用 Lerna.js 提供的 lerna add 命令添加依赖。

lerna create 命令的使用也很简单,命令后跟一个需要创建的包名即可:

lerna create <name> [loc]

name 参数就是我们要创建的包名,而后面的 loc 参数则可以指定要创建的软件包的位置,默认是在当前项目的 packages 文件夹内创建软件包。

lerna create 命令还提供了许多参数,可通过 lerna create --help 命令来查阅 lerna create 的用法和它提供的额外参数。

lerna add 安装依赖

上面提到对软件包依赖的管理不再使用 npm 或 yarn 了,而是通过 lerna add 来管理指定软件包的第三方依赖。lerna add 命令能让我们管理全局软件包的依赖和管理指定的某个/某些软件包的依赖。

为了便于理解,这里再创建一个软件包 utils

lerna create utils

现在 packages 文件夹内已经有了两个软件包:coreutils

安装全局软件包依赖

假如要在 coreutils 两个软件包中安装同一个依赖,比如安装 babel-core,可在终端执行下面的命令:

lerna add babel-core

安装完成后,检查 coreutils 软件包中的 package.json 文件,我们发现 babel-core 已被添加到了 dependencies 中。

如果只想在 core 软件包中安装 babel-core 依赖该怎么做呢?

安装单个软件包依赖

首先我们将安装的 babel-core 依赖清空:

lerna clean

之后将 babel-core 安装到 core 软件包:

lerna add babel-core packages/core

此时,我们会复现在 core 软件包的 package.json 文件中安装了 babel-core 依赖,而 utils 软件包中并没有安装 babel-core

安装多个软件包依赖

还有一种情况也是给指定软件包安装依赖,不过这种方式有点类似给一类软件包安装依赖而非只给单独一个软件包安装。比如:

lerna add babel-core packages/prefix-*

这句话的意思是,给所有以 prefix- 开头的软件包都安装 babel-core。有时我们会以这种方式来管理一类软件包共有的第三方依赖。

lerna link 链接依赖

lerna linknpm link 的功能是相同的,而 lerna link 却比 npm link 更容易管理本地多个软件包之间的软连接。当本地软件包中存在互相引用的情况时,可以用 lerna link 一键生产软连接。

比如,要在 core 软件包中引用 utils 软件包,可以这样做:

core 软件包中的 package.json 文件中添加 utils 软件包依赖:

{
  "name": "@smpower-cli-dev/core",
  "version": "1.0.0",
  "description": "smpower-cli-dev core",
  "author": "Randal <randal@foxmail.com>",
  "homepage": "",
  "license": "ISC",
  "main": "lib/core.js",
  "directories": {
    "lib": "lib",
    "test": "__tests__"
  },
  "files": [
    "lib"
  ],
  "publishConfig": {
    "registry": "https://registry.yarnpkg.com/"
  },
  "scripts": {
    "test": "node ./__tests__/core.test.js"
  },
  "dependencies": {
    "@smpower-cli-dev/utils": "^1.0.0"
  }
}

注意 dependencies 属性,该对象中添加的是一个本地依赖 utils 软件包。该软件包的版本为 1.0.0,之后我们用 lerna link 就能在本地建立软连接,如下:

lerna link

当执行上面的命令后,在 core 软件包内会将本地的 utils 软件包链接过来。而且我们会发现在 core 软件包中出现了一个 node_modules 文件夹,而 @smpower-cli-dev/utils 是一个软连接,链接到 packages 文件夹下的 utils 软件包。

这时,在 core/lib/core.js 文件中就能引用 utils 依赖的方法了。

 title=

如果本地软件包之间没有互相依赖的情况,执行 lerna link 是没有什么作用的。

当我们调试完本地的软件包之后,就可以将软件包发布到 npm 上了。这时,可以用 lerna clean 将各软件包的 node_modules 文件夹清除,之后再执行 lerna bootstrap 重新安装各个软件包的依赖,这时安装的依赖就是我们已经发布到 npm 上的软件包了。

以上,希望对你有所帮助。

Last modification:November 22, 2022
如果觉得我的文章对你有用,请随意赞赏