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

詳解Monorepo:進化、優(yōu)劣與使用場景

開發(fā) 前端
Monorepo是軟件開發(fā)中的一種代碼管理方法,它將多個項目集中到單個代碼倉庫中。Monorepo為團隊提供了簡化的代碼共享、版本控制和部署流程,同時提高了可重用性和協(xié)作效率。

Hello,大家好,我是 Sunday。

訓(xùn)練營同學(xué)在學(xué)習(xí) Vue3 或者 React 源碼的時候,可以發(fā)現(xiàn) Vue3 或者 React 的源碼是基于 monorepo(單體倉庫)架構(gòu)的。其所有相關(guān)的代碼和項目都被組織在同一個版本控制倉庫中,同時又必須使用 pnpm 進行管理。

那么為什么 Vue3 或者 React 要使用 monorepo 架構(gòu)呢? monorepo 又是什么?為什么 monorepo 要通過 pnpm 進行管理呢?這篇文章,咱們來看一下這些問題。

Monorepo的本質(zhì)及其優(yōu)勢

Monorepo是軟件開發(fā)中的一種代碼管理方法,它將多個項目集中到單個代碼倉庫中。Monorepo為團隊提供了簡化的代碼共享、版本控制和部署流程,同時提高了可重用性和協(xié)作效率。這種方法已被廣泛采用,包括一些知名公司如Google、Facebook和Microsoft等。

Monorepo一詞源自希臘語"μ?νο?"(單一)和"repo"(代碼庫)。雖然一開始可能有些反直覺,但將多個項目放置于同一代碼庫中確實帶來了許多好處。

Monorepo的演變與優(yōu)勢

Monorepo的發(fā)展經(jīng)歷了從單一倉庫巨石應(yīng)用(Monolith),到多倉庫多模塊應(yīng)用(MultiRepo),再到單倉庫多模塊應(yīng)用(MonoRepo)的階段。每個階段都有其獨特的優(yōu)勢和挑戰(zhàn),具體采用哪種方式取決于項目的需求和團隊的工作流程。

  1. 單倉庫巨石應(yīng)用(Monolith):在項目初期,Monolith結(jié)構(gòu)比較常見,因為所有代碼都集中在一個倉庫中,便于管理和部署。然而,隨著項目規(guī)模的增長,Monolith結(jié)構(gòu)逐漸顯現(xiàn)出構(gòu)建時間增加、代碼沖突頻繁以及難以維護等缺點。
  2. 多倉庫多模塊應(yīng)用(MultiRepo):為了克服Monolith的缺點,團隊可能會將項目拆分成多個較小的模塊,每個模塊使用單獨的倉庫管理。這種方式提高了模塊的獨立性,便于團隊并行開發(fā)和維護,但也帶來了跨倉庫依賴管理、版本同步問題以及工作流程復(fù)雜性增加等新挑戰(zhàn)。
  3. 單倉庫多模塊應(yīng)用(MonoRepo):為了解決多倉庫管理帶來的問題,一些團隊和項目轉(zhuǎn)向使用單一倉庫管理多個模塊。這種方式簡化了跨模塊的依賴管理,提高了代碼共享效率,并統(tǒng)一了構(gòu)建和測試流程。然而,MonoRepo也面臨著更精細的權(quán)限控制、大型倉庫性能優(yōu)化等挑戰(zhàn)。

在選擇適合項目的策略時,需要綜合考慮團隊規(guī)模、項目復(fù)雜度以及構(gòu)建測試流程的需求等因素。

圖片圖片

一個真正的Monorepo不僅僅是將多個項目代碼放在同一個代碼庫中。它還需要這些項目之間有明確的關(guān)系和定義。如果項目之間缺乏良好的關(guān)系,那么就不能稱之為Monorepo。

類似地,如果一個代碼庫包含龐大的應(yīng)用,但沒有進行合理的分割和封裝,那么這只是一個大型的代碼庫,而不是真正的Monorepo。即使你給它取一個新的名字,也無法改變它的本質(zhì)。

