成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

現代 Monorepo 工程技術選型,聊聊我的思考

開發 新聞
看了本文我想大家應該理解了 PNPM + Turborepo + Changesets 這個技術選型的原因以及要怎么做。

前言

相信很多關注 Monorepo 生態的同學,應該大都看過這篇文章 monorepo.tools [1] ,其中列舉了現存的幾個主流的 Monorepo 相關的工具:

  • Bazel (by Google) [2]
  • Lage (by Microsoft) [3]
  • Lerna [4]
  • Nx (by Nrwl) [5]
  • Rush (by Microsoft) [6]
  • Turborepo (by Vercel) [7]

相應地,在這篇文章中也對各類工具進行了一一介紹。并且,我相信每個看過這篇文章的同學,都會留下這么個疑問: 這么多 Monorepo Tool,我要如何進行選型?

這里,我給出的答案是 PNPM + Turborepo + Changesets。那么,又為什么是這 3 者呢?下面,我將會分別圍繞這 3 個技術展開,來一一解答這個選型的原因以及怎么做。

PNPM

PNPM 的動機( Motivation [8] ),如它在官方文檔介紹的所說: “Saving disk space and boosting installation speed”,節省磁盤空間和提高安裝速度 。除開這個動機描述的顯著優點外, PNPM 內置了對 Monorepo 的支持 [9] ,并解決了很多令人詬病的問題。

其中,比較經典的就是 Phantom dependencies(幻影依賴)。由于,默認情況下 yarn 、 npm 安裝的依賴都是會被提升。所以,有時候你可能會遇到 Monorepo 項目中的某個包中的 package.json 沒有安裝這個依賴,結果實際代碼中卻使用了這個依賴...

雖說,PNPM 可以解決這個問題,但是, 默認情況 下 PNPM 安裝的依賴也是會被提升的。如果,需要 PNPM 禁止依賴提升,我們可以通過在 Monorepo 項目工作區下的 .npmrc 文件中 配置 [10] ,例如只提升 lodash :

hoist-pattern[]=*lodash*

當然,還有一些其他的問題,有興趣的同學可以看 ELab 團隊寫的這篇文章 《Monorepo 的這些坑,我們幫你踩過了!》 [11] 。

那么,在簡單解答了為什么用 PNPM 后,下面我們來看一下要怎么用?

Workspace 配置

要使用 PNPM 的 Monorepo 很簡單,只需要在 Monorepo 項目的工作區下新建 pnpm-workspace.yaml 文件并配置:

packages:
- 'packages/**'

接下來,則是記憶常用依賴和多包任務執行相關的命令。由于,我們的技術選型中有 Turborepo,它會負責多包任務的執行。所以,這里只需要記憶 常用依賴相關的命令 。

常用依賴相關命令

pnpm i

