當前端項目變得愈來愈大的時候,咱們一般會將公共代碼拆分出來,成爲一個個獨立的npm包進行維護。可是這樣一來,各類包之間的依賴管理就十分讓人頭疼。爲了解決這種問題,咱們能夠將不一樣的npm包項目都放在同一個項目來管理。這樣的項目開發策略也稱做monorepo。Lerna就是這樣一個你更好地進行這項工做的工具。本文將詳細介紹如何使用Lerna來輔助咱們的包依賴管理。javascript
根據官網上的定義,Lerna是一個使用git和npm來處理多包依賴管理的工具,利用它可以自動幫助咱們管理各類模塊包之間的版本依賴關係。目前,已經有不少公共庫都使用Lerna做爲它們的模塊依賴管理工具了,如:babel, create-react-app, react-router, jest等。前端
使用bootstrap命令,會下載全部定義在package.json中的依賴包。至關於執行npm install
,而且連接全部依賴包。java
當你完成某個包的更新後,就可使用lerna publish
命令來發布新版本的包。執行這條命令的時候,你能夠指定版本號,而後lerna就會自動給你加更新版本號,加tag並提交到git倉庫上去。node
假設你想往你的開發項目中特定包中加入依賴,你就可使用add
命令輕鬆實現:react
# 給a, b 包中加入Lodash,會同時改變a,b模塊中packages.json文件
lerna add lodash packages/a packages/b
# 給a 包中加入jquery, 使用--dev參數是使依賴加入到devDependencies中
lerna add jquery packages/a --dev
# 你也可使用通配符, 下面這命令,會往全部re開頭的模塊包中加入依賴
lerna add jquery packages/re-*
# 指定特定的範圍,要使用--scope參數,以下:給b包安裝a模塊
lerna add a --scope=b
複製代碼
執行clean命令,用來刪除全部模塊下node_modules中的npm包。jquery
你可使用import命令導入已有的模塊,而且會保留全部的git commit記錄。git
列出項目中全部的模塊。github
在每一個包含該腳本的模塊中運行npm腳本。shell
說了那麼多,咱們寫個例子實操一下。npm
首先,先建一個新項目,接着咱們全局安裝lerna,並執行初始化操做,再上傳到git倉庫上。:
npm intall lerna -g
mkdir lerna-demo && cd $_
lerna init
git init
git add .
git commit -m "Initial Commit"
git remote add origin http://github.com/scq000/lerna-demo.git
git push -u origin master
ls
複製代碼
執行完上述命令後,就會在當前目錄下生成如下幾個文件:
packages/ package.json lerna.json
其中: packages目錄用來存放咱們須要拆分的各類公共代碼庫。lerna.json文件裏面記錄了lerna的相關配置信息:
{
"version": "1.1.3",
"npmClient": "npm",
"command": {
"publish": {
"ignoreChanges": ["ignored-file", "*.md"],
"message": "chore(release): publish"
},
"bootstrap": {
"ignore": "component-*",
"npmClientArgs": ["--no-package-lock"]
}
},
"packages": ["packages/*"]
}
複製代碼
分別介紹每一個配置項的功能:
你能夠根據須要本身更改相應的配置。
爲了演示方便,咱們新建兩個模塊, moduleA和moduleB, 並讓moduleA依賴moduleB:
lerna create module-a
lerna create module-b
# 將本地包連接起來,能夠直接引用
lerna link
複製代碼
修改module-b 的入口文件:
export const sayHello() {
return "hello world";
};
複製代碼
修改module-a 的入口文件:
const moduleB = require('module-b');
const moduleA = function() {
console.log(moduleB.sayHello());
}
export default moduleA;
複製代碼
完成修改後,咱們能夠直接發佈新的模塊
lerna publish
複製代碼
而後,根據提示輸入版本號等,lerna就會自動幫咱們給包加上tag,並上傳到對應的倉庫中去。
但願這個簡單的例子能夠能讓你們熟悉簡單的操做流程。
lerna容許咱們使用兩種模塊來管理咱們的模塊:Fixed 模式和Independent模式。
這個模式也是咱們初始化項目的時候默認採用的模式。在這種模式下, 你能夠理解爲"全量發佈"。也就是當咱們一旦有某個模塊的主版本更新了,那麼全部包都會擁有一個新的版本號。而主版本號,是管理在項目根目錄的lerna.json文件中。
若是你不喜歡上面這種模式,你也可使用Independent模式來管理項目中的模塊。你只須要在初始化項目的使用指定--independent參數就能夠了:
lerna init --independent
複製代碼
在這種模式下,咱們能夠獨立地更新某個包的版本號,你能夠理解爲"增量發佈"。
在使用過程當中,最常常遇到的問題是,執行lerna bootstrap
的時候奇慢無比。這種狀況一般是由於在每一個獨立包中都重複安裝了公共依賴。在這時候,咱們能夠將全部公共使用的包,如react,lodash之類的移到根目錄的package.json中去,並使用lerna bootstrap --hoist
命令進行安裝。使用hoist
選項後,全部公共的依賴都只會安裝在根目錄的node_modules目錄中去,而不會在每一個包目錄下的node_modules中都保留各自的依賴包。
這樣一來,lerna bootstrap
的執行效率就大大增長了。
另外一個可能常遇到的問題就是多個安裝包之間版本不一致,好比,A包須要依賴1.0的lodash, 而B包則須要依賴2.0的lodash。這樣就會致使在打包過程當中多了許多重複代碼。並且在同一項目下保留不一樣版本的npm包也難以管理。對於這個問題,在大多數狀況下,咱們能夠嘗試使用npm包管理器提供的peerDependencies選項來固定一個版本號。既能夠避免不少重複的代碼,也能夠解決不一樣版本號所帶來的衝突問題。
#參考資料
——本文首發於我的公衆號,轉載請註明出處———