本備忘單旨在快速理(li)解 所涉及的(de)主要概念,顯(xian)示了(le)它(ta)的(de)常用命令使用清單
現代構建系統,用于(yu)管理和發布(bu)來自(zi)同一(yi)存儲庫(ku)的(de)多個(ge) 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
中依賴(lai)于(yu)它(ta)們,如下所(suo)示:
"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
將包鏈(lian)接過程委托(tuo)給(gei)你的包管理器 (此功能(neng)由 npm、yarn 和(he) pnpm 支持)。
npx lerna run test --scope=header # 單個
多個任務運行
npx lerna run test --scope=header,footer
忽略 header
,footer
其(qi)它包中運行(xing)任務運行(xing)
npx lerna run build --ignore=header,footer
# 在所有包含它的包中(zhong)運行(xing) npm run my-script
$ lerna run <script> -- [..args]
$ lerna run test
$ lerna run build
# 觀(guan)看所(suo)有包并(bing)在(zai)更改時轉換,流式前綴輸出
$ lerna run --parallel watch
# 在(zai)所有包(bao)中運行命令
$ 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 ),而不是使用由 提供支持的默認現代任務運行器實現。 |
# 發布(bu)自(zi)上次發布(bu)以(yi)來已更(geng)改的軟件包
$ lerna publish
# 顯(xian)式發布在當前提(ti)交中標記的包
$ lerna publish from-git
# 顯(xian)式(shi)發布注冊表中不存在(zai)最新(xin)版本的軟件包
$ lerna publish from-package
# 使用下一(yi)個(ge)語(yu)義預發布版本,例如(ru)
$ lerna publish --canary
# 1.0.0 => 1.0.1-alpha.0+${SHA}
# 自上次提(ti)交以來更改的包
# 隨后的金絲(si)雀發布(bu)將產(chan)生1.0.1-alpha.1+${SHA}等
$ lerna publish --canary --preid beta
# 1.0.0 => 1.0.1-beta.0+${SHA}
# 以下(xia)是等(deng)價的:
$ 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": "//my-registry.com",
"tag": "flippin-sweet",
"directory": "dist"
}
:- | :- |
---|---|
access | 要發布具有范圍的包(例如,@mycompany/rocks ) |
registry | 通過設置注冊表來自定義每個包的注冊表 |
tag | 您可以通過設置標簽來自定義每個包的 dist-tag |
directory | 這個 非標準 字段允許您像 --contents 一樣自定義發布的子目錄,但基于每個包 |
$ lerna version 1.0.1 # 明確(que)的
$ lerna version patch # semver 關鍵字
$ lerna version # 從提示中選(xuan)擇
$ lerna version [major | minor | ...]
# 使用下一個(ge)語(yu)義(yi)版(ban)本(ben)值
# 這會跳過“為...選擇新版(ban)本”提示
# 強制所(suo)有(you)包版本化
$ lerna version --force-publish
$ lerna version -m "chore(doc): publish %s"
# 提(ti)交(jiao)消息 = "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 | 默認情況下,更改日志預設設置為 |
--conventional-commits | 使用常規提交規范來確定 并生成 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 關鍵字傳遞給 位置 |
--repo-version | 將明確的版本號傳遞給 位置 |
--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
# 列出(chu)自(zi)最新標簽以來已(yi)更改(gai)的(de)包(bao)的(de)內(nei)容
$ lerna exec --since -- ls -la
# 對自(zi) main 以(yi)來發生更改的所有包(bao)運行測(ce)試
$ lerna run test --since main
# 列出自(zi) some-branch 以來(lai)發生(sheng)變化(hua)的所有包
$ lerna ls --since some-branch
# my-component 及其(qi)所(suo)有依(yi)賴項將被(bei)引導
$ lerna bootstrap --scope my-component --include-dependencies
$ lerna bootstrap --scope "package-*" --ignore "package-util-*" --include-dependencies
# 所(suo)有(you)匹(pi)配(pei) “package-util-*” 的包都將(jiang)被(bei)忽(hu)略,除非它(ta)們是
# 依(yi)賴(lai)于名稱(cheng)與(yu) “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 list 相同,它本(ben)身(shen)類似(si)于 ls 命令
lerna ls
# 相當于(yu) lerna ls -l,顯示長(chang)輸(shu)出
lerna ll
# 相(xiang)當(dang)于 lerna ls -la,顯示所(suo)有包(包括私有包)
lerna la
:- | :- |
---|---|
--json | 顯示為 JSON |
--ndjson | 換行符分隔 |
-a,--all | 所有包 |
-l,--long | 顯示擴展信息 |
-p,--parseable | 顯示可解析的輸出 |
--toposort | 按拓撲排序 |
--graph | JSON 格式鄰接依賴關系圖 |
列出(chu)自上(shang)次標記版(ban)本以來(lai)已更(geng)改的(de)本地軟(ruan)件(jian)包
lerna changed
支持 lerna ls
支持的所有選項lerna ls
不同的是不支持過濾器選項lerna changed
支持 lerna version
的以下選項
:- | :- |
---|---|
--conventional-graduate | |
--force-publish | |
--ignore-changes | |
--include-merged-tags |
創建新(xin)的 Lerna 倉(cang)(cang)庫(ku)或將現(xian)有倉(cang)(cang)庫(ku)升級到當(dang)前版本 Lerna
lerna
不存在,請將其添加到 package.json
中的 devDependency
lerna.json
配置文件來存儲版本號.gitignore
,則生成一個忽略文件$ lerna init --independent
:- | :- |
---|---|
--independent | 使用獨立版本控制模式 |
--exact | 添加或更新 lerna 的本地版本時將使用插入符范圍 |
它將配置 lerna.json
以強制所有(you)后續執行完全匹配
{
"command": {
"init": {
"exact": true
}
},
"version": "0.0.0"
}
將一個包導入到帶有提交歷史的 monorepo
# 開(kai)始使用 Lerna
$ git init lerna-repo && cd lerna-repo
$ npx lerna init
$ npm install
# 添(tian)加提交
$ git add .
# 如果沒有提交,導入命令將失敗
$ git commit -m "Initial lerna commit"
# 導(dao)入其(qi)他(ta)存儲庫
$ npx lerna import <外部存儲庫的路徑>
$ npx lerna import ~/Product --flatten
選項
:- | :- |
---|---|
--flatten | 當導入具有沖突的合并提交的存儲庫時,導入命令將無法嘗試應用所有提交 |
--dest | 導入倉庫時,可以通過 lerna.json 中列出的目錄來指定目標目錄 |
--preserve-commit | 每個 git 提交都有一個作者和一個提交者 |
將(jiang)依賴項添(tian)加到匹配(pei)的包
$ 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 包(bao)添加到“prefix-”前(qian)綴文(wen)件夾中(zhong)的(de)包(bao)中(zhong)
$ lerna add mod-1 packages/prefix-*
# 將 mod-1 安裝到mod-2
$ lerna add mod-1 --scope=mod-2
# 在(zai) devDependencies 中安裝 mod-1 到(dao) mod-2
$ lerna add mod-1 --scope=mod-2 --dev
# 在 peerDependencies 中安(an)裝 mod-1 到 mod-2
$ lerna add mod-1 --scope=mod-2 --peer
# 在除 mod-1 之外的所有(you)模(mo)塊中(zhong)安裝(zhuang) mod-1
$ lerna add mod-1
# 在所有(you)模塊(kuai)中安裝(zhuang) babel-core
$ lerna add babel-core
比較自(zi)上次發布以來的(de)所有包或單個包
$ lerna diff [package]
$ lerna diff
$ lerna diff package-name # 區分一個特定的(de)包
類似于 lerna changed
,此命令運行 git diff
從所有包中刪除 node_modules
目錄
$ lerna clean
接受所有過濾選項。lerna clean
不會從根 node_modules
目錄中刪除模塊,即使您啟用了 --hoist
選項
運(yun)行設置基本緩存選項(xiang)的向導(dao)
$ lerna add-caching
將(jiang)所有相互依賴(lai)的(de)包符號鏈接在一起
$ lerna link
設置會導(dao)致鏈接命令始(shi)終(zhong)對本地依賴(lai)項進行符號鏈接
更新配置文(wen)件以匹(pi)配當前安裝的(de) lerna 版本
$ npm i lerna@latest
$ lerna repair
在升級后最有用,可確(que)保應用新版本(ben) lerna 的任何配置文(wen)件更(geng)改