2021年管理Monorepo代碼庫的11種出色工具

Vue.js 3.0 源碼管理用的Lerna

現在,許多工具能夠在20個不一樣的文件夾中運行「npm install」和「npm run build」。可是,並非全部的工具都能促進正確的monorepo。vue

促進一個正確的單體開發意味着要解決一些挑戰,好比爲分離的模塊運行測試和構建過程,可以從項目中獨立發佈模塊,以及管理變動對項目中每一個受影響的依賴模塊的部分影響。node

挑戰的清單還在繼續,甚至包括「瑣碎」的事情,好比你如何管理issues和PRs,這可能會隨着你的開發規模而變得困難。react

請注意, 一個monorepo不是一個總體的應用程序(!) ——它不是一次性構建或部署的,它是一組單獨開發的應用程序。

什麼是 monorepo?

國慶期間10月5日尤大公開了vue3.0已完成的源碼,也是採用了monorepo管理模式,看來monorepo確實有其獨到的優點。webpack

monorepo是一種將多個package放在一個repo中的代碼管理模式,摒棄了傳統的多個package多個repo的模式。git

目前 Babel, React, Angular, Ember, Meteor, Jest等許多開源項目都使用該種模式來管理代碼。github

解決的問題web

  • 多個repo難以管理,編輯器須要打開多個項目;
  • 某個模塊升級,依賴改模塊的其餘模塊須要手動升級,容易疏漏;
  • 公用的npm包重複安裝,佔據大量硬盤容量,好比打包工具webpack會在每一個項目中安裝一次;
  • 對新人友好,一句命令便可完成全部模塊的依賴安裝,且整個項目模塊不用到各個倉庫去找;

帶來的問題npm

  • 全部package代碼集中在一個項目,單個項目體積較大;
  • 全部package代碼對全部人可見,沒法作權限管理;

還不知道monorpo的同窗能夠閱讀如下文章:json

在這篇綜述中,我收集了一些世界上最好的工具來構建一個「monorepo」,你能夠在一個項目裏面構建多個模塊,而且有不錯的開發者體驗,能夠擴展。bootstrap

這個列表並無進行排名,旨在根據每一個工具的優勢來概述其優點。但願能幫助你節省時間,找到合適的工具。

歡迎在下方評論,分享本身的心得。

1. Yarn Workspaces

Yarn Workspaces 的目標是簡化與monorepos的工做,以更明確的方式解決 yarn link 的一個主要用例。你的依賴關係能夠連接在一塊兒,這意味着你的工做空間能夠相互依賴,同時老是使用最新的代碼。這也是比 yarn link 更好的機制,由於它隻影響你的工做空間樹而不是你的整個系統。

Workspaces有助於解決一些問題,使其成爲一個很好的單兵裝備。

  • 它設置了一個單一的 node_modules,不須要在項目中的不一樣包中重複或克隆依賴關係。
  • 你的全部項目依賴都將被安裝在一塊兒,從而給Yarn更大的空間來更好地優化它們。
  • Yarn將使用一個單一的鎖文件,而不是爲每一個項目使用不一樣的鎖文件,這意味着更少的衝突和更容易的審查。
  • 它容許你改變你的一個軟件包的代碼,並讓使用它的其餘軟件包當即看到這些變化。對一個包的源代碼的任何修改都會當即應用到其餘包中。

所以,Yarn Workspaces是一個很是強大的組合,能夠和列表中的幾乎全部工具,特別是Bit、Nx和Lerna等工具一塊兒使用,做爲你的monorepo管理抽象的下層。

不過,你也能夠直接用workspaces發佈。當一個工做空間被打包到一個存檔中時,它會動態地將任何 workspace: 依賴關係替換爲一個包的版本,所以您能夠將結果包發佈到遠程註冊表,而無需運行中間步驟——消費者將可以像使用任何其餘包同樣使用發佈的工做空間。太酷了!

參考閱讀基於lerna和yarn workspace的monorepo工做流

2. Bit

Bit是用於構建模塊化項目的下一代工具。這是一種新的、使人興奮的單倉庫方法,在這種方法中,由同一個項目(同一個Bit工做空間)管理的模塊實際上分佈在不一樣的範圍內,而不考慮倉庫。

Bit讓你以徹底解耦的方式拆分模塊的開發,享受簡單的、總體的開發體驗來協調一切。

