Rush Stack商店部落格活動
跳至主要內容

為什麼要使用單一大型儲存庫?

開源 NPM 套件似乎都在許多小的 GitHub 儲存庫中開發。我不是也應該這樣做嗎?

當然,如果你正在建構獨立的元件,而且它們如何組合在一起不是那麼重要。但商業軟體似乎不是這樣運作的。它更像是這樣:

大多數人最初都是建構單一的 Web 應用程式,而不是一堆程式庫。在你的應用程式發佈後,它會不斷地成長。然後有一天,你需要與另一個專案共用一些程式碼,你才意識到你已經有了一個很大的老鼠窩。是時候重構了!

顯然,你必須將這個東西分成可管理的元件。NPM 套件是在 JavaScript 中執行此操作的方法。環顧四周,約定俗成的做法似乎是「每個 NPM 套件一個 GitHub 儲存庫。」在一個英勇的一兩週內,你建立了 10 個 Git 儲存庫,分割了你的程式碼,並嘗試了一下...

...但使用 10 個 Git 儲存庫 ternyata 是一個很大的麻煩! 有太多令人頭痛的問題

  • 目光短淺:如果同事主要在儲存庫 #5 和 #6 中工作,他們似乎完全忽略了其他 8 個儲存庫的提取請求。新的儲存庫每天都在不知不覺中出現。

  • 級聯發佈:將修復程式從 lib3 傳播到你的應用程式專案需要以正確的順序更新/建置/發佈許多 Git 儲存庫: lib3 --> lib2 --> lib1 --> 應用程式。當 lib3 頻繁變更時,這會變得非常繁瑣。人們甚至如何記住正確的發佈順序?網路上有很多方法可以解決這個問題,但你的人力有限,而且他們非常忙碌。

  • 下游受害者:當 Bob 發佈對 lib3 的變更時,所有下游專案可能需要一段時間才能升級以使用它。如果出現回歸,Alice 可能要過一週才能在 lib1 中嘗試執行 "npm update" 並發現問題。到那時,也許 Bob 已經出發去歐洲背包旅行了。為什麼 Alice 要承擔修復別人回歸的重擔? 似乎每次她升級時,都會有東西壞掉!

  • 連結瘋狂:解決方法是使用 npm link 將你的 應用程式 直接符號連結到 lib3 進行測試。但 NPM 會透過全域資料夾建立符號連結,如果你需要在同一台筆記型電腦上使用 lib3 的多個分支,就會造成麻煩。而且有 10 個以上的程式庫,很難記住什麼符號連結到什麼。

「每個套件一個儲存庫」 模型適用於由不協調的陌生人維護的獨立專案。(此外,大多數這些程式庫的更新頻率相當低,這使得問題更容易解決。)而在我們的範例中,每個人都在同一家公司工作,「程式庫」更像是整合式架構的元件。程式碼會經常變更,而且一個地方的變更很容易破壞系統的其他部分。一起建置多個專案可讓你為每個變更執行所有單元測試,這將修復責任轉移到它應該去的地方:到最初引入變更的人。

新興原則變為「每個團隊一個 Git 儲存庫」,甚至更好的是「盡可能少的 Git 儲存庫來完成工作」。

monorepo block diagram

許多建構大型商業軟體的人似乎最終都將他們的所有程式碼放在一個大型的「單一儲存庫」中。許多 JavaScript 只是最後一個加入派對的人。

這個策略的最大問題顯然是建置時間。 JavaScript 工具比編譯語言慢。如果一個專案需要 1 分鐘來建置,而你有 75 個專案,理論上你可能會看到荒謬的 75 分鐘建置時間。這看起來令人卻步,但使用工業級的工具鏈,你可以在建置時間成為問題之前擴展得非常遠。我們針對 Rush 和 Heft 的大部分路線圖都集中在建置時間上,而且我們樂觀地認為還有很多優化的空間。使用子集/增量建置,理論上你可以避免重建所有內容,除非變更確實影響所有內容 - 而且對於這種變更,很難說提早發現中斷不值得等待較長建置時間的代價。