Rush 子空間
什麼是子空間?
子空間是 Rush 的一項功能,可讓單一單體儲存庫使用多個 PNPM 鎖定檔進行安裝。例如,如果子空間名稱為 my-team
,則會有一個資料夾 common/config/subspaces/my-team/
,其中包含 pnpm-lock.yaml
檔案和相關設定。每個 Rush 專案都只屬於一個子空間,而單體儲存庫仍然只有一個統一的「工作區」。因此,專案的 package.json
檔案可以使用 workspace:
指定詞來相依於其他子空間的專案。
有什麼好處?
一般來說,最好為整個單體儲存庫使用單一鎖定檔,因為這樣可以最佳化安裝時間,並盡量減少管理版本衝突的維護工作。但是,在某些情況下,使用多個鎖定檔具有優勢。
非常大的程式碼庫:鎖定檔可以視為一個巨大的多變數方程式,我們透過協調許多專案中的 NPM 套件版本選擇來解決這個方程式,以消除衝突並盡量減少重複。(Lockfile Explorer 文件深入說明了這一點。)將單體儲存庫相依性分成較小的鎖定檔確實會使這些方程式變小且更容易解決,但代價是增加了管理版本的總開銷。對於非常大的工程團隊來說,分配工作可能比盡量減少總工作量更重要。
分離的專案集:大型程式碼庫可能會有某些專案叢集,其相依性與儲存庫的其餘部分不一致。例如,假設有 50 個專案組成一個使用已淘汰或過時框架的舊版應用程式,而沒有進行現代化的商業動機。將這些專案移至子空間可讓其版本控制獨立管理。
安裝測試:發佈 NPM 套件時,某些錯誤無法使用
workspace:*
符號連結來重現。例如,虛擬相依性或不正確的.npmignore
全域模式會導致套件的外部使用者發生失敗,但在單體儲存庫中測試相同的程式庫時,可能會運作良好。將測試專案移至子空間(與注入的相依性結合使用)會產生更精確的安裝,可以發現此類問題,同時仍然避免實際發佈到測試 NPM 登錄的開銷。
我需要多少子空間?
我們通常建議「盡可能少」,以盡量減少額外的版本管理開銷。每個團隊一個子空間是一個合理的上限。也就是說,此功能已在具有 1,000 多個子空間的生產單體儲存庫中成功使用。
真實世界示範
Rush Stack 在 GitHub 上的自有儲存庫目前設定了兩個子空間
- common/config/subspaces/build-tests-subspace:用於測試已發佈 NPM 套件的安裝
- common/config/subspaces/default:包含所有其他專案
功能設計
每個子空間都必須在 common/config/subspaces.json 設定檔中集中註冊其名稱。專案使用 rush.json 中的 subspaceName
欄位新增至子空間。
每個子空間的設定都放在資料夾 common/config/subspaces/<子空間名稱>/
中,其中可能包含下列檔案
檔案 | 用途 |
---|---|
common-versions.json | Rush 版本覆寫 |
pnpm-config.json | PNPM 版本覆寫 |
pnpm-lock.yaml | PNPM 鎖定檔 |
repo-state.json | Rush 產生以防止手動鎖定檔變更的設定檔 |
.npmrc | 套件管理員設定 |
.pnpmfile-subspace.cjs | 程式碼版本覆寫,遵循與 .pnpmfile.cjs 相同的規格,但特定於子空間 |
除了子空間層級之外,某些檔案可以全域設定(適用於整個單體儲存庫)
子空間設定檔 | 全域設定檔 | 繼承 |
---|---|---|
common-versions.json | 無 | 啟用子空間後,禁止使用全域檔案 |
pnpm-config.json | common/config/rush/pnpm-config.json | (仍在開發中)子空間優先,但會忽略某些欄位 |
pnpm-lock.yaml | 無 | 啟用子空間後,禁止使用全域檔案 |
repo-state.json | 無 | 啟用子空間後,禁止使用全域檔案 |
.npmrc | common/config/rush/.npmrc | 子空間覆寫優先 |
.pnpmfile-subspace.cjs | common/config/rush/.pnpmfile.cjs | 子空間覆寫優先 |
請注意,下列設定檔不會移動
common/config/.npmrc-publish
:此檔案用於 Rush NPM 發佈,無論發佈的專案屬於哪個子空間common/config/.pnpmfile.cjs
:此檔案可以套用將會影響單體儲存庫中所有子空間的版本控制覆寫。為了避免跨鎖定檔的混淆互動,在大多數情況下,最好改用.pnpmfile-subspace.cjs
。
如果沒有子空間,Rush 會在 common/temp/
資料夾中產生並安裝 PNPM 工作區。啟用子空間後,這會在 common/temp/<子空間名稱>/
等資料夾中單獨執行。
有兩種基本操作模式
只有少數子空間: 您可以在
subspaces.json
中設定"preventSelectingAllSubspaces": false
,並且rush install
預設會安裝所有子空間。大量的子空間: 如果安裝所有子空間會消耗太多時間和磁碟空間,則您可以設定
"preventSelectingAllSubspaces": true
。在此模式下,當叫用rush install
或rush update
等指令時,使用者必須以某種方式篩選子空間,例如rush install --to my-project
以僅安裝指定專案的相依性rush install --subspace my-subspace
以僅安裝特定子空間rush install --to subspace:my-subspace
使用專案選取器來為屬於指定子空間的專案安裝
如何啟用子空間
請確保您的 rush.json 指定
"rushVersion": "5.122.0"
或更新版本,以及"pnpmVersion": "8.7.6"
或更新版本。使用 subspaces.json 來啟用此功能並定義子空間。您可以從 subspaces.json 文件中複製此檔案的範本,或使用
rush init
來產生它。在本教學課程中,我們將建立一個名為install-test
的子空間,用於測試 NPM 套件common/config/rush/subspaces.json
{
"$schema": "https://developer.microsoft.com/json-schemas/rush/v5/subspaces.schema.json",
/**
* Set this flag to "true" to enable usage of subspaces.
*/
"subspacesEnabled": false,
/**
* When a command such as "rush update" is invoked without the "--subspace" or "--to"
* parameters, Rush will install all subspaces. In a huge monorepo with numerous subspaces,
* this would be extremely slow. Set "preventSelectingAllSubspaces" to true to avoid this
* mistake by always requiring selection parameters for commands such as "rush update".
*/
"preventSelectingAllSubspaces": false,
/**
* The list of subspace names, which should be lowercase alphanumeric words separated by
* hyphens, for example "my-subspace". The corresponding config files will have paths
* such as "common/config/subspaces/my-subspace/package-lock.yaml".
*/
"subspaceNames": [
// The "default" subspace always exists even if you don't define it,
// but let's include it for clarity
"default",
"install-test" // 👈👈👈 Our secondary subspace name
]
}建立
default
子空間資料夾並將現有的設定檔移動到該資料夾cd my-repo
mkdir --parents common/config/subspaces/default
# Move these files:
mv common/config/rush/common-versions.json common/config/subspaces/default/
mv common/config/rush/pnpm-lock.yaml common/config/subspaces/default/
mv common/config/rush/.npmrc common/config/subspaces/default/
# Rename this file:
mv common/config/rush/.pnpmfile.cjs common/config/subspaces/default/.pnpmfile-subspace.cjs建立
install-test
子空間資料夾cd my-repo
mkdir --parents common/config/subspaces/install-test透過編輯
rush.json
將專案指派給子空間。例如rush.json
. . .
"projects": [
{
"packageName": "my-library-test",
"projectFolder": "test-projects/my-library-test",
"subspaceName": "install-test"
}
. . .如果省略任何專案的
"subspaceName"
,它們將屬於default
子空間。現在更新新子空間的鎖定檔
# Clean out the common/temp folder from before
rush purge
# Regenerate the "default" subspace:
rush update --full --subspace default
# Regenerate the "install-test" subspace:
rush update --full --subspace install-test注意:您可以在不使用
--full
來重新產生任何鎖定檔的情況下移轉到子空間,但這是一個更複雜的過程,可能需要使用指令碼來重寫pnpm-lock.yaml
檔案中的某些路徑。
另請參閱
- subspaces.json 設定檔
- rfc-4230-rush-subspaces.md:此功能的原始規格,其中更詳細地說明了動機和設計