Yarn Workspace 使用指南

本文轉(zhuǎn)自:Yarn Workspace 使用指南

Yarn 從 1.0 版開始支持 Workspace (工作區(qū))。

Workspace 能更好的統(tǒng)一管理有多個(gè)項(xiàng)目的倉(cāng)庫(kù),既可在每個(gè)項(xiàng)目下使用獨(dú)立的 package.json 管理依賴,又可便利的享受一條 yarn 命令安裝或者升級(jí)所有依賴等。更重要的是可以使多個(gè)項(xiàng)目共享同一個(gè) node_modules 目錄,提升開發(fā)效率和降低磁盤空間占用。

一句話總結(jié)就是可以大大簡(jiǎn)化對(duì)多個(gè)項(xiàng)目的統(tǒng)一管理。

很多知名的開源項(xiàng)目也使用了 Yarn Workspace,如 vuereact、jest 等。

1. Yarn Workspace 共享 node_modules 依賴詳解

回看下面的帶兩個(gè)子項(xiàng)目的經(jīng)典 Node.js 項(xiàng)目:

projects/
|--project1/
|  |--package.json
|  |--node_modules/
|  |  |--a/
|--project2
|  |--package.json
|  |--node_modules/
|  |  |--a/
|  |  |--project1/

project1/package.json:

{
  "name": "project1",
  "version": "1.0.0",
  "dependencies": {
    "a": "1.0.0"
  }
}

project2/package.json:

{
  "name": "project2",
  "version": "1.0.0",
  "dependencies": {
    "a": "1.0.0",
    "project1": "1.0.0"
  }
}

沒(méi)有使用 Yarn Workspace 前,需要分別在 project1project2 目錄下分別執(zhí)行 yarn|npm install 來(lái)安裝依賴包到各自的 node_modules 目錄下?;蛘呤褂?yarn|npm upgrade 來(lái)升級(jí)依賴的包。

這會(huì)產(chǎn)生很多不良的問(wèn)題:

  1. 如果 project1 和 project2 有相同的依賴項(xiàng)目 a,a 都會(huì)各自下載一次,這不僅耗時(shí)降低開發(fā)效率,還額外占用重復(fù)的磁盤空間;當(dāng) project 項(xiàng)目比較多的時(shí)候,此類問(wèn)題就會(huì)顯得十分嚴(yán)重。

  2. 如果 project2 依賴 project1,而 project1 并沒(méi)有發(fā)布到 npm 倉(cāng)庫(kù),只是一個(gè)本地項(xiàng)目,有兩種方式配置依賴:

    1. 使用相對(duì)路徑(如 file: 協(xié)議)在 project2 中指定 project1 的依賴。
    2. 使用 yarn|npm link 來(lái)配置依賴。

    第 1 種方式缺少版本號(hào)的具體指定,每次發(fā)布版本時(shí)都需要相應(yīng)的依賴版本的修改;第 2 種方式需要自行手工操作,配置復(fù)雜易出錯(cuò)。

    需要 npm-2.0.0+ 才支持模塊間的相對(duì)路徑依賴,詳見(jiàn) npm 官方文檔 package.json/Local Paths

  3. 沒(méi)有一個(gè)統(tǒng)一的地方對(duì)全部項(xiàng)目進(jìn)行統(tǒng)一構(gòu)建等,需要到各個(gè)項(xiàng)目?jī)?nèi)執(zhí)行 yarn|npm build 來(lái)構(gòu)架項(xiàng)目。

使用 Yarn Workspace 之后,上述問(wèn)題都能得到很好的解決。而且這是 Yarn 內(nèi)置的功能,并不需要安裝什么其他的包,只需要簡(jiǎn)單的在 projects 目錄(Yarn 稱之為 workspace-root)下增加如下內(nèi)容的 package.json 文件即可。

projects/package.json:

{
  "private": true,
  "workspaces": ["project1", "project2"] // 也可以使用通配符設(shè)置為 ["project*"]
}

開源社區(qū)則都基本上使用 "workspaces": ["packages/*"] 的目錄結(jié)構(gòu),這與 Lerna 的目錄結(jié)構(gòu)一致。

