Loading... Lerna 是一个管理工具,用于管理包含多个软件包(package)的 JavaScript 项目。在许多大型项目中我们都能看到 Lerna.js 的身影,比如前端知名的工具库 React 就是使用 Lerna.js 管理多个软件包的。 下面创建了一个简单的项目,我们就通过这个项目来了解 Lerna.js 是如何管理多个软件包的。 <!--more--> ## 项目初始化 这里分 3 小节来初始化一个 lerna 项目。 ### 初始化 npm 项目 创建一个项目文件夹 smpower-cli-dev,执行 `npm init -y` 来初始化一个 npm 项目。 ```shell npm init -y ``` 此时,npm 会在项目根目录创建一个 `package.json` 文件,文件中描述了该项目的一些基础信息。 ### 安装 Lerna 安装 Lerna.js 有两种方式,一种是在项目内安装 Lerna.js,另一种是以全局的形式安装。两种方式各有利弊,项目内安装 Lerna.js 能保证多个项目之间 Lerna.js 的版本能各自隔离开来,不会互相影响,但使用 lerna 命令会稍微麻烦一点。全局安装 Lerna.js 则会使多个项目的 lerna 版本统一为一个,在任何项目都能访问到 lerna 的命令,缺点是不能在各项目之间分别管理 lerna。根据开发经验来开,这里推荐使用全局安装的方式,各项目见不必单独维护 lerna 的版本。 要在全局安装 Lerna.js,可在终端执行以下命令: ```shell npm i -g lerna # or `npm i -g --global-style lerna` ``` ### lerna init 初始化项目 全局安装 Lerna.js 完成后,便可以初始化一个多软件包的项目了。初始化 lerna 项目的命令如下: ```shell 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 管理的软件包。命令如下: ```shell $ 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`: ```shell lerna create utils ``` 现在 `packages` 文件夹内已经有了两个软件包:`core` 和 `utils`。 #### 安装全局软件包依赖 假如要在 `core` 和 `utils` 两个软件包中安装同一个依赖,比如安装 `babel-core`,可在终端执行下面的命令: ```shell lerna add babel-core ``` 安装完成后,检查 `core` 和 `utils` 软件包中的 `package.json` 文件,我们发现 `babel-core` 已被添加到了 `dependencies` 中。 如果只想在 `core` 软件包中安装 `babel-core` 依赖该怎么做呢? #### 安装单个软件包依赖 首先我们将安装的 `babel-core` 依赖清空: ```shell lerna clean ``` 之后将 `babel-core` 安装到 `core` 软件包: ```shell lerna add babel-core packages/core ``` 此时,我们会复现在 `core` 软件包的 `package.json` 文件中安装了 `babel-core` 依赖,而 `utils` 软件包中并没有安装 `babel-core`。 #### 安装多个软件包依赖 还有一种情况也是给指定软件包安装依赖,不过这种方式有点类似给一类软件包安装依赖而非只给单独一个软件包安装。比如: ```shell lerna add babel-core packages/prefix-* ``` 这句话的意思是,给所有以 `prefix-` 开头的软件包都安装 `babel-core`。有时我们会以这种方式来管理一类软件包共有的第三方依赖。 ### lerna link 链接依赖 `lerna link` 与 `npm link` 的功能是相同的,而 `lerna link` 却比 `npm link` 更容易管理本地多个软件包之间的软连接。当本地软件包中存在互相引用的情况时,可以用 `lerna link` 一键生产软连接。 比如,要在 `core` 软件包中引用 `utils` 软件包,可以这样做: 在 `core` 软件包中的 `package.json` 文件中添加 `utils` 软件包依赖: ```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" }, "dependencies": { "@smpower-cli-dev/utils": "^1.0.0" } } ``` 注意 `dependencies` 属性,该对象中添加的是一个本地依赖 `utils` 软件包。该软件包的版本为 1.0.0,之后我们用 `lerna link` 就能在本地建立软连接,如下: ```json lerna link ``` 当执行上面的命令后,在 `core` 软件包内会将本地的 `utils` 软件包链接过来。而且我们会发现在 `core` 软件包中出现了一个 `node_modules` 文件夹,而 `@smpower-cli-dev/utils` 是一个软连接,链接到 `packages` 文件夹下的 `utils` 软件包。 这时,在 `core/lib/core.js` 文件中就能引用 `utils` 依赖的方法了。  如果本地软件包之间没有互相依赖的情况,执行 `lerna link` 是没有什么作用的。 当我们调试完本地的软件包之后,就可以将软件包发布到 npm 上了。这时,可以用 `lerna clean` 将各软件包的 `node_modules` 文件夹清除,之后再执行 `lerna bootstrap` 重新安装各个软件包的依赖,这时安装的依赖就是我们已经发布到 npm 上的软件包了。 以上,希望对你有所帮助。 Last modification:November 22, 2022 © Allow specification reprint Support Appreciate the author AliPayWeChat Like 0 如果觉得我的文章对你有用,请随意赞赏