如何利用lerna管理模塊

當前端項目變得愈來愈大的時候,咱們一般會將公共代碼拆分出來,成爲一個個獨立的npm包進行維護。可是這樣一來,各類包之間的依賴管理就十分讓人頭疼。爲了解決這種問題,咱們能夠將不一樣的npm包項目都放在同一個項目來管理。這樣的項目開發策略也稱做monorepo。Lerna就是這樣一個你更好地進行這項工做的工具。本文將詳細介紹如何使用Lerna來輔助咱們的包依賴管理。javascript

什麼是Lerna

根據官網上的定義,Lerna是一個使用git和npm來處理多包依賴管理的工具,利用它可以自動幫助咱們管理各類模塊包之間的版本依賴關係。目前,已經有不少公共庫都使用Lerna做爲它們的模塊依賴管理工具了,如:babel, create-react-app, react-router, jest等。前端

經常使用命令

bootstrap

使用bootstrap命令,會下載全部定義在package.json中的依賴包。至關於執行npm install,而且連接全部依賴包。java

publish

當你完成某個包的更新後,就可使用lerna publish命令來發布新版本的包。執行這條命令的時候,你能夠指定版本號,而後lerna就會自動給你加更新版本號,加tag並提交到git倉庫上去。node

add

假設你想往你的開發項目中特定包中加入依賴,你就可使用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

執行clean命令,用來刪除全部模塊下node_modules中的npm包。jquery

import

你可使用import命令導入已有的模塊,而且會保留全部的git commit記錄。git

list

列出項目中全部的模塊。github

run

在每一個包含該腳本的模塊中運行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/*"]
}
複製代碼

分別介紹每一個配置項的功能:

  • version: 記錄當前項目的版本號
  • npmClient: 你能夠指定使用npm, cnpm或yarn來執行命令
  • command.publish.ignoreChanges: 忽略特定的項
  • command.publish.npmClientArgs: 當執行lerna bootstrap命令時,傳給npm install的參數
  • command.publish.message: 發佈模塊的時候,填寫的commit信息
  • 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模式。

Fixed/Locked mode

這個模式也是咱們初始化項目的時候默認採用的模式。在這種模式下, 你能夠理解爲"全量發佈"。也就是當咱們一旦有某個模塊的主版本更新了,那麼全部包都會擁有一個新的版本號。而主版本號,是管理在項目根目錄的lerna.json文件中。

Independent mode

若是你不喜歡上面這種模式,你也可使用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選項來固定一個版本號。既能夠避免不少重複的代碼,也能夠解決不一樣版本號所帶來的衝突問題。

#參考資料

github.com/lerna/lerna

——本文首發於我的公衆號,轉載請註明出處———

微信掃描二維碼,關注個人公衆號
最後,歡迎你們關注個人公衆號,一塊兒學習交流。
相關文章
相關標籤/搜索