本备忘单旨在快速理解 Lerna v6 所涉及的主要概念,显示了它的常用命令使用清单
现代构建系统,用于管理和发布来自同一存储库的多个 JavaScript/TypeScript 包。
$ npx lerna@latest init
下面是示例目录结构
├── README.md
├── remixapp # web 应用 (remixapp)
│ ├── src
│ └── package.json
│
├── packages
│ ├── footer # 组件(@remixapp/footer)
│ │ ├── src
│ │ └── package.json
│ │
│ └── header # 组件(@remixapp/header)
│ ├── src
│ └── package.json
│
├── lerna.json
└── package.json
它在 package.json
中依赖于它们,如下所示:
"dependencies": {
// ....
"@remixapp/header": "*",
"@remixapp/footer": "*"
}
remixapp
应用程序导入页眉
和页脚
库,如下所示:
import { Header } from "header";
import { Footer } from "footer";
export default function Home() {
return (
<>
<Header />
<div>Content!</div>
<Footer />
</>
);
}
{
"$schema": "node_modules/lerna/schemas/lerna-schema.json",
"useWorkspaces": true,
"version": "0.0.0"
}
在 lerna.json
中配置 useWorkspaces
告诉
Lerna
将包链接过程委托给你的包管理器 (此功能由 npm、yarn 和 pnpm 支持)。
npx lerna run test --scope=header # 单个
多个任务运行
npx lerna run test --scope=header,footer
忽略 header
,footer
其它包中运行任务运行
npx lerna run build --ignore=header,footer
# 在所有包含它的包中运行 npm run my-script
$ lerna run <script> -- [..args]
$ lerna run test
$ lerna run build
# 观看所有包并在更改时转换,流式前缀输出
$ lerna run --parallel watch
# 在所有包中运行命令
$ lerna exec -- <command> [..args]
$ lerna exec -- rm -rf ./node_modules
$ lerna exec -- protractor conf.js
:- | :- |
---|---|
--npm-client <client>
#
|
必须是知道如何运行 npm 生命周期脚本的可执行文件,默认值是 npm |
--stream
#
|
立即从子进程流式输出,以原始包名称为前缀 |
--parallel
#
|
类似于
--stream
但完全忽略并发和拓扑排序,立即在所有匹配的包中运行给定的命令或脚本,并带有前缀流输出
|
--no-bail
#
|
默认情况下,如果任何脚本运行返回非零退出代码,lerna run 将退出并出现错误。传递
--no-bail 以禁用此行为
|
--no-prefix
#
|
当输出为流式传输(--stream 或
--parallel )时禁用包名称前缀。当将结果传送到其他进程(例如编辑器插件)时,此选项很有用
|
--profile
#
|
分析脚本执行并生成性能配置文件 |
--profile-location <location>
#
|
您可以为性能配置文件输出提供自定义位置。提供的路径将相对于当前工作目录进行解析。 |
useNx=false
#
|
通过将 useNx 设置为 false ,您可以使用
lerna 中的遗留任务运行实现 (p-map 和
p-queue ),而不是使用由
Nx 提供支持的默认现代任务运行器实现。
|
# 发布自上次发布以来已更改的软件包
$ lerna publish
# 显式发布在当前提交中标记的包
$ lerna publish from-git
# 显式发布注册表中不存在最新版本的软件包
$ lerna publish from-package
# 使用下一个语义预发布版本,例如
$ lerna publish --canary
# 1.0.0 => 1.0.1-alpha.0+${SHA}
# 自上次提交以来更改的包
# 随后的金丝雀发布将产生1.0.1-alpha.1+${SHA}等
$ lerna publish --canary --preid beta
# 1.0.0 => 1.0.1-beta.0+${SHA}
# 以下是等价的:
$ lerna publish --canary minor
$ lerna publish --canary preminor
# 1.0.0 => 1.1.0-alpha.0+${SHA}
:- | :- |
---|---|
--canary
#
|
使用此标志运行时,以更精细的方式(每次提交)发布包 |
--contents <dir>
#
|
要发布的子目录。 必须适用于所有包,并且必须包含 package.json 文件
|
--dist-tag <tag>
#
|
使用此标志运行时,将使用给定的 npm dist-tag (默认为 latest )发布到
npm
|
--git-head <sha>
#
|
打包 tarball 时将显式 SHA 设置为清单上的
gitHead ,仅允许使用 from-package 位置
|
--graph-type <all|dependencies>
#
|
设置在构建包图时使用哪种依赖项。默认值是依赖项,即仅包含包的
package.json 的依赖项部分中列出的包
|
--ignore-scripts
#
|
传递时,此标志将在 lerna 发布期间禁用运行生命周期脚本
|
--ignore-prepublish
#
|
传递时,此标志将禁用在 lerna 发布期间运行已弃用的预发布脚本
|
--legacy-auth
#
|
发布需要身份验证的包时,您正在使用仅使用旧版 Base64
用户名:密码 的内部托管 NPM 注册表。这与 NPM 发布 _auth 标志相同
|
--no-git-reset
#
|
默认情况下,lerna publish 确保对工作树的任何更改都已重置 |
--no-granular-pathspec
#
|
默认情况下,lerna publish 将尝试(如果启用)git checkout
仅在发布过程中临时修改的叶包清单
|
--verify-access
#
|
从历史上看,lerna 试图通过使用给定令牌执行一些抢占式
npm API 请求来快速解决授权/身份验证问题
|
--otp
#
|
发布需要双重身份验证的包时,您可以使用 --otp 指定一次性密码 |
--preid
#
|
与同名的 lerna 版本选项不同,该选项只适用于 --canary 版本计算
|
--pre-dist-tag <tag>
#
|
与 --dist-tag 的工作方式相同,但仅适用于使用预发布版本发布的软件包
|
--registry <url>
#
|
使用此标志运行时,转发的 npm 命令将为您的包使用指定的注册表 |
--tag-version-prefix
#
|
此选项允许提供自定义前缀而不是默认前缀:v |
--temp-tag
#
|
传递时,此标志将更改默认发布过程,首先将所有更改的包发布到临时
dist-tag(lerna-temp) ,然后将新版本移动到 --dist-tag 配置的
dist-tag (默认latest )
|
--yes
#
|
使用此标志运行时,lerna publish 将跳过所有确认提示 |
:- | :- |
---|---|
--no-verify-access
#
|
旧的抢先访问验证现在默认关闭,因此不需要 --no-verify-access |
--skip-npm
#
|
直接调用 lerna version |
"publishConfig": {
"access": "public",
"registry": "http://my-registry.com",
"tag": "flippin-sweet",
"directory": "dist"
}
:- | :- |
---|---|
access
#
|
要发布具有范围的包(例如,@mycompany/rocks ) |
registry
#
|
通过设置注册表来自定义每个包的注册表 |
tag
#
|
您可以通过设置标签来自定义每个包的 dist-tag |
directory
#
|
这个 非标准 字段允许您像 --contents 一样自定义发布的子目录,但基于每个包
|
$ lerna version 1.0.1 # 明确的
$ lerna version patch # semver 关键字
$ lerna version # 从提示中选择
$ lerna version [major | minor | ...]
# 使用下一个语义版本值
# 这会跳过“为...选择新版本”提示
# 强制所有包版本化
$ lerna version --force-publish
$ lerna version -m "chore(doc): publish %s"
# 提交消息 = "chore(doc): publish v1.0.0"
$ lerna version -m "chore(doc): publish %v"
# 提交消息 = "chore(doc): publish 1.0.0"
major
重大的minor
次要的patch
修补premajor
主要的preminor
初级prepatch
预补丁prerelease
预发行:- | :- |
---|---|
--allow-branch <glob>
#
|
与启用 lerna version 的 git 分支匹配的 glob 白名单
|
--amend
#
|
使用此标志运行时,lerna version 将在当前提交上执行所有更改,而不是添加新的
|
--changelog-preset
#
|
默认情况下,更改日志预设设置为 angular |
--conventional-commits
#
|
使用常规提交规范来确定版本 bump 并生成 CHANGELOG.md 文件 |
--conventional-graduate
#
|
将使用 * 对指定的包(逗号分隔)或所有包进行分级 |
--conventional-prerelease
#
|
预发布版本发布指定的包 |
--create-release <type>
#
|
根据更改的包创建正式的 GitHub 或 GitLab 版本 |
--exact
#
|
在更新的包中精确指定更新的依赖项(没有标点符号),而不是与
semver 兼容(使用^ )
|
--force-publish
#
|
强制发布指定的包 |
--git-remote <name>
#
|
把 git 更改推送到指定的远程位置,而不是origin |
--ignore-changes
#
|
检测更改的包时忽略与 glob 匹配的文件中的更改 |
--ignore-scripts
#
|
禁用在 lerna version 期间运行的生命周期脚本 |
--include-merged-tags
#
|
在检测到更改的包时包括来自合并分支的标签 |
--message <msg>
#
|
此选项别名为 -m 以与 git commit 进行奇偶校验 |
--no-changelog
#
|
使用常规提交时,不要生成任何 CHANGELOG.md 文件 |
--no-commit-hooks
#
|
允许 git commit hooks 在提交版本更改时运行。通过
--no-commit-hooks 禁用此行为
|
--no-git-tag-version
#
|
将提交对 package.json 文件的更改并标记发布。通过
--no-git-tag-version 禁用该行为
|
--no-granular-pathspec
#
|
仅添加在版本控制过程中更改的叶包清单(可能还有变更日志)。这产生了
git add --packages/*/package.json 的等价物,但针对更改的内容量身定制
|
--no-private
#
|
在选择版本、提交和标记版本时包含私有包。通过 --no-private 禁用此行为
|
--no-push
#
|
将已提交和标记的更改推送到配置的 git remote 。通过
--no-push 禁用此行为
|
--preid
#
|
使用此标志运行时,lerna 版本将使用指定的预发布标识符增加 premajor 、preminor 、prepatch 或
prerelease semver bumps
|
--sign-git-commit
#
|
此选项类似于同名的 npm 版本选项 |
--sign-git-tag
#
|
此选项类似于同名的 npm 版本选项 |
--force-git-tag
#
|
此选项替换任何现有标记而不是失败 |
--tag-version-prefix
#
|
此选项允许提供自定义前缀而不是默认前缀:v |
--yes
#
|
使用此标志运行时,lerna 版本将跳过所有确认提示 |
:- | :- |
---|---|
--cd-version
#
|
将 semver 关键字传递给
bump 位置
|
--repo-version
#
|
将明确的版本号传递给 bump 位置 |
--skip-git
#
|
请改用 --no-git-tag-version 和 --no-push |
将本地包链接
在一起,并安装
其余的包依赖项
$ lerna bootstrap -- --production \
--no-optional
$ lerna bootstrap --hoist
:- | :- |
---|---|
--hoist [glob]
#
|
在 repo 根目录安装与 glob 匹配的外部依赖项,以便它们可用于所有包
|
--strict
#
|
与提升 (hoist) 一起使用时,会在发出版本警告后抛出错误并停止引导 |
--nohoist [glob]
#
|
不要在 repo 根目录安装与
glob 匹配的外部依赖项。这可用于选择不提升某些依赖项
|
--ignore
#
|
当与 bootstrap 命令一起使用时,还可以在 lerna 中设置
--ignore 标志
|
:- | :- |
---|---|
--ignore-prepublish
#
|
跳过默认在引导程序包中运行的预发布生命周期脚本 |
--ignore-scripts
#
|
跳过通常在引导程序包中运行(准备等)的任何生命周期脚本 |
--registry <url>
#
|
指定 npm 包的仓库地址 |
--npm-client <client>
#
|
必须是知道如何安装 npm 包依赖项的可执行文件 |
--use-workspaces
#
|
启用与 Yarn Workspaces 的集成(从 yarn@0.27+ 开始可用)
|
--no-ci
#
|
在 CI 环境中调用 npm ci 而不是 npm install
|
--force-local
#
|
此标志会导致引导命令始终对本地依赖项进行符号链接,而不管匹配的版本范围如何 |
$ lerna info
lerna notice cli v6.0.0
Environment info:
System(系统):
OS: macOS 12.2
CPU: (8) x64 Apple M1
Binaries(二进制文件):
Node: 16.17.0 - /usr/local/bin/node
Yarn: 1.22.10 - /usr/local/bin/yarn
npm: 8.5.0 - /usr/local/bin/npm
Utilities(实用程序):
Git: 2.33.0 - /opt/homebrew/bin/git
npmPackages:
lerna: ^6.0.0 => 6.0.0
$ lerna exec --scope my-component -- ls -la
$ lerna run --scope toolbar-* test
$ lerna run --scope package-1 --scope *-2 lint
$ lerna exec --ignore package-{1,2,5} -- ls -la
$ lerna run --ignore package-1 test
$ lerna run --ignore package-@(1|2) --ignore package-3 lint
# 列出自最新标签以来已更改的包的内容
$ lerna exec --since -- ls -la
# 对自 main 以来发生更改的所有包运行测试
$ lerna run test --since main
# 列出自 some-branch 以来发生变化的所有包
$ lerna ls --since some-branch
# my-component 及其所有依赖项将被引导
$ lerna bootstrap --scope my-component --include-dependencies
$ lerna bootstrap --scope "package-*" --ignore "package-util-*" --include-dependencies
# 所有匹配 “package-util-*” 的包都将被忽略,除非它们是
# 依赖于名称与 “package-*” 匹配的包
:- | :- |
---|---|
--scope <glob>
#
|
仅包括名称与给定 glob 匹配的包 |
--ignore <glob>
#
|
排除名称与给定 glob 匹配的包 |
--no-private
#
|
排除私有包 |
--since [ref]
#
|
仅包括自指定 ref 以来已更改的包 |
--exclude-dependents
#
|
使用 --since 运行命令时排除所有传递依赖项,覆盖默认的“changed”算法
|
--include-dependents
#
|
无论 --scope 、--ignore 或
--since 是什么,在运行命令时都包括所有传递依赖项
|
--include-dependencies
#
|
无论 --scope 、--ignore 或 --since
#
是什么,在运行命令时都包括所有传递依赖项
|
--include-merged-tags
#
|
使用 --since 运行命令时包括来自合并分支的标签 |
创建新的 Lerna 仓库或将现有仓库升级到当前版本 Lerna
lerna
不存在,请将其添加到 package.json
中的
devDependency
lerna.json
配置文件来存储版本号.gitignore
,则生成一个忽略文件$ lerna init --independent
:- | :- |
---|---|
--independent
#
|
使用独立版本控制模式 # |
--exact
#
|
添加或更新 lerna 的本地版本时将使用插入符范围
#
|
它将配置 lerna.json
以强制所有后续执行完全匹配
{
"command": {
"init": {
"exact": true
}
},
"version": "0.0.0"
}
将一个包导入到带有提交历史的 monorepo
# 开始使用 Lerna
$ git init lerna-repo && cd lerna-repo
$ npx lerna init
$ npm install
# 添加提交
$ git add .
# 如果没有提交,导入命令将失败
$ git commit -m "Initial lerna commit"
# 导入其他存储库
$ npx lerna import <外部存储库的路径>
$ npx lerna import ~/Product --flatten
选项
:- | :- |
---|---|
--flatten
#
|
当导入具有冲突的合并提交的存储库时,导入命令将无法尝试应用所有提交 |
--dest
#
|
导入仓库时,可以通过 lerna.json 中列出的目录来指定目标目录 |
--preserve-commit
#
|
每个 git 提交都有一个作者和一个提交者 |
将依赖项添加到匹配的包
$ lerna add <package>[@version] \
[--dev] [--exact] [--peer]
选项
:- | :- |
---|---|
--dev #
|
将新包添加到 devDependencies |
--exact
#
|
添加具有精确版本(例如 1.0.1 )而不是默认 ^ semver 范围(例如
^1.0.1 )的新包
|
--peer
#
|
将新包添加到 peerDependencies |
--registry <url>
#
|
使用自定义注册表安装目标包 |
--no-bootstrap
#
|
跳过链式 lerna bootstrap |
实例
# 将 mod-1 包添加到“prefix-”前缀文件夹中的包中
$ lerna add mod-1 packages/prefix-*
# 将 mod-1 安装到mod-2
$ lerna add mod-1 --scope=mod-2
# 在 devDependencies 中安装 mod-1 到 mod-2
$ lerna add mod-1 --scope=mod-2 --dev
# 在 peerDependencies 中安装 mod-1 到 mod-2
$ lerna add mod-1 --scope=mod-2 --peer
# 在除 mod-1 之外的所有模块中安装 mod-1
$ lerna add mod-1
# 在所有模块中安装 babel-core
$ lerna add babel-core
比较自上次发布以来的所有包或单个包
$ lerna diff [package]
$ lerna diff
$ lerna diff package-name # 区分一个特定的包
类似于 lerna changed
,此命令运行 git diff
从所有包中删除 node_modules
目录
$ lerna clean
接受所有过滤选项。lerna clean
不会从根 node_modules
目录中删除模块,即使您启用了 --hoist
选项
运行设置基本缓存选项的向导
$ lerna add-caching
更新配置文件以匹配当前安装的 lerna 版本
$ npm i lerna@latest
$ lerna repair
lerna repair
在升级后最有用,可确保应用新版本 lerna 的任何配置文件更改