Featured image of post TypeScript 專案參考:擴充大型程式碼庫Featured image of post TypeScript 專案參考:擴充大型程式碼庫

TypeScript 專案參考:擴充大型程式碼庫

用於擴展大型程式碼庫的 TypeScript 專案參考。組合專案、建置模式、增量建置、單一儲存庫整合和 CI 最佳化。

介紹

隨著 TypeScript 程式碼庫的成長,單一的 tsconfig.json 方法會崩潰。每次呼叫 tsc 都會進行類型檢查並發出整個項目 - 即使在大型 monorepos 中使用 --noEmit ,這個過程也可能需要幾分鐘的時間。更糟的是,沒有模組邊界,任何文件都可以匯入任何其他文件,從而創建難以重構的混亂依賴關係圖。 TypeScript 專案參考 透過允許您將程式碼庫拆分為獨立的子專案(每個子專案都有自己的 tsconfig.json)來解決此問題,從而實現增量建置、強制執行 API 邊界以及顯著加快類型檢查速度。


什麼是項目參考?

專案引用聲明一個 TypeScript 專案依賴另一個專案。每個子項目必須在其 tsconfig.json 中設定 composite: true,並且使用項目在 references 數組中列出其依賴項:

{
  "compilerOptions": {
    "composite": true,
    "declaration": true,
    "declarationMap": true,
    "rootDir": "src",
    "outDir": "dist"
  }
}
{
  "references": [
    { "path": "../packages/core" },
    { "path": "../packages/utils" }
  ]
}

建置時,TypeScript 首先建構引用的項目(依拓樸順序),產生父專案使用的 .d.ts.js 輸出。這強制了一個清晰的、非循環的依賴關係圖——如果套件 A 引用包 B,那麼 B 就不能引用 A。任何建立循環相依性的嘗試都會產生編譯時錯誤。


組合項目和建構模式

複合項目 (composite: true) 是設計供其他項目引用的項目。它需要 declaration: truerootDiroutDir。強烈建議啟用 declarationMap: true — 它會產生 .d.ts.map 文件,允許編輯器工具(如「轉到定義」)直接導航到原始 .ts 來源而不是 .d.ts 聲明文件。

建置模式指令 tsc --build (或 tsc -b)智慧地處理整個專案圖:

# Build all projects and their dependencies
tsc -b

# Force rebuild all projects
tsc -b --force

# Clean build outputs
tsc -b --clean

# Dry run — show what would be built
tsc -b --dry

建置模式使用 .tsbuildinfo 檔案來追蹤檔案雜湊和依賴關係。在後續運行中,它會跳過輸入未更改的項目,導致大型 monorepos 的建置時間減少 50–90%。 incremental: true 選項由 composite 隱含,但您可以使用 tsBuildInfoFile 控制建置資訊檔案的寫入位置。


單一倉庫集成

專案參考與 monorepo 工具自然整合。典型的結構如下圖所示:

packages/
  core/        tsconfig.json (composite: true)
  utils/       tsconfig.json (composite: true)
apps/
  web/         tsconfig.json (references: [core, utils])
  api/         tsconfig.json (references: [core, utils])
tsconfig.base.json

不同的 monorepo 工具提供不同程度的支援:

工具支援
npm/pnpm/yarn 工作區效果很好;在根 tsconfig.json 中聲明引用
渦輪增壓透過 inputsdependsOn 提供原生支援
Nx自動偵測項目參考;並行化建置
勒納需要手動設定

聲明圖和開發者經驗

最有影響力但未充分利用的功能之一是聲明映射。當您導航到消費者專案中的類型定義(例如,VS Code 的「轉到定義」)時,如果沒有聲明映射,您將進入 .d.ts 文件,該文件僅包含類型簽名,而不包含實作。使用 declarationMap: true,您可以直接跳到原始 .ts 來源:

{
  "compilerOptions": {
    "declaration": true,
    "declarationMap": true,
    "sourceMap": true
  }
}

聲明映射的運行時開銷為零——它們僅被編輯器工具消耗。與 sourceMap: true 相結合,它們提供了從開發到生產的完整偵錯體驗。


CI優化

項目參考的真正回報來自 CI。透過在運行之間快取 .tsbuildinfo 檔案(使用 @actions/cache 或類似檔案),您可以在管道執行之間保留增量建置資訊:

# GitHub Actions — cache .tsbuildinfo files
- uses: actions/cache@v3
  with:
    path: "**/*.tsbuildinfo"
    key: tsbuildinfo-${{ runner.os }}-${{ hashFiles('**/tsconfig*.json') }}

對於選擇性類型檢查,請使用 tsc -b --noEmit — 此類型僅檢查自上次建置以來發生變更的項目,而不是整個程式碼庫。為主分支建置保留 --force ;依賴增量模式進行拉取請求 CI。對於非常大的單一儲存庫,像 nx affected 這樣的工具可以進一步將範圍縮小到受給定變更直接影響的項目。


結論

TypeScript 專案參考解決了大型 TypeScript 程式碼庫的擴充問題。首先將您的專案分成 2-3 個邏輯包 - 一個核心類型包、一個實用程式包和您的應用程式程式碼。將 composite: true 與聲明映射結合使用以獲得良好的開發人員體驗,利用 tsc -b 進行快速增量構建,並在 CI 中緩存 .tsbuildinfo 文件以跨管道運行擴展這些優勢。 Turborepo 和 Nx 等工具透過快取和並行執行增強項目引用,使它們在 monorepo 設定中更加強大。