Monorepo中的各個項目(或模塊、組件)之間應(yīng)該有清晰、明確的依賴關(guān)系和接口定義。這有助于確保模塊之間能夠高效協(xié)作,同時保持一定程度的獨立性和可重用性。

Monorepo 優(yōu)劣

圖片圖片

圖片圖片

Monorepo 使用場景

Monorepo(單一倉庫)模式適用于多種場景,特別是在以下情況下,使用 Monorepo 可以帶來顯著的好處:

  1. 大型團隊協(xié)作:對于大型團隊在多個相關(guān)項目上進行協(xié)作時,Monorepo 可以簡化協(xié)作流程。所有項目位于同一倉庫中,團隊成員可以輕松訪問和修改跨項目的代碼,促進了團隊間的溝通和合作。
  2. 微服務(wù)架構(gòu):在微服務(wù)架構(gòu)中,系統(tǒng)由多個小型、獨立服務(wù)組成。使用 Monorepo 可以方便地管理這些服務(wù)的代碼,確保服務(wù)之間的兼容性,并簡化跨服務(wù)的重構(gòu)和共享代碼。
  3. 多平臺/多產(chǎn)品開發(fā):對于跨多個平臺(如 Web、iOS、Android)或多個產(chǎn)品線開發(fā)的公司,Monorepo 提供了一個統(tǒng)一的代碼基礎(chǔ)。這使得共享通用庫、組件和工具變得簡單,同時保持構(gòu)建和發(fā)布流程的一致性。
  4. 共享庫和組件:在開發(fā)涉及多個共享庫或可重用組件的項目時,Monorepo 允許開發(fā)人員輕松更新和維護這些共享資源。這有助于提高代碼重用率,降低維護成本。
  5. 統(tǒng)一的工具和流程:對于希望統(tǒng)一代碼風(fēng)格、構(gòu)建工具、測試框架和部署流程的團隊,Monorepo 提供了一個共同的基礎(chǔ)設(shè)施。這有助于標(biāo)準(zhǔn)化開發(fā)實踐,簡化新成員的入職過程。
  6. 原子性更改和重構(gòu):當(dāng)需要對跨多個項目或模塊的代碼進行重構(gòu)或更新時,Monorepo 使得這些更改可以作為一個原子提交進行。這降低了部署和回滾的復(fù)雜性。

統(tǒng)一配置:整合 ESLint、TypeScript 和 Babel

在 Monorepo 項目中,統(tǒng)一配置 ESLint、TypeScript 和 Babel 可以有助于保持代碼一致性,簡化項目維護,并提高開發(fā)效率。

TypeScript

我們可以在 packages 目錄中放置 tsconfig.settings.json 文件,并在文件中定義通用的 TypeScript 配置。然后,在每個子項目中,通過 extends 屬性引入通用配置,并將 compilerOptions.composite 設(shè)置為 true。理想情況下,子項目的 tsconfig.json 文件應(yīng)該只包含以下內(nèi)容:

{
  "extends": "../../tsconfig.settings.json", // 繼承通用配置
  "compilerOptions": {
    "composite": true, // 用于幫助 TypeScript 快速確定引用工程的輸出文件位置
    "outDir": "dist",
    "rootDir": "src"
  },
  "include": ["src"]
}

ESLint

對于 ESLint,我們可以使用相同的思路來配置。在每個子項目的 .eslintrc.js 文件中,使用 extends 字段繼承頂層配置,并添加或覆蓋規(guī)則。

module.exports = {
  extends: "../../.eslintrc.js",
  rules: {
    // 重寫或添加規(guī)則
  },
};

Babel

Babel 配置文件的合并方式與 TypeScript 類似,甚至更加簡單。我們只需在子項目的 .babelrc 文件中聲明如下:

{
  "extends": "../../.babelrc"
}

當(dāng)所有配置準(zhǔn)備完畢時,我們的項目目錄結(jié)構(gòu)大致如下所示:

