網站搜尋

typescript2.0 - TypeScript 匯入路徑別名


我目前正在開發一個 TypeScript 應用程序,該應用程序由多個使用 TypeScript 編寫的 Node 模組組成,這些模組被安裝在 node_modules 目錄中。

在繼續之前,我想說明我正在使用 TypeScript 2.0,如果有需要,我也不排斥使用 2.1 開發版本。我只是想讓這個運作起來。

每個 Node 模組的結構大致如下:

dist/
    es2015/
        index.js
        utils/
            Calculator.js
            Calculator.d.ts
            Date.js
            Date.d.ts
            Flatpack.js
            Flatpack.d.ts
src/
    index.ts
    utils/
        Calculator.ts
        Date.ts
        Flatpack.ts

dist 資料夾是生成的源碼,這個路徑是使用我 tsconfig.json 文件中的 outDir 屬性配置的。我也已經配置了 package.json 中的 main 屬性為 dist/es2015/index.js。

重要事項:

  • 在我的專案中,我正在使用 moduleResolution 類型的 node
  • 我正在使用 TypeScript 2.0
  • 我不是在問如何從套件內部導入檔案。我是透過 Npm 安裝這個套件,然後從使用這個模組的應用程式內透過 packagename/ 來導入它。

現在輪到我的問題/疑問了。在從這個模組匯入檔案時,我希望能夠這樣做:

import {Sin, Cos, Tan} from "common-utils/utils/Calculator";

然而,該檔案無法解析到 dist/es2015/utils 目錄。理想情況下,我希望我的匯入能從這個特定的 dist 資料夾解析,而不是從根目錄解析,但這似乎就是目前發生的情況。

上述的匯入需要寫成以下這樣才能運作:

import {Sin, Cos, Tan} from "common-utils/dist/es2015/utils/Calculator";

不過,每次都寫 dist/es2015 並不理想,而且這只會讓某些匯入看起來非常長。我有沒有辦法配置我的模組,使其解析到 dist/es2015 目錄呢?我不想在我的專案內部加入覆寫,理想情況下每個模組都能指定檔案的解析來源。

如果你仍然不確定我在問什麼(如果這讓你感到困惑,我感到抱歉),在 Jspm 中,當你創建一個用於 Jspm 的插件/模組時,你可以在該模組的 package.json 中指定類似以下內容:

  "jspm": {
    "registry": "npm",
    "jspmPackage": true,
    "main": "my-module",
    "format": "amd",
    "directories": {
      "dist": "dist/amd"
    },

我正在尋找上述在 TypeScript 中的對應(如果存在的話)。一個映射指令,所以當最終使用者運行 npm install my-cool-package,然後在他們的應用中嘗試導入某些東西時,所有導入默認解析到 commonjs 目錄(上述 Jspm 示例使用的是 amd,但原理相同)。

這可能嗎,還是我在這裡誤解了什麼?我知道最新版本新增了一些路徑映射功能,但關於如何使用它們的文件幾乎不存在。

答案#1

所以在讀了你的評論後,我意識到我誤解了你的問題!如果你想從導入的套件的角度控制路徑,只需將你的 package.json 的 main 屬性設置為一個正確表示你的模組物件圖的文件即可。

{
  "main": "common-utils/dist/es2015/index.js"
}

如果你嘗試從專案的角度來控制匯入路徑,你需要的是 TypeScript 2 的新路徑映射功能來解決模組。你可以透過如下配置你的 tsconfig.json 來啟用路徑映射:

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "angular2/*": ["../path/to/angular2/*"],
      "local/*": ["../path/to/local/modules/*"]
    }
  }
}

然後,在你的 TypeScript 文件中,你可以這樣導入模組:

import { bootstrap } from 'angular2/bootstrap';
import { module } from 'local/module';

有關 TypeScript 2 中路徑映射功能的更多細節,請參閱此 Github 問題。

就你的情況而言,我認為以下配置應該可行:

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "common-utils/utils/*": ["./node_modules/common-utils/dist/es2015/utils/*"]
    }
  }
}

答案#2

如果你使用路徑,你將需要將絕對路徑改回相對路徑,才能在使用 tsc 將 TypeScript 編譯成純 JavaScript 後正常運作。

到目前為止,對此最受歡迎的解決方案是 tsconfig-paths。

我試過了,但對於我複雜的配置,它並沒有起作用。而且,它是在運行時解析路徑,這意味著會增加你的套件大小和解析性能的開銷。

所以,我自己寫了一個解決方案,tscpaths。

我會說它整體上更好,因為它在編譯時就替換路徑。這意味著沒有運行時依賴或任何性能開銷。它使用起來非常簡單。你只需要在 package.json 的構建腳本中添加一行即可。

這個專案還相當年輕,所以如果你的設置非常複雜,可能會有一些問題。不過,它在我的設置上運行得非常順利,儘管我的設置相當複雜。