倉儲庫的結構
turbo
建構於 工作區之上,這是 JavaScript 生態系統中套件管理工具的一項功能,可讓您在一個倉儲庫中群組多個套件。
遵循這些慣例非常重要,因為它可讓您
- 在您倉儲庫的所有工具中依賴這些慣例
- 快速、逐步地將 Turborepo 導入現有倉儲庫
在本指南中,我們將逐步設定多套件工作區 (monorepo),以便為 turbo
奠定基礎。
開始使用
手動設定工作區結構可能很繁瑣。如果您是 monorepo 新手,我們建議使用 create-turbo
開始,立即獲得有效的工作區結構。
然後您可以檢閱倉儲庫,以查看本指南中描述的特性。
工作區的結構
在 JavaScript 中,工作區可以是單一套件或套件集合。在這些指南中,我們將重點放在多套件工作區,通常稱為「monorepo」。
以下重點說明 create-turbo
的結構元素,使其成為有效的工作區。
最低要求
在 monorepo 中指定套件
宣告套件的目錄
首先,您的套件管理工具需要描述套件的位置。我們建議從將套件分成 apps/
(用於應用程式和服務)和 packages/
(用於其他所有內容,例如程式庫和工具)開始。
使用此組態,apps
或 packages
目錄中每個具有 package.json
的目錄都將被視為套件。
Turborepo 不支援巢狀套件,例如 apps/**
或 packages/**
,因為 JavaScript 生態系統中套件管理工具之間的行為不明確。使用會將一個套件放在 apps/a
,另一個套件放在 apps/a/b
的結構將導致錯誤。
如果您想按目錄群組套件,您可以使用 glob,例如 packages/*
和 packages/group/*
,而不要建立 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
函數,如下所示
以這種方式使用 exports 提供三大優點
- 避免 barrel 檔案:Barrel 檔案是指重新匯出同一套件中其他檔案的檔案,為整個套件建立一個進入點。雖然它們看起來可能很方便,但編譯器和捆綁器很難處理它們,並且可能會快速導致效能問題。
- 更強大的功能:與
main
欄位相比,exports
還具有其他強大的功能,例如條件匯出。一般來說,我們建議盡可能使用exports
而不是main
,因為它是更現代化的選項。 - IDE 自動完成:透過使用
exports
指定套件的進入點,您可以確保您的程式碼編輯器可以為套件的匯出提供自動完成功能。
imports
(選用)
imports
欄位為您提供了一種在套件內建立其他模組子路徑的方式。您可以將這些視為「捷徑」,以寫出更簡單的匯入路徑,這些路徑更能適應移動檔案的重構。若要了解如何操作,請造訪TypeScript 頁面。
您可能更熟悉 TypeScript 的 compilerOptions#paths
選項,它完成了類似的目標。從 TypeScript 5.4 開始,TypeScript 可以從 imports
推斷子路徑,使其成為更好的選項,因為您將使用 Node.js 慣例。如需更多資訊,請造訪我們的 TypeScript 指南。
原始碼
當然,您會在套件中放入一些原始碼。套件通常使用 src
目錄來儲存其原始碼,並編譯到 dist
目錄(也應該位於套件內),儘管這不是必需的。
常見陷阱
- 如果您使用 TypeScript,您可能不需要工作區根目錄中的
tsconfig.json
。套件應該獨立指定自己的組態,通常以工作區中單獨套件的共用tsconfig.json
為基礎。如需更多資訊,請造訪TypeScript 指南。 - 您希望盡可能避免跨套件邊界存取檔案。如果您發現自己正在寫入
../
以從一個套件移到另一個套件,您可能有一個機會重新思考您的方法,方法是將套件安裝在需要它的位置,並將其匯入到您的程式碼中。
後續步驟
設定好工作區後,您現在可以使用套件管理工具將依賴性安裝到您的套件中。