├── package.json
├── .babelrc
├── .eslintrc
├── tsconfig.settings.json
└── packages/
    │   ├── tsconfig.settings.json
    │   ├── .babelrc
    ├── @mono/project_1/
    │   ├── index.js
    │   ├── .eslintrc
    │   ├── .babelrc
    │   ├── tsconfig.json
    │   └── package.json
    └───@mono/project_2/
        ├── index.js
        ├── .eslintrc
        ├── .babelrc
        ├── tsconfig.json
        └── package.json

以上是統(tǒng)一配置 ESLint、TypeScript 和 Babel 的方法,通過這種方式,我們可以更輕松地管理和維護 Monorepo 項目中的代碼。

為什么 vue3 || React 要使用 monorepo 架構(gòu)?

根據(jù)以上內(nèi)容所述,Vue3 采用 monorepo 架構(gòu)的決定主要基于以下幾個考慮:

  1. 便于代碼管理和共享: Monorepo 架構(gòu)使得不同模塊、組件、工具等相關(guān)的代碼可以統(tǒng)一存放在一個倉庫中,便于管理和共享。這樣的架構(gòu)有助于更好地組織代碼結(jié)構(gòu),減少重復(fù)代碼,并使得不同模塊之間的依賴關(guān)系更清晰。
  2. 更簡單的依賴管理: 在 monorepo 中,不同項目之間的依賴關(guān)系更加清晰,開發(fā)人員可以更輕松地管理這些依賴關(guān)系,確保代碼庫的穩(wěn)定性和一致性。
  3. 易于協(xié)作和開發(fā): 使用 monorepo 架構(gòu)可以促進團隊協(xié)作和開發(fā)效率。開發(fā)人員可以更方便地在不同項目之間共享代碼、解決問題,并且可以更容易地進行代碼審查和協(xié)作開發(fā)。
  4. 更好的版本管理: 將相關(guān)的項目放在同一個倉庫中,使得版本管理更加一致和統(tǒng)一。這樣做有助于確保不同模塊之間的版本兼容性,并使得發(fā)布和部署過程更加簡單和可靠。

為什么 pnpm 能實現(xiàn) Monorepo

pnpm 利用其軟鏈接和硬鏈接功能實現(xiàn)了內(nèi)容尋址存儲的方法來保存依賴項。這種方法基于依賴項內(nèi)容的哈希值確定存儲位置,帶來了以下優(yōu)勢:

  1. 依賴項共享:多個項目依賴相同版本的包時,在全局存儲中只保留一份副本,通過硬鏈接指向這個副本,大大減少了磁盤空間的占用。
  2. 內(nèi)容完整性:內(nèi)容尋址存儲確保了依賴項的完整性。任何對文件內(nèi)容的更改都會導(dǎo)致哈希值的變化,防止了依賴污染和意外更改。

其中一個受大家比較歡迎的就是我們打開 pnpm 官網(wǎng)就能直接看到的內(nèi)容,那就是安裝快:

圖片圖片