使用bit,你能夠在你的項目中解耦組件,這樣每一個組件都是獨立開發、構建、測試和發佈的。每一個組件都是使用特殊的環境進行開發和構建的,這些環境是可擴展和可重用的,這樣你就能夠快速定製和再次使用它們。

Bit的工做空間管理着項目中全部組件之間的關係。當你對任何組件進行更改時,Bit會單獨構建和測試它,並將更改傳播到依賴關係圖中。

組件能夠做爲獨立的包,批量發佈到NPM和/或bit.dev平臺,用於協做、消費和文檔。

Bit的UI能夠幫助你查看你的monorepo的開發狀況。當你編寫代碼時,每一個組件都會被記錄、測試、構建等,你能夠經過實時反饋和熱重載直觀地看到正在發生的事情。

Bit提供瞭解耦的開發環境--可重用和可定製的模塊,這些模塊將獨立組件整個生命週期所需的不一樣服務配置和「捆綁」在一塊兒,如編譯、捆綁、測試、磨合、文檔等。

Bit的工做空間以簡單而全面的方式解耦組件開發

掌握組件圖——Bit定義、管理並幫助你利用項目中全部組件之間的關係。

圖形驅動的構建——當您對某個組件進行更改時,Bit會自動檢測依賴於它的其餘組件,並「知道」只構建依賴組件的受影響的圖形。

「圖形驅動的構建」也意味着,萬一一個組件被標記了新的發佈版本(在被導出到Bit的雲端以前),Bit不只會在每一個受影響的組件上運行構建,並且會確保給它們標記一個新的發佈版本。

隔離的測試和構建——每一個組件都是在項目外部隔離地構建和測試的,所以您能夠確切地看到更改的影響。

組件構建管道——您能夠在可重用的管道中構建做業,該管道可應用於項目或全部項目中的全部組件。

批量發佈——在Bit monorepo中開發的每一個組件均可以做爲一個獨立的包發佈。Bit去掉了配置每一個組件的「package.json」和其餘設置文件的全部開銷。你要作的就是運行'bit tag',這樣Bit就會自動給全部修改過的組件打上版本補丁(支持semver規則),而後批量發佈修改。

可重複使用的文檔模板——每一個組件都使用可重複使用和可定製的模板進行文檔化,Bit爲您自動完成大部分工做。用MDX工做?也許還能夠添加一些可視化的例子?沒問題。

獨立渲染的組合——每一個組件都是徹底獨立渲染的,徹底在項目以外渲染,渲染的視覺效果(在編寫代碼時熱從新加載)成爲每一個組件文檔的一部分。

3. NX

NX是一套先進的可擴展的開發工具,適用於monorepos,很是強調現代全棧Web技術。

空NX monorepo

NX的目標是經過CLI(帶編輯器插件)提供總體的開發體驗,並提供可控代碼共享和一致代碼生成的功能。它還提供了增量構建,所以它不會在你的每一次提交中重建和從新測試全部內容,從而加快構建時間。

有了Nx,你可使用你喜歡的框架,集成你可能已經在使用的現代工具。例如,NX可讓你使用與Cypress、Jest、Typescript、Prettier和其餘工具的開箱即用的集成。

NX團隊還提供了NX雲,經過雲中的智能計算記憶和更快的構建來幫助使用NX的團隊更快地交付。

8

4. Rush

Rush是由微軟+開源的一個強大的monorepo基礎設施,它的目的是幫助你在一個倉庫中構建和發佈許多包。

登錄頁面和一些組件,兩個項目,一個倉庫

rush的一些主要功能包括一個單一的NPM安裝(也能夠和Yarn和pnpm一塊兒使用),因此你能夠將全部項目的全部依賴關係安裝到一個共同的文件夾中,使用隔離的符號連接爲每一個項目從新構建一個準確的「node_modules」文件夾。

這也有助於確保沒有幻影依賴,因此你不會意外地導入一個在package.json中缺失的庫,也不會在node_modules中發現10份lib的依賴重複。

Rush交互式CLI不錯

自動本地連接意味着你全部的項目都會自動地相互創建符號連接,當你作了一個改變,你能夠看到下游的效果,而不須要發佈任何東西,也沒有任何 npm link 的麻煩。

Rush獨特的安裝策略爲你的全部項目生成一個快速安裝的單一收縮/鎖定文件。Rush會檢測你的依賴關係圖,並以正確的順序構建你的項目,因此若是兩個包之間沒有直接的依賴關係,Rush會將它們做爲單獨的進程並行構建。

