Turborepo logo

建立內部套件

內部套件是您工作區的建構區塊,為您提供強大的方式來跨儲存庫共用程式碼和功能。 Turborepo 會自動了解內部套件之間的關係,方法是使用 package.json 中的依賴項,在底層建立套件圖,以最佳化您儲存庫的工作流程。

Visual representation of a Package Graph in a Turborepo.

讓我們建立您的第一個內部套件,以使用套件剖析章節和已編譯套件模式中的指南,在您的儲存庫中分享數學實用程式。 在以下步驟中,我們假設您已使用 create-turbo 建立新的儲存庫,或正在使用結構類似的儲存庫。

建立空的目錄

您需要一個目錄來放置套件。 讓我們在 ./packages/math 建立一個。

package.json
turbo.json

新增 package.json

接下來,為套件建立 package.json。 透過新增此檔案,您將滿足內部套件的兩個要求,使其可被 Turborepo 和您工作區的其餘部分發現

./packages/math/package.json
{
  "name": "@repo/math",
  "type": "module",
  "scripts": {
    "dev": "tsc --watch",
    "build": "tsc"
  },
  "exports": {
    "./add": {
      "types": "./src/add.ts",
      "default": "./dist/add.js"
    },
    "./subtract": {
      "types": "./src/subtract.ts",
      "default": "./dist/subtract.js"
    }
  },
  "devDependencies": {
    "@repo/typescript-config": "*",
    "typescript": "latest"
  }
}

讓我們逐項分解此 package.json

  • scriptsdevbuild 指令碼使用TypeScript 編譯器編譯套件。 dev 指令碼將監看原始碼的變更,並自動重新編譯套件。
  • devDependenciestypescript@repo/typescript-configdevDependencies,因此您可以在 @repo/math 套件中使用這些套件。 在真實世界的套件中,您可能會擁有更多 devDependenciesdependencies - 但現在我們可以保持簡單。
  • exports:定義套件的多個進入點,使其可以在其他套件中使用 (import { add } from '@repo/math')。

值得注意的是,此 package.json 將內部套件 @repo/typescript-config 宣告為依賴項。 Turborepo 將識別 @repo/math@repo/typescript-config 的依賴項,以排序您的任務。

新增 tsconfig.json

透過將 tsconfig.json 檔案新增至套件的根目錄,指定此套件的 TypeScript 組態。 TypeScript 具有 extends 金鑰,可讓您在整個儲存庫中使用基本組態,並視需要使用不同的選項覆寫。

./packages/math/tsconfig.json
{
  "extends": "@repo/typescript-config/base.json",
  "compilerOptions": {
    "outDir": "dist",
    "rootDir": "src"
  },
  "include": ["src"],
  "exclude": ["node_modules", "dist"]
}

您在這裡完成了四件重要的事情

關於 TypeScript 組態還有很多東西要學習,但這是一個很好的起點。 如果您想了解更多資訊,請造訪官方 TypeScript 文件我們的 TypeScript 指南

新增包含原始碼的 src 目錄

您現在可以為您的套件撰寫一些程式碼。 在 src 目錄內建立兩個檔案

./packages/math/src/add.ts
export const add = (a: number, b: number) => a + b;

這些檔案對應到當您稍後執行 turbo build 時,tsc 將建立的輸出。

將套件新增至應用程式

您已準備好在應用程式中使用您的新套件。 讓我們將其新增至 web 應用程式。

apps/web/package.json
  "dependencies": {
+   "@repo/math": "*",
    "next": "latest",
    "react": "latest",
    "react-dom": "latest"
  },

您剛剛變更了儲存庫中的依賴項。 請務必執行套件管理員的安裝命令,以更新您的鎖定檔。

@repo/math 現在可在 web 應用程式中使用,您可以在程式碼中使用它

apps/web/src/app/page.tsx
import { add } from '@repo/math/add';
 
function Page() {
  return <div>{add(1, 2)}</div>;
}
 
export default Page;

編輯 turbo.json

將新 @repo/math 程式庫的成品新增至 turbo.jsonbuild 任務的 outputs。 這可確保其建置輸出將由 Turborepo 快取,以便在您開始執行建置時可以立即還原它們。

./turbo.json
{
  "tasks": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": [".next/**", "!.next/cache/**", "dist/**"]
    }
  }
}

執行 turbo build

如果您已全域安裝 turbo,請在工作區根目錄的終端機中執行 turbo build。 您也可以使用套件管理員從 package.json 執行 build 指令碼,這將使用 turbo run build

@repo/math 套件在 web 應用程式建置之前建置,因此當 web 應用程式捆綁時,./packages/math/dist 中的執行階段程式碼可用於 web 應用程式。

您可以再次執行 turbo build,以查看您的 web 應用程式在毫秒內重建。 我們將在快取指南中詳細討論此問題。

內部套件的最佳實踐

每個套件一個「用途」

當您建立內部套件時,建議建立具有單一「用途」的套件。 這不是嚴格的科學或規則,而是一種最佳實踐,取決於您的儲存庫、您的規模、您的組織、您的團隊的需求等等。 此策略具有多個優點

  • 更易於理解:隨著儲存庫擴展,在儲存庫中工作的開發人員將更容易找到他們需要的程式碼。
  • 減少每個套件的依賴項:每個套件使用較少的依賴項,使 Turborepo 能夠更有效地修剪您的套件圖的依賴項

一些範例包括

  • @repo/ui:包含所有共用 UI 元件的套件
  • @repo/tool-specific-config:用於管理特定工具組態的套件
  • @repo/graphs:用於建立和操作圖形資料的網域特定程式庫

應用程式套件不包含共用程式碼

當您建立應用程式套件時,最好避免將共用程式碼放入這些套件中。 相反地,您應該為共用程式碼建立一個單獨的套件,並讓應用程式套件依賴該套件。

此外,應用程式套件不應安裝到其他套件中。 相反地,它們應被視為您套件圖的進入點。

要知道的好消息: 

此規則有罕見的例外

下一步

在新的內部套件就位後,您可以開始設定任務