pnpm 在安裝依賴包時,主要經(jīng)歷了以下三個步驟:解析依賴、獲取依賴以及鏈接依賴。這個過程通過優(yōu)化來確保高效的依賴管理,尤其在處理大型項目或 Monorepo 時。

  1. 解析依賴(Dependency Resolution) 在這個階段,pnpm 需要確定要安裝的每個依賴包的具體版本。它會查看項目的 package.json 文件以及任何現(xiàn)有的鎖文件(如 pnpm-lock.yaml),來決定哪些版本的包需要被安裝。解析依賴時,pnpm 會遵循以下規(guī)則:
  • 版本兼容性:基于 package.json 中指定的版本范圍,選擇與之兼容的最新版本。
  • 鎖文件:如果存在鎖文件,pnpm 會優(yōu)先使用鎖文件中鎖定的版本,以確保依賴的一致性和項目的可重現(xiàn)性。
  1. 獲取依賴(Fetching Dependencies) 一旦確定了需要安裝的依賴版本,pnpm 將開始獲取這些依賴包。這個過程包括以下幾個步驟:
  • 檢查全局存儲:pnpm 首先會檢查其全局存儲中是否已經(jīng)存在所需版本的依賴包。如果已經(jīng)存在,就不需要從遠程倉庫下載,直接重用即可。
  • 下載缺失的依賴:對于全局存儲中不存在的依賴,pnpm 會從 npm 或其他配置的倉庫下載它們。下載的依賴包會被存儲在全局存儲中,以便將來重用。
  • 內(nèi)容尋址存儲:pnpm 使用內(nèi)容尋址方式來存儲依賴包,即根據(jù)包內(nèi)容的哈希值來確定存儲路徑。這確保了相同內(nèi)容的包在全局存儲中只有一份副本,節(jié)省了磁盤空間。
  1. 鏈接依賴(Linking Dependencies) 獲取依賴包之后,pnpm 需要將這些依賴鏈接到項目的 node_modules 目錄中,使得項目能夠使用這些依賴。這個步驟涉及:
  • 創(chuàng)建硬鏈接和符號鏈接:對于每個依賴包,pnpm 會在項目的 node_modules 目錄中創(chuàng)建指向全局存儲中相應(yīng)包的硬鏈接。如果是包內(nèi)部的依賴,還可能創(chuàng)建符號鏈接來保持正確的依賴結(jié)構(gòu)。
  • pnpm 通過構(gòu)建一個虛擬的 node_modules 目錄來模擬傳統(tǒng)的嵌套依賴結(jié)構(gòu),但實際上依賴之間是通過符號鏈接相連的。這樣做既保持了 npm 生態(tài)的兼容性,又避免了重復(fù)的依賴副本和深層嵌套的問題。
  • 通過這種鏈接方式,pnpm 確保了項目只能訪問其直接依賴的包,防止了對未聲明依賴的意外訪問,提高了項目的穩(wěn)定性和安全性。

通過上述三個步驟,pnpm 實現(xiàn)了對依賴的高效管理,優(yōu)化了存儲空間的使用,加快了依賴安裝的速度,同時還保證了項目依賴的一致性和隔離性。

pnpm 在安裝依賴時能夠并行執(zhí)行多個任務(wù),比如解析依賴、下載和鏈接依賴。這種并行處理機制充分利用了現(xiàn)代多核 CPU 的性能,顯著減少了安裝過程的總時間。

pnpm 安裝速度快除了上面提到的這些原因之外,它的另一個優(yōu)點是它支持增量更新。當(dāng)你添加或更新項目依賴時,pnpm 只會下載那些實際改變了的包。如果某個包的版本已經(jīng)存在于全局存儲中,pnpm 將重用這個版本,避免了不必要的下載,從而加快了安裝過程。

在 Monorepo 中,包之間經(jīng)常相互依賴。pnpm 通過 Workspace 協(xié)議支持這種內(nèi)部依賴,允許包在其 package.json 中直接引用 Monorepo 中的其他包,如:

"dependencies": {
  "foo": "workspace:^1.0.0"
}

這種方式使得在本地開發(fā)時,包之間可以輕松地相互依賴,而不需要發(fā)布到 npm 上。pnpm 會自動處理這些內(nèi)部依賴,并確保正確的鏈接和版本匹配。

在 workspace 模式下,項目根目錄通常不會作為一個子模塊或者 npm 包,而是主要作為一個管理中樞,執(zhí)行一些全局操作,安裝一些共有的依賴,每個子模塊都能訪問根目錄的依賴,適合把 TypeScript、eslint 等公共開發(fā)依賴裝在這里,下面簡單介紹一些常用的中樞管理操作。

在項目跟目錄下運行 pnpm install,pnpm 會根據(jù)當(dāng)前目錄 package.json 中的依賴聲明安裝全部依賴,在 workspace 模式下會一并處理所有子模塊的依賴安裝。

安裝項目公共開發(fā)依賴,聲明在根目錄的 package.json - devDependencies 中。-w 選項代表在 monorepo 模式下的根目錄進行操作。

// 安裝
pnpm install -wD xxx
// 卸載
pnpm uninstall -w xxx

執(zhí)行根目錄的 package.json 中的腳本

pnpm run xxx

在 workspace 模式下,pnpm 主要通過 --filter 選項過濾子模塊,實現(xiàn)對各個工作空間進行精細化操作的目的。