在 workspace-root 目錄下執(zhí)行 yarn install

$ cd projects
$ rm -r project1/node_modules
$ rm -r project2/node_modules

$ yarn install
yarn install v1.22.0
info No lockfile found.
[1/4] ??  Resolving packages...
[2/4] ??  Fetching packages...
[3/4] ??  Linking dependencies...
[4/4] ??  Building fresh packages...
success Saved lockfile.
?  Done in 0.56s.

此時(shí)查看目錄結(jié)構(gòu)如下:

projects/
|--package.json
|--project1/
|  |--package.json
|--project2
|  |--package.json
|--node_modules/
|  |--a/
|  |--project1/ -> ./project1/

說(shuō)明:

  • projects 是各個(gè)子項(xiàng)目的上級(jí)目錄,術(shù)語(yǔ)上稱之為 workspace-root,而 project1 和 project2 術(shù)語(yǔ)上稱之為 workspace

  • yarn install 命令既可以在 workspace-root 目錄下執(zhí)行,也可以在任何一個(gè) workspace 目錄下執(zhí)行,效果是一樣的。

  • 如果需要某個(gè)特殊的 workspace 不受 Yarn Workspace 管理,只需在此 workspace 目錄下添加 .yarnrc 文件,并添加如下內(nèi)容禁用即可:

    workspaces-experimental false
    
    
  • 在 project1 和 project2 目錄下并沒(méi)有 node_modules 目錄(特殊情況下才會(huì)有,如當(dāng) project1 和 project2 依賴了不同版本的 a 時(shí))。

  • /node_modules/project1/project1 的軟鏈接,軟鏈接的名稱使用的是 /project1/package.json#name 屬性的值。

  • 如果只是修改單個(gè) workspace,可以使用 --focus 參數(shù)來(lái)快速安裝相鄰的依賴配置從而避免全部安裝一次。

2. 可用的 Yarn Workspace 命令

2.1. yarn workspace <workspace_name> <command>

針對(duì)特定的 workspace 執(zhí)行指定的 <command>,如:

$ yarn workspace project1 add vue --dev 《 往 project1 添加 vue 開發(fā)依賴
$ yarn workspace project1 remove vue    《 從 project1 移除 vue 依賴

{workspace}/package.json#scripts 中定義的腳本命令,也可以作為 <command> 來(lái)執(zhí)行。

下面是一個(gè)利用這個(gè)特點(diǎn)創(chuàng)建統(tǒng)一構(gòu)建命令的例子:

projects/package.json:

{
  "scripts": {
    "build": "yarn workspaces run build"
  }
}

project1|project2/package.json:

{
  "scripts": {
    "build": "rollup -i index.js -f esm -o dist/bundle.js"
  }
}

執(zhí)行 yarn build 的結(jié)果:

$ yarn build
yarn run v1.22.0
$ yarn workspaces run build

> project1
$ rollup -i index.js -f esm -o dist/bundle.js

index.js → dist/bundle.js...
created dist/bundle.js in 70ms

> project2
$ rollup -i index.js -f esm -e project1 -o dist/bundle.js

index.js → dist/bundle.js...
created dist/bundle.js in 80ms
?  Done in 2.45s.

2.2. yarn workspaces <command>

2.2.1. yarn workspaces run <command>

在每個(gè) workspace 下執(zhí)行 <command>。如:

yarn workspaces run test

將會(huì)執(zhí)行各個(gè) workspace 的 test script。

2.2.2. yarn workspaces info [--json]

顯示當(dāng)前各 workspace 之間的依賴關(guān)系樹。

$ yarn workspaces info
yarn workspaces v1.21.1
{
  "project1": {
    "location": "project1",
    "workspaceDependencies": [],
    "mismatchedWorkspaceDependencies": []
  },
  "project2": {
    "location": "project2",
    "workspaceDependencies": [
      "project1"
    ],
    "mismatchedWorkspaceDependencies": []
  }
}
?  Done in 0.12s.

相關(guān)源代碼已放在 Github 上,詳見(jiàn)這里。

Yarn Workspace 官方參考文檔:英文中文

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容