在 PNPM 中,安裝依賴可以用 pnpm i 來完成。在 Monorepo 的場景下,默認情況下 pnpm i 會安裝所有的依賴(包括 packages/* )。此外, pnpm i 還需要用到 3 個選項(Option):

  • --filter <package>,安裝依賴到指定的 package,不聲明要安裝的依賴包則默認安裝 package.json 中的所有依賴
  • --prod, P,安裝依賴到 dependencies
  • --dev, D,安裝依賴到 devDependencies

pnpm remove

在 PNPM 中,刪除在 package.json 中的某個依賴,可以用 pnpm remove 完成。它的選項(Option)使用和 pnpm i 大同小異。其中,不同地是當我們在工作區想要刪除 packages 中所有包的 package.json 中的某個依賴的時候,需要使用 -r ,例如移除所有包中的 lodash :

pnpm remove lodash -r

當然,可能還有同學有一些其他的訴求,有興趣的同學可以移步文檔了解,這里不做展開。

Changesets

經常維護開源項目的同學都知道的一點,每次包(Package)的發布,需要修改 package.json 的 version 字段,以及同步更新一下本次發布修改的 CHANGELOG.md。

這么一來,就會凸顯一個問題,每次發布都需要手動地去更新 version 、更新 CHANGELOG.md,未免 有點繁瑣 。并且,用過 Lerna 的同學,應該都知道 Lerna 內置了對這塊的支持。

但是,無論是 PNPM 又或者是下面要說的 Turborepo 都不支持這塊,所以 2 者的官方文檔都給大家推薦了用于支持這塊能力的工具,例如 Changesets [12] 、 Beachball [13] 、 Auto [14] 等。

那么,這里我們要介紹的就是 Changesets。下面,我們來看一下在前面建好的 PNPM 的 Monorepo 項目中如何使用 Changesets。首先,需要執行在 Monorepo 項目的工作區下,執行如下 2 個命令:

pnpm i -DW @changesets/cli
pnpm changeset init

前者是安裝 Changesets 的 CLI,后者是初始化 .changeset 文件夾以及對應的文件:

.changeset
-- config.json
|__ README.md

這里,我們來看一下 config.json [15] 文件:

{
"$schema": "https://unpkg.com/@changesets/config@1.6.4/schema.json",
"changelog": "@changesets/cli/changelog",
"commit": false,
"linked": [],
"access": "restricted",
"baseBranch": "master",
"updateInternalDependencies": "patch",
"ignore": []
}

除開 $schema 這個不需要修改的字段, config.json 文件中列了 7 個字段,各個字段分別代表的作用為:

  • changelog 設置 CHANGELOG.md 生成方式,可以設置 false 不生成,也可以設置為定義生成行為的文件地址或依賴名稱,例如 Changsets 提供的 `changelog-git` [16] 。其中,定義生成行為的文件固定代碼模版為:
async function getReleaseLine() {}
async function getDependencyReleaseLine() {}
export default {
getReleaseLine,
getDependencyReleaseLine
}
  • commit 設置是否把執行 changeset add 或 changeset publish 操作時對修改用 Git 提交
  • linked 設置共享版本的包,而不是獨立版本的包,例如一個組件庫中主題和單獨的組件的關系,也就是修改 Version 的時候,共享的包需要同步一起更新版本
  • access 設置執行 npm publish 的 --access 選項,通常情況下我們是公共的包,所以設置 public 即可(注意,它會被 package.json 中的 access 字段重寫)
  • baseBranch 設置默認的 Git 分支,例如現在 GitHub 的默認分支應該是 main
  • updateInternalDependencies 設置互相依賴的包版本更新機制,它是一個枚舉( major|minor|patch ),例如設置為 minor 時,只有當依賴的包新了 minor 版本或者才會對應地更新 package.json 的 dependencies 或 devDependencies 中對應依賴的版本
  • ignore 設置不需要發布的包,這些會被 Changesets 忽略

在初始化 .changeset 文件夾后,就可以正常使用 changeset 相關的命令,主要是這 3 個命令:

  • pnpm chageset 用于生成本次修改的要添加到 CHANGELOG.md 中的描述
  • pnpm changeset version 用于生成本次修改后的包的版本
  • pnpm changeset publish 用于發布包

此外,如果是在業務場景下,我們通常需要把包發到公司 私有的 NPM Registry ,而這有很多種配置方式。但是, 需要注意 的是 Changesets 只支持在每個包中聲明 publicConfig.registry 或者配置 process.env.npm_config_registry ,對應的代碼會是這樣:

// https://github.com/changesets/changesets/blob/main/packages/cli/src/commands/publish/npm-utils.ts
function getCorrectRegistry(packageJson?: PackageJSON): string {
const registry =
packageJson?.publishConfig?.registry ?? process.env.npm_config_registry;
return !registry || registry === "https://registry.yarnpkg.com"
? "https://registry.npmjs.org"
: registry;
}

可以看到,如果在前面說的這 2 種情況下獲取不到 registry 的話,Changesets 都是按公共的 Registry 去查找或者發布包的。

Turborepo

說起 Turborepo,可能大家會有點陌生。但是,對于 Vercel [17] 我想大家都知道(畢竟 Rich Harris [18] 、Sebastian Markb?ge 等都加入了),Turbrepo 則是 Vercel 旗下的一個開源項目。Turborepo 是用于為 JavaScript/TypeScript 的 Monorepo 提供一個極快的構建系統,簡單地理解就是用 Turborepo 來執行 Monorepo 項目的中構建(或者其他)任務會 非常快 !

關于 Turborepo 其他優勢,其 官方文檔 [19] 寫的很詳盡,有興趣的同學可以自行了解~

所以,你可以理解成 快 是選擇 Turborepo 負責 Monorepo 項目多包任務執行的原因。而在 Turborepo 中執行多包任務是通過 turbo run <script> 。不過, turbo run 和 lerna run 直接使用有所不同,它需要配置 turbo.json 文件,注冊每個需要執行的 script 命令。

在 Turborepo 中有個 Pipelines [20] 的概念,它是由 turbo.json 文件中的 pipline 字段的配置描述,它會在執行 turbo run 命令的時候,根據對應的配置進行 有序的執行 和 緩存輸出的文件 。

舉個例子,通常情況下我們一個 Monorepo 項目中的每個包可能會有 dev 、 build 、 test 、 clean 等 4 個命令,那么對應的 turbo.json 的配置會是這樣:

{
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**"]
},
"clean": {
"dependsOn": ["^clean"]
},
"test": {
"dependsOn": ["build" "lint"]
},
"dev": {
"cache": false
}
}
}

可以看到, pipeline 中的每個 key 則對應著每個需要執行的 turbo run 命令的名稱,其中 dependsOn 、 outputs 、 cache 等 3 個字段分別作用為:

  • dependsOn 表示當前命令所依賴的命令,^ 表示 dependencies 和 devDependencies 的所有依賴都執行完 build,才執行 build
  • outputs 表示命令執行輸出的文件緩存目錄,例如我們常見的 dist、coverage 等
  • cache 表示是否緩存,通常我們執行 dev 命令的時候會結合 watch 模式,所以這種情況下關閉掉緩存比較切合實際需求

這樣一來,我們就可以使用諸如 turbo run build test 的命令,它則會按 pipeline 的配置依次執行對應的命令。

當然,如果你想每個命令都支持單獨執行,可以直接配置為 {} 即可。此外,如果要使用 turbo run 命令,還需要在 package.json 中聲明 packageManage 字段為指定的包管理工具及版本,例如 "packageManager": "pnpm@6.30.0" 。

結語

閱讀到此處,我想大家應該理解了 PNPM + Turborepo + Changesets 這個技術選型的原因以及要怎么做。當然,這個選型只是我個人的思考所得出的答案,相信也有同學仍然鐘情于 Lerna,又或者喜歡 Rush 一把梭,這些觀點并無對錯,本質上這也是編程的魅力所在, 各個輪子都有其存在的價值 。

責任編輯:張燕妮 來源: Code center
相關推薦

2023-04-11 08:02:26

單測技術JUnit框架

2023-08-23 18:56:46

2021-03-25 09:41:43

前端Monorepo技術熱點

2016-10-21 15:58:51

容器容器技術Docker

2022-06-08 13:25:51

數據

2024-01-22 10:18:32

平臺工程開發人員技術

2012-07-12 09:37:23

Instagram工程技術

2023-12-07 07:02:00

大倉權限設計

2018-07-23 15:35:17

機器學習特征工程技能數據科學

2020-09-25 07:40:39

技術開發選型

2021-03-10 09:33:51

技術研發管理

2023-03-31 13:53:00

低代碼平臺選型

2022-03-18 08:57:17

前端數據流選型

2018-02-27 15:10:38

區塊鏈分布式系統工程技術

2024-09-03 11:37:48

2017-05-05 10:55:31

Web應用登錄工程身份驗證

2025-03-14 08:00:59

TypeScript編譯器Go

2021-02-22 09:30:09

go開發環境桌面系統
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日本高清中文字幕 | 国产精品1区| 久久精品国产一区二区三区 | 狠狠操电影 | 在线第一页 | 天堂资源最新在线 | 久草网址 | 国产精品视频一二三 | 成人在线免费 | 伊人网在线播放 | 亚洲国产欧美在线人成 | 日韩精品中文字幕一区二区三区 | h视频网站在线观看 | 不卡的av在线 | 欧美一区二区三区在线 | 欧美成人猛片aaaaaaa | 欧美日韩视频在线 | 户外露出一区二区三区 | 欧美一二三四成人免费视频 | 日韩一区二区免费视频 | 精品免费视频 | a级片www| 欧美色综合 | 亚洲高清一区二区三区 | 在线视频久久 | 免费同性女女aaa免费网站 | 国产一级视屏 | 国产精品久久国产精品 | 久久精品一区二区 | 国产精品久久久久久久久久久久 | japanhd美女动| 特a毛片 | 91精品久久久久久久久久入口 | 久草在线在线精品观看 | 欧美性久久久 | 在线观看欧美一区 | 亚洲高清视频一区二区 | 国产精品成人在线 | 2018国产精品 | 一本色道精品久久一区二区三区 | 国产1区在线 |