若是你只打算使用你的repo中的幾個項目,Rush提供了子集和增量構建,因此 rush rebuild --to <project> 只對你的上游依賴進行乾淨的構建。在你作了修改以後,rush rebuild --from <project> 只對受影響的下游項目進行清理。而 rush build 則提供了強大的跨項目增量構建,Rush甚至能夠經過分離項目的版原本處理循環依賴關係。

當你想發佈的時候,Rush支持批量發佈,因此它會檢測哪些包有變化,自動跳轉全部相關的版本號,並在每一個文件夾中運行 npm publish

Rush還有助於實施和執行發展政策。例如,當建立PR時,你能夠要求開發人員提供受影響項目的主要/次要/補丁日誌條目,這些條目隨後將在發佈時彙總到一個變動日誌文件中。它還能夠幫助你執行諸如發佈前的審查、特定的依賴版本等東西。

5. Lerna

Lerna(以多頭野獸Hydra的家命名)是一個「用於管理帶有多個包的JavaScript項目的工具」。

Lerna的建立是爲了解決Babel的多包問題,以優化使用git和npm管理多包倉庫的工做流程,它本質上是一種工具和腳本,能夠有效地管理和發佈許多獨立版本的包在一個Git倉庫中。

my-lerna-repo/
  package.json
  packages/
    package-1/
      package.json
    package-2/
      package.json

Lerna 的兩個主要命令是 lerna bootstraplerna publishbootstrap 會將 repo 中的依賴關係鏈接在一塊兒,publish 會幫助發佈任何更新的包。

您可使用如下兩種模式之一來管理項目:固定(Fixed)或獨立(Independent)。

固定模式的Lerna項目是以單一的版本行來操做的,版本是保存在你的項目根目錄下的 lerna.json 文件中的 version 鍵。當您運行 lerna publish 時,若是一個模塊在上次發佈後被更新,它將被更新到您發佈的新版本。這是Babel目前使用的模式。

一個帶有Yarn Workspaces的Lerna例子

獨立模式Lerna項目容許維護者相互獨立地增長包的版本,每次發佈時,你都會收到一個提示,提示你每個已經改變的軟件包,以指定它是一個補丁,小的,大的或自定義的變化。獨立模式可讓你更具體地更新每一個包的版本,對於一組包來講是有意義的。

「lerna.json」文件是一個匹配包含 package.json 的目錄的globs列表,這也是lerna識別「葉子」包的方式(相對於管理整個repo的開發依賴和腳本)。例子:

{
  "version": "1.1.3",
  "npmClient": "npm",
  "command": {
    "publish": {
      "ignoreChanges": ["ignored-file", "*.md"],
      "message": "chore(release): publish",
      "registry": "https://npm.pkg.github.com"
    },
    "bootstrap": {
      "ignore": "component-*",
      "npmClientArgs": ["--no-package-lock"]
    }
  },
  "packages": ["packages/*"]
}

即便你不打算髮布到NPM,Lerna仍然能夠在monorepo中幫助管理版本管理和常見的開發任務。

6. Bazel構建系統 (Google)

谷歌推出了Bazel build system,它是一個相似於Make、Maven和Gradle的開源構建和測試工具,使用的是人類可讀的高級構建語言。Bazel支持多種語言的項目,併爲多種平臺構建輸出。它支持大型單一倉庫中的大型代碼庫或跨多個倉庫的大型代碼庫和大量用戶。

Uber開發者使用Bazel來構建他們的Go monorepo。Uber用Go編寫了大部分的後端服務和庫,在2018年,這些服務和庫都被概括到一個大型的Go monorepo中,如今有超過10萬個文件。Bazel讓這個項目得以擴展,縮短了構建時間,並支持其發展。

這是一個不錯的小型開源項目,以Bazel做爲演示: thundergolfer/example-bazel-monorepo

Bazel被設計成大規模工做,並支持跨分佈式基礎設施的增量密封構建,這是大型代碼庫所必需的。有了Bazel的遠程緩存,構建服務器還能夠共享它們的構建工件。Bazel緩存全部之前完成的工做,並跟蹤對文件內容和構建命令的更改。只有在包或包的依賴關係發生更改時,才構建和測試包。

