原文:github.com/lerna/lernagit
一個用於管理具備多個包的JavaScript項目的工具。github
將大型代碼庫拆分爲單獨的獨立版本包對於代碼共享很是有用。然而,跨多個存儲庫進行更改是混亂的,並且很難跟蹤,跨存儲庫的測試也變得很是複雜。npm
爲了解決這些(和許多其餘)問題,一些項目將其代碼庫組織到多包存儲庫(有時稱爲monorepos)。像Babel、React、Angular、Ember、Meteor、Jest等項目在一個存儲庫中開發全部的包。json
Lerna是一個工具,它優化了使用git和npm管理多包存儲庫的工做流。bootstrap
Lerna還能夠減小開發和構建環境中對包的大量副本的時間和空間需求,這一般是將項目劃分爲多個單獨的NPM包的缺點。有關詳細信息,請參閱 提高 提高文檔。數組
事實上不多有。您的文件結構以下所示:服務器
my-lerna-repo/
package.json
packages/
package-1/
package.json
package-2/
package.json
複製代碼
Lerna中的兩個主要命令是Lerna bootstrap和Lerna publish。babel
bootstrap將把repo中的依賴項連接在一塊兒。publish將幫助發佈任何更新包。app
Lerna不是無服務器monorepos的部署工具。提高可能與傳統的無服務器monorepo部署技術不兼容。工具
下面的說明適用於Lerna 3.x。咱們建議在新的Lerna項目中使用它而不是2.x。
讓咱們從安裝Lerna做爲npm項目的開發依賴項開始。
$ mkdir lerna-repo && cd $_
$ npx lerna init
複製代碼
這將建立一個lerna.json配置文件以及packages 文件夾,所以您的文件夾如今應該以下所示:
lerna-repo/
packages/
package.json
lerna.json
複製代碼
Lerna容許您使用兩種模式之一管理項目:固定模式或獨立模式(Fixed or Independent)。
固定模式Lerna項目在一個版本行上運行。版本保存項目根目錄下lerna.json文件,在version鍵下。運行lerna publish時,若是某個模塊自上次發佈以來已更新,則它將更新爲您要發佈的新版本。這意味着您只在須要時發佈包的新版本。
注意:若是您的主版本爲0,則全部更新都將被視爲中斷。所以,使用主版本零運行lerna publish並選擇任何非預發佈版本號將致使爲全部包發佈新版本,即便不是全部包自上次發佈以來都發生了更改。
這是babel目前使用的模式。若是要自動將全部包版本綁定在一塊兒,請使用此選項。這種方法的一個問題是,任何包中的重大更改都將致使全部包都有一個新的主版本。
lerna init --independent
複製代碼
獨立模式Lerna項目容許維護人員獨立地增長包版本。每次發佈時,對於每一個已更改的包,都將獲得一個提示,以指定它是修補程序、次要更改、主要更改仍是自定義更改。
獨立模式容許您更具體地更新每一個包的版本,並對一組組件有意義。將這種模式與語義釋放之類的東西結合在一塊兒,會讓它不那麼痛苦。(atlassian/lerna semantic release已經對此進行了研究)。
設置version: independent 鍵lerna.json以獨立模式運行。
若是您在使用Lerna時遇到任何問題,請查看咱們的故障排除文檔,您能夠從中找到問題的答案。
見 FAQ.md.
當它在運行命令時遇到錯誤Lerna會記錄到lerna-debug.log文件(與npm-debug.log相同)。
Lerna還支持做用域包。
運行lerna--help查看全部可用的命令和選項。
{
"version": "1.1.3",
"npmClient": "npm",
"command": {
"publish": {
"ignoreChanges": ["ignored-file", "*.md"],
"message": "chore(release): publish",
"registry": "https://npm.pkg.github.com"
},
"bootstrap": {
"ignore": "component-*",
"npmClientArgs": ["--no-package-lock"]
}
},
"packages": ["packages/*"]
}
複製代碼
在lerna.json中的packages是一個文件數組匹配包含package.json的目錄,這就是lerna如何識別「leaf」包(相對於「root」package.json,用於管理整個repo的dev依賴項和腳本)。
默認狀況下,lerna將包列表初始化爲[「packages/*」],但您也可使用其餘目錄,如[「modules/*」]或[「package1」,「package2」]。定義的glob目錄位置是相對於lerna.json,這一般是存儲庫根。惟一的限制是不能直接嵌套包位置,但這也是「普通」npm包共享的限制。
例如,[「packages/*」,「src/**」]與此樹匹配:
packages/
├── foo-pkg
│ └── package.json
├── bar-pkg
│ └── package.json
├── baz-pkg
│ └── package.json
└── qux-pkg
└── package.json
src/
├── admin
│ ├── my-app
│ │ └── package.json
│ ├── stuff
│ │ └── package.json
│ └── things
│ └── package.json
├── profile
│ └── more-things
│ └── package.json
├── property
│ ├── more-stuff
│ │ └── package.json
│ └── other-things
│ └── package.json
└── upload
└── other-stuff
└── package.json
複製代碼
在packages/*下定位leaf包被認爲是「最佳實踐」,但不是使用Lerna的要求。
一些lerna.json字段再也不使用。值得注意的包括:
lerna:最初用來表示lerna的當前版本。使過期並在v3中刪除
大多devDependencies 能夠經過Lerna link convert被拉到Lerna repo的根目錄
上面的命令將自動提高對象並使用相對file: 說明符。
提高有幾個好處:
全部包都使用給定依賴項的同一版本
可使用諸如GreenKeeper這樣的自動化工具在根目錄上保持最新的依賴關係
減小依賴項安裝時間
所需存儲更少
注意,提供npm腳本使用的「二進制」可執行文件的devDependencies 仍然須要直接安裝在使用它們的每一個包中。
例如,在這種狀況下,要使lerna run nsp(和npm run nsp在包的目錄中)正常工做,nsp依賴關係是必需的:
{
"scripts": {
"nsp": "nsp"
},
"devDependencies": {
"nsp": "^2.3.3"
}
}
複製代碼
Lerna容許將本地依賴包的目標版本寫入git遠程url,並使用commitish(git 版本標識)(例如,#v1.0.0或#semver:^1.0.0),而不是普通的數字版本範圍。當包必須是私有的而且不須要私有的npm註冊時,這容許經過git存儲庫分發包。
請注意,lerna並無實際將git歷史分割到單獨的只讀存儲庫中。【解決方案:從monorepo中實現「git-only」分發有多種方式供之後參考。1:splitsh 2:regular git filter-branch --subdirectory-filter packages/】這是用戶的責任。(有關實施細節,請參閱此註釋)
// packages/pkg-1/package.json
{
name: "pkg-1",
version: "1.0.0",
dependencies: {
"pkg-2": "github:example-user/pkg-2#v1.0.0"
}
}
// packages/pkg-2/package.json
{
name: "pkg-2",
version: "1.0.0"
}
複製代碼
在上面的例子中,
llerna bootstrap將正確地將pkg-2符號連接到pkg-1。
當pkg-2發生變化時,lerna publish將更新pkg-1中的commitish(#v1.0.0)。