例如 a 包安裝 lodash 外部依賴,-S 和 -D 選項分別可以將依賴安裝為正式依賴(dependencies)或者開發(fā)依賴(devDependencies):

// 為 a 包安裝 lodash
pnpm --filter a add -S lodash // 生產(chǎn)依賴
pnpm --filter a add -D lodash // 開發(fā)依賴

指定模塊之間的互相依賴。下面的例子演示了為 a 包安裝內(nèi)部依賴 b。

// 指定 a 模塊依賴于 b 模塊
pnpm --filter a i -S b

pnpm workspace 對內(nèi)部依賴關(guān)系的表示不同于外部,它自己約定了一套 Workspace 協(xié)議。下面給出一個內(nèi)部模塊 a 依賴同是內(nèi)部模塊 b 的例子。

{
  "name": "a",
  // ...
  "dependencies": {
    "b": "workspace:^"
  }
}

在實際發(fā)布 npm 包時,workspace:^ 會被替換成內(nèi)部模塊 b 的對應(yīng)版本號(對應(yīng) package.json 中的 version 字段)。替換規(guī)律如下所示:

{
  "dependencies": {
    "a": "workspace:*", // 固定版本依賴,被轉(zhuǎn)換成 x.x.x
    "b": "workspace:~", // minor 版本依賴,將被轉(zhuǎn)換成 ~x.x.x
    "c": "workspace:^" // major 版本依賴,將被轉(zhuǎn)換成 ^x.x.x
  }
}


責(zé)任編輯:武曉燕 來源: 程序員Sunday
相關(guān)推薦

2023-06-27 13:51:07

FPGA數(shù)據(jù)中心程序

2013-12-25 16:03:39

GitGit 命令

2018-08-29 15:23:18

數(shù)據(jù)庫NoSQLMongoDB

2025-07-02 09:56:07

2025-04-24 10:40:46

CatalogFlink SQL元數(shù)據(jù)

2023-05-15 08:50:58

ContextGolang

2023-05-16 07:47:18

RabbitMQ消息隊列系統(tǒng)

2022-05-31 08:21:07

MQ使用場景消費消息

2021-04-21 09:21:07

zookeeper集群源碼

2025-02-07 14:33:04

2010-07-14 17:32:53

SQL Server

2011-05-06 11:04:37

2020-04-07 14:20:10

RabbitMMySQL數(shù)據(jù)庫

2018-08-15 09:48:27

數(shù)據(jù)庫Redis應(yīng)用場景

2024-10-10 08:46:28

2014-05-15 09:43:11

CloudaMobile WebANodejs

2013-09-09 15:55:12

SDN應(yīng)用場景

2021-08-13 12:31:26

Redis代碼Java

2024-04-11 13:41:47

2023-08-28 16:49:08

物聯(lián)網(wǎng)傳感器
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 视频精品一区二区三区 | 一级看片免费视频囗交动图 | 日韩视频高清 | 亚洲一区播放 | 午夜精品久久久久久久 | 性色av一区二区三区 | 中文一区| 国产成人精品一区二区三区 | 国产区久久 | 日韩成人在线视频 | 欧美久久久网站 | 国产成人精品一区二三区在线观看 | 国产精品无| 中文字幕免费观看 | 婷婷色国产偷v国产偷v小说 | 欧美高清视频一区 | 在线视频国产一区 | 国产精品国产三级国产aⅴ入口 | 欧美国产一区二区 | 欧美精品v国产精品v日韩精品 | 91精品久久久久久久久 | 黄色在线观看国产 | 国产精品99久久久久久久久久久久 | 精品国产18久久久久久二百 | 亚洲国产欧美在线 | 91 久久| av一级久久 | 丝袜美腿一区二区三区 | 成av在线| 日韩欧美国产一区二区三区 | 91影视| 亚洲一区二区视频在线观看 | 亚洲成人动漫在线观看 | 麻豆一区一区三区四区 | 国产日韩视频在线 | 国产目拍亚洲精品99久久精品 | 麻豆天堂 | 亚洲资源站 | 国产探花在线精品一区二区 | 日韩欧美国产精品一区二区三区 | a级片在线观看 |