組織儲存庫
turbo
建構於 工作區 之上,這是 JavaScript 生態系中套件管理工具的一項功能,可讓您將多個套件分組在一個儲存庫中。
遵循這些慣例非常重要,因為這可讓您:
- 在您儲存庫的所有工具中利用這些慣例
- 快速地將 Turborepo 逐步導入現有的儲存庫
在本指南中,我們將逐步說明如何設定多套件工作區(monorepo),以便為 turbo
奠定基礎。
開始使用
手動設定工作區的結構可能很繁瑣。如果您是 monorepo 的新手,我們建議使用 create-turbo
立即開始,並建立有效的工作區結構。
然後,您可以檢查儲存庫是否具有本指南中描述的特性。
工作區的結構
在 JavaScript 中,工作區可以是單一套件,也可以是多個套件的集合。在這些指南中,我們將重點放在多套件工作區,通常稱為「monorepo」。
下方將重點說明 create-turbo
的結構元素,使其成為有效的工作區。
最低需求
在 monorepo 中指定套件
宣告套件的目錄
首先,您的套件管理工具需要描述套件的位置。我們建議從將套件分割成 apps/
(用於應用程式和服務)和 packages/
(用於其他所有內容,例如函式庫和工具)開始。
使用此組態,在 apps
或 packages
目錄中,每個具有 package.json
的目錄都會被視為一個套件。
由於 JavaScript 生態系中套件管理工具之間存在不明確的行為,因此 Turborepo 不支援巢狀套件,例如 apps/**
或 packages/**
。使用將套件放在 apps/a
和另一個放在 apps/a/b
的結構將會導致錯誤。
如果您想要依目錄分組套件,可以使用類似 packages/*
和 packages/group/*
的 glob,而不是建立 packages/group/package.json
檔案。
每個套件中的 package.json
在套件的目錄中,必須有 package.json
才能讓套件對套件管理工具和 turbo
而言是可探索的。下方列出套件的 package.json
的需求。
根 package.json
根 package.json
是您工作區的基礎。下方是您會在根 package.json
中找到的常見範例
根 turbo.json
turbo.json
用於設定 turbo
的行為。若要深入瞭解如何設定任務,請造訪設定任務頁面。
套件管理工具鎖定檔
鎖定檔是您的套件管理工具和 turbo
可重複行為的關鍵。此外,Turborepo 使用鎖定檔來了解您工作區中內部套件之間的相依性。
如果您在執行 turbo
時沒有鎖定檔,可能會看到無法預期的行為。
套件的結構
最好開始將設計套件視為工作區內自己的單元。在高階層次上,每個套件幾乎都像是自己的小型「專案」,具有自己的 package.json
、工具組態和原始碼。這個想法有一些限制,但它是個很好的起點。
此外,套件具有特定的進入點,工作區中的其他套件可以使用這些進入點來存取套件,並由 exports
指定。
套件的 package.json
name
name
欄位用於識別套件。它在您的工作區中應是唯一的。
最佳做法是為您的內部套件使用命名空間字首,以避免與 npm 登錄檔上的其他套件發生衝突。例如,如果您的組織名稱是 acme
,您可能會將您的套件命名為 @acme/package-name
。
我們在我們的文件和範例中使用 @repo
,因為它在 npm 登錄檔上是未使用且無法宣告的命名空間。您可以選擇保留它或使用您自己的字首。
scripts
scripts
欄位用於定義可以在套件的內容中執行的指令碼。Turborepo 將使用這些指令碼的名稱來識別要在套件中執行哪些指令碼(如果有的話)。我們在執行任務頁面上會進一步討論這些指令碼。
exports
exports
欄位用於指定想要使用套件的其他套件的進入點。當您想要使用一個套件中的程式碼到另一個套件時,您會從該進入點匯入。
例如,如果您有一個 @repo/math
套件,您可能會具有下列 exports
欄位
請注意,此範例為了簡化起見使用了即時套件模式。它直接匯出 TypeScript,但您可以選擇改用編譯套件模式。
此範例中的 exports
欄位需要 Node.js 和 TypeScript 的現代版本。
這可讓您從 @repo/math
套件匯入 add
和 subtract
函式,如下所示
以這種方式使用匯出可帶來三個主要優點
- 避免使用 barrel 檔案:Barrel 檔案是重新匯出同一個套件中其他檔案的檔案,為整個套件建立一個進入點。雖然它們看起來很方便,但編譯器和 bundler 很難處理,而且可能會快速導致效能問題。
- 更強大的功能:與
main
欄位相比,exports
也具有其他強大功能,例如條件匯出。一般而言,我們建議盡可能使用exports
而不是main
,因為它是比較現代的選項。 - IDE 自動完成:透過使用
exports
指定套件的進入點,您可以確保您的程式碼編輯器可以為套件的匯出提供自動完成功能。
好消息
您也可以使用萬用字元指定 exports
。不過,您會因為 TypeScript 編譯器的效能取捨而失去一些 IDE 自動完成功能。如需詳細資訊,請造訪TypeScript 指南。
imports
(選用)
imports
欄位可讓您建立套件中其他模組的子路徑。您可以將這些子路徑視為「捷徑」,以撰寫更簡單的匯入路徑,更能夠復原移動檔案的重構。若要瞭解如何操作,請造訪TypeScript 頁面。
您可能更熟悉 TypeScript 的 compilerOptions#paths
選項,該選項可達成類似的目標。從 TypeScript 5.4 開始,TypeScript 可以從 imports
推斷子路徑,使其成為更好的選項,因為您將使用 Node.js 慣例。如需詳細資訊,請造訪我們的 TypeScript 指南。
原始碼
當然,您會在套件中需要一些原始碼。套件通常會使用 src
目錄來儲存其原始碼,並編譯到 dist
目錄(也應該位於套件中),儘管這不是必要條件。
常見的陷阱
- 如果您使用 TypeScript,您可能不需要在工作區的根目錄中具有
tsconfig.json
。套件應該獨立指定自己的組態,通常是從工作區中個別套件的共用tsconfig.json
進行建置。如需詳細資訊,請造訪TypeScript 指南。 - 您希望盡可能避免跨套件界限存取檔案。如果您發現自己正在寫入
../
以從一個套件移到另一個套件,您可能會找到機會重新思考您的方法,方法是在需要的地方安裝套件,並將其匯入您的程式碼。
後續步驟
設定好您的工作區後,您現在可以使用您的套件管理器將相依性安裝到您的套件中。
這對您有幫助嗎?