Bazel能夠在Linux、macOS和Windows上運行。Bazel能夠從同一個項目爲多個平臺構建二進制文件和可部署的包,包括桌面、服務器和移動設備。支持許多語言,你能夠擴展Bazel來支持任何其餘語言或框架。

7. Buck構建系統 (Facebook)

Buck是一個鼓勵建立由代碼和資源組成的小型可重用模塊的構建系統,支持不一樣平臺上的各類語言。

它是由Facebook開發和使用的,做爲FB單體的官方構建系統,因爲被Uber開發者等團隊使用,大大縮短了構建時間,所以名聲大噪。而AirbnbEng的團隊則將構建速度提升了50%,將應用程序縮小了30%。

Uber憑藉buck得到了更好的構建結果

Buck被設計用來構建一個monorepo,而對monorepo設計的支持激發了Buck對cell和項目的支持。

Facebook的經驗是,將全部的依賴關係維護在同一個版本庫中,能夠更容易地確保全部開發者擁有正確的代碼版本,並簡化了進行原子提交的過程。

Buck經常使用於Android和iOS開發。

8. Pants構建系統(Twitter)

2014年,Twitter推出了名爲Pants的monorepo構建系統。今天,在v2版本上,Pants的目標是成爲一個快速、可擴展的構建系統,以適應不斷增加的代碼庫。目前,它的重點是Python,很快就會支持其餘語言。

Pants使用細粒度的工做流,並將每一個工做單元與反作用隔離,所以能夠利用全部可用的內核。Pant的一些最佳特性包括明確的依賴建模、細粒度的無效化、共享結果緩存、併發執行、遠程執行,以及經過插件API的可擴展性和可定製性。

Pants引擎是用Rust寫的,爲的是性能。構建規則是用類型化的Python 3寫的,爲了熟悉和簡單。該引擎的設計使得細粒度的無效化、併發性、密封性、緩存和遠程執行天然發生,而無需規則做者的干預。

9. Please構建系統

Please是一個跨語言的構建系統,強調高性能、可移植性、可擴展性和正確性。

請確保構建步驟是在本身的密封環境中執行的,只能訪問被賦予權限的文件和env變量。增量構建意味着它只構建它須要的東西,它還提供了任務並行性,以及分佈式緩存,以實現大規模的可靠和高性能的構建系統。

Please的目標也是專一於開發體驗,因此你能夠享受一個經常使用的CLI,併爲使用自動完成的常見任務定義別名。

Please用Go編寫,Please提供全部這些用戶體驗,沒有運行時依賴。而且,沒有須要處理太多配置的單個大工做區文件。

10. Oao

Oao並非列表中最成熟、最豐富、最容易使用的工具,但它仍是頗有趣。它是一個基於Yarn的,有意見的monorepo管理工具,p提供monorepo功能,如安裝全部的依賴關係,添加/刪除/升級子包的依賴關係,驗證版本號,肯定更新的子包,一次性發布全部的東西,更新變動日誌等。

Oao可讓你在全部子包上運行命令或 package.json 腳本,串行或並行,可選擇遵循反向依賴樹。並且,它支持yarn workspaces,從總體上優化了monorepo依賴樹,簡化了bootstrap以及依賴的添加/升級/刪除。

支持非單包發佈:從oao’s的發佈前檢查、標籤、版本選擇、變動日誌更新等方面受益,也能夠在你的單包、非單包中使用。須要注意的是,Oao使用的是同步版本方案,因此在根級的 package.json 中配置了一個主版本,而子包也將與該版本同步。你能夠在這裏嘗試一下。

11. Bolt

Boltpkg旨在成爲一個「超級功能JavaScript項目管理工具」。

Bolt在Yarn的基礎上實現了workspaces的概念。Bolt CLI在很大程度上是Yarn CLI的替代品,你能夠在任何Yarn項目中使用它。

咱們知道,workspaces是嵌套在一個更大的項目/repo中的,每一個workspaces均可以有本身的依賴關係,有本身的代碼和腳本。workspaces也能夠納入子目錄進行組織。

使用Bolt,你能夠一次安裝全部這些包的依賴關係(並且你能夠作得很是很是快)。並且,當你從一個工做區指定一個依賴關係到另外一個工做區時,它將被連接到源代碼。這樣,當你去測試你的代碼時,你全部的變化都會被一塊兒測試。


原文:https://blog.zhangbing.site/2020/12/28/how-to-implement-lazy-loading-in-react-with-intersection-observer/

相關文章
相關標籤/搜索