Featured image of post TypeScript 路徑別名:大規模清理導入Featured image of post TypeScript 路徑別名:大規模清理導入

TypeScript 路徑別名:大規模清理導入

TypeScript 路徑別名指南,涵蓋 tsconfig 路徑、baseUrl、通配符模式、捆綁器整合、ESLint 解析和 monorepo 策略。

TypeScript 路徑別名消除了深度相對導入(如 ../../../utils/helpers)的痛苦,將其替換為乾淨的、揭示意圖的路徑(如 @utils/helpers)。本文涵蓋配置、捆綁程式整合、測試和遷移策略。

配置baseUrl和路徑

路徑別名的基礎是 tsconfig.json 中的 paths 映射,與 baseUrl 結合:

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"],
      "@components/*": ["./src/components/*"],
      "@utils/*": ["./src/utils/*"]
    }
  }
}

baseUrl 設定用於解析非相對模組名稱的基底目錄。 paths 將別名前綴對應到相對於 baseUrl 的檔案系統位置。通配符 * 符合前綴之後的任何路徑段。


通配符模式和進階映射

通配符支援靈活的映射策略:

{
  "paths": {
    "@shared/*": ["./src/shared/*"],
    "@components/*": ["./src/components/*", "./src/shared/components/*"],
    "@config": ["./src/config/index.ts"]
  }
}

如果第一個位置不存在,則依序搜尋多個後備路徑。直接模組別名(不帶通配符)對於特定條目積分很有用。


捆綁器集成

TypeScript 的 paths 僅影響類型檢查和 IDE 支援。每個捆綁器都需要自己的別名配置:

工具配置
網頁包佔位符_0
維特resolve.alias: { '@': '/src' } (或 vite-tsconfig-paths 外掛程式)
esbuild佔位符_0
西南世界中心jsc.paths 鏡像 tsconfig

對於 Vite,vite-tsconfig-paths 外掛程式會自動讀取您的 tsconfig,消除重複:

import { defineConfig } from 'vite';
import tsconfigPaths from 'vite-tsconfig-paths';

export default defineConfig({
  plugins: [tsconfigPaths()],
});

對於 Node.js 執行時期解析,請將 tsconfig-paths 套件與 tsconfig-paths/register 一起使用。


ESLint 解析度

如果沒有正確的解析器配置,ESLint 的 import/no-unresolved 規則將在別名匯入上失敗。 eslint-import-resolver-typescript 套件自動讀取 tsconfig 路徑:

settings: {
  'import/resolver': {
    typescript: { alwaysTryTypes: true }
  }
}

您也可以設定 import/order 以單獨對別名匯入進行分組:

'import/order': ['warn', {
  groups: ['builtin', 'external', 'internal', 'parent', 'sibling'],
  pathGroups: [
    { pattern: '@/**', group: 'internal', position: 'before' }
  ]
}]

單一回購策略

在 monorepos 中,每個套件通常都有自己的 tsconfig.json 和路徑別名:

  • Nx:具有共用路徑的根 tsconfig 的專案級 tsconfig
  • Turborepo:每個套件定義自己的路徑;跨包導入的工作區協定
  • pnpm 工作區:對於跨套件引用,優先使用工作區協定而不是路徑別名

TypeScript 專案引用 (composite + references) 提供了 monorepos 中路徑別名的替代方案,提供增量編譯和更快的建置。


使用路徑別名進行測試

測試運行器還需要別名配置:

// Jest - moduleNameMapper
{ "^@/(.*)$": "<rootDir>/src/$1" }

// Vitest - automatically uses Vite's resolve.alias
import { defineConfig } from 'vitest/config';
import tsconfigPaths from 'vite-tsconfig-paths';

export default defineConfig({
  plugins: [tsconfigPaths()],
});

遷移策略

逐步採用路徑別名。從新程式碼的單一 @/ 別名開始,然後使用 ts-migrate 等 codemod 或自訂 jscodeshift 轉換重構現有導入。遷移後,在 ESLint 中強制使用 import/no-relative-parent-imports 約定。

避免常見的陷阱:使用別名更難發現循環依賴關係,而過度別名(為每個目錄創建別名)會增加認知負擔,但沒有任何好處。


路徑別名顯著提高了大中型 TypeScript 專案中的程式碼可維護性。關鍵的挑戰是保持捆綁程式、測試運行程序和 linter 配置同步。使用自動讀取 tsconfig 的插件可以大大減輕這種負擔。