deno.com
本頁內容

模組與依賴性

Deno 使用 ECMAScript 模組 作為其預設模組系統,以符合現代 JavaScript 標準,並促進更有效率和一致的開發體驗。它是 JavaScript 模組的官方標準,可以實現更好的 tree-shaking、改進的工具整合,以及跨不同環境的原生支援。

透過採用 ECMAScript 模組,Deno 確保與不斷發展的 JavaScript 生態系統相容。對於開發人員來說,這意味著一個簡化且可預測的模組系統,避免了與 CommonJS 等舊式模組格式相關的複雜性。

匯入模組 跳到標題

在此範例中,add 函數是從本地 calc.ts 模組匯入的。

calc.ts
export function add(a: number, b: number): number {
  return a + b;
}
main.ts
// imports the `calc.ts` module next to this file
import { add } from "./calc.ts";

console.log(add(1, 2)); // 3

您可以透過在包含 main.tscalc.ts 的目錄中呼叫 deno run main.ts 來執行此範例。

使用 ECMAScript 模組時,本地匯入規範符必須始終包含完整檔案副檔名。它不能省略。

example.ts
// WRONG: missing file extension
import { add } from "./calc";

// CORRECT: includes file extension
import { add } from "./calc.ts";

匯入第三方模組和函式庫 跳到標題

在 Deno 中使用第三方模組時,請使用與本地程式碼相同的 import 語法。第三方模組通常從遠端註冊表匯入,並以 jsr:npm:https:// 開頭。

main.ts
import { camelCase } from "jsr:@luca/cases@1.0.0";
import { say } from "npm:cowsay@1.6.0";
import { pascalCase } from "https://deno.land/x/case/mod.ts";

Deno 推薦 JSR,這個現代 JavaScript 註冊表,用於第三方模組。在那裡,您可以找到大量文件完善的 ES 模組用於您的專案,包括 Deno 標準函式庫

您可以 在此處閱讀更多關於 Deno 對 npm 套件支援的資訊

管理第三方模組和函式庫 跳到標題

在多個檔案中匯入模組時,輸入完整版本規範符的模組名稱可能會變得繁瑣。您可以使用 deno.json 檔案中的 imports 欄位集中管理遠端模組。我們將此 imports 欄位稱為匯入地圖,它基於 Import Maps Standard

deno.json
{
  "imports": {
    "@luca/cases": "jsr:@luca/cases@^1.0.0",
    "cowsay": "npm:cowsay@^1.6.0",
    "cases": "https://deno.land/x/case/mod.ts"
  }
}

使用重新對應的規範符,程式碼看起來更簡潔

main.ts
import { camelCase } from "@luca/cases";
import { say } from "cowsay";
import { pascalCase } from "cases";

重新對應的名稱可以是任何有效的規範符。這是 Deno 中一個非常強大的功能,可以重新對應任何內容。在此處 瞭解更多關於匯入地圖可以做什麼

區分 deno.json 中的 importsimportMap--import-map 選項 跳到標題

Import Maps Standard 要求每個模組有兩個條目:一個用於模組規範符,另一個用於帶有尾部 / 的規範符。這是因為標準只允許每個模組規範符有一個條目,而尾部 / 表示規範符指的是一個目錄。例如,當使用 --import-map import_map.json 選項時,import_map.json 檔案必須包含每個模組的兩個條目(請注意使用 jsr:/@std/async 而不是 jsr:@std/async

import_map.json
{
  "imports": {
    "@std/async": "jsr:@std/async@^1.0.0",
    "@std/async/": "jsr:/@std/async@^1.0.0/"
  }
}

相反地,deno.json 擴展了匯入地圖標準。當您在 deno.json 中使用 imports 欄位,或透過 importMap 欄位引用 import_map.json 檔案時,您只需要指定不帶尾部 / 的模組規範符

deno.json
{
  "imports": {
    "@std/async": "jsr:@std/async@^1.0.0"
  }
}

使用 deno add 新增依賴性 跳到標題

使用 deno add 子命令可以輕鬆完成安裝過程。它會自動將您請求的套件的最新版本新增到 deno.json 中的 imports 區段。

# Add the latest version of the module to deno.json
$ deno add jsr:@luca/cases
Add @luca/cases - jsr:@luca/cases@1.0.0
deno.json
{
  "imports": {
    "@luca/cases": "jsr:@luca/cases@^1.0.0"
  }
}

您也可以指定確切的版本

# Passing an exact version
$ deno add jsr:@luca/cases@1.0.0
Add @luca/cases - jsr:@luca/cases@1.0.0

deno add 參考中閱讀更多資訊。

您也可以使用 deno remove 移除依賴性

$ deno remove @luca/cases
Remove @luca/cases
deno.json
{
  "imports": {}
}

deno remove 參考中閱讀更多資訊。

套件版本 跳到標題

可以為您要匯入的套件指定版本範圍。這是透過使用 @ 符號後跟版本範圍規範符來完成的,並遵循 semver 版本控制方案。

例如

@scopename/mypackage           # highest version
@scopename/mypackage@16.1.0    # exact version
@scopename/mypackage@16        # highest 16.x version >= 16.0.0
@scopename/mypackage@^16.1.0   # highest 16.x version >= 16.1.0
@scopename/mypackage@~16.1.0   # highest 16.1.x version >= 16.1.0

以下是您可以指定版本或範圍的所有方式的概述

符號 描述 範例
1.2.3 確切的版本。只會使用這個特定版本。 1.2.3
^1.2.3 與 1.2.3 版相容。允許不更改最左邊非零數字的更新。
例如,允許 1.2.41.3.0,但不允許 2.0.0
^1.2.3
~1.2.3 約略等於 1.2.3 版。允許更新到修補程式版本。
例如,允許 1.2.4,但不允許 1.3.0
~1.2.3
>=1.2.3 大於或等於 1.2.3 版。允許任何 1.2.3 或更高版本。 >=1.2.3
<=1.2.3 小於或等於 1.2.3 版。允許任何 1.2.3 或更低版本。 <=1.2.3
>1.2.3 大於 1.2.3 版。僅允許高於 1.2.3 的版本。 >1.2.3
<1.2.3 小於 1.2.3 版。僅允許低於 1.2.3 的版本。 <1.2.3
1.2.x 次要版本 1.2 內的任何修補程式版本。例如,1.2.01.2.1 等。 1.2.x
1.x 主要版本 1 內的任何次要和修補程式版本。例如,1.0.01.1.01.2.0 等。 1.x
* * *

允許任何版本。

HTTPS 匯入 跳到標題

import { Application } from "https://deno.land/x/oak/mod.ts";

Deno 也支援引用 HTTP/HTTPS URL 的 import 語句,可以直接引用

{
  "imports": {
    "oak": "https://deno.land/x/oak/mod.ts"
  }
}

或作為您的 deno.json 匯入地圖的一部分

unpkg.com

如果您有一個小的、通常是單一檔案的 Deno 專案,不需要任何其他設定,HTTPS 匯入非常有用。使用 HTTPS 匯入,您可以完全避免使用 deno.json 檔案。但是,建議在較大的應用程式中使用這種匯入方式,因為您最終可能會遇到版本衝突(不同的檔案使用不同的版本規範符)。

資訊

請謹慎使用 HTTPS 匯入,且僅從受信任的來源使用。如果伺服器遭到入侵,它可能會向您的應用程式提供惡意程式碼。如果您在不同的檔案中匯入不同的版本,它們也可能導致版本問題。HTTPS 匯入仍然受支援,但我們建議使用套件註冊表以獲得最佳體驗。

覆寫依賴性 跳到標題

Deno 提供了覆寫依賴性的機制,使開發人員能夠在開發或測試期間使用自訂或本地版本的函式庫。

注意:如果您需要快取並在本機修改依賴性以供跨建置使用,請考慮供應商化遠端模組

覆寫本地 JSR 套件 跳到標題

範例

deno.json
{
  "patch": [
    "../some-package-or-workspace"
  ]
}

對於熟悉 Node.js 中 npm link 的開發人員,Deno 透過 deno.json 中的 patch 欄位為本地 JSR 套件提供了類似的功能。這允許您在開發期間使用本地版本覆寫依賴性,而無需發布它們。

  • 重點
  • patch 欄位接受包含 JSR 套件或工作區的目錄路徑。如果您引用工作區中的單一套件,則將包含整個工作區。
  • 此功能僅在工作區根目錄中受到尊重。在其他地方使用 patch 將觸發警告。

目前,patch 僅限於 JSR 套件。嘗試修補 npm 套件將導致警告,但沒有效果。

  • 限制
  • 尚不支援 npm 套件覆寫。這計劃在未來的更新中實現。
  • 基於 Git 的依賴性覆寫不可用。
  • patch 欄位需要在工作區根目錄中進行正確的設定。

此功能是實驗性的,可能會根據使用者回饋而變更。

覆寫 NPM 套件 跳到標題

我們計劃使用上述修補功能支援 NPM 套件,但在那之前,如果您有 node_modules 目錄,則可以使用 npm link 而無需更改即可達到相同的效果。這通常是透過在 deno.json 檔案中設定 { "nodeModulesDir": "manual" } 來完成的。另請參閱關於 node_modules 的文件

覆寫 HTTPS 匯入 跳到標題

範例

deno.json
{
  "imports": {
    "example/": "https://deno.land/x/example/"
  },
  "scopes": {
    "https://deno.land/x/example/": {
      "https://deno.land/x/my-library@1.0.0/mod.ts": "./patched/mod.ts"
    }
  }
}

對於熟悉 Node.js 中 npm link 的開發人員,Deno 透過 deno.json 中的 patch 欄位為本地 JSR 套件提供了類似的功能。這允許您在開發期間使用本地版本覆寫依賴性,而無需發布它們。

  • Deno 也允許透過 deno.json 中的 importMap 欄位覆寫 HTTPS 匯入。當使用本地修補版本替換遠端依賴性以進行除錯或臨時修復時,此功能特別有用。
  • 匯入地圖中的 scopes 欄位允許您將特定匯入重新導向到替代路徑。
  • 這通常用於使用本地檔案覆寫遠端依賴性以進行測試或開發目的。

匯入地圖僅適用於專案的根目錄。依賴性內的巢狀匯入地圖將被忽略。

供應商化遠端模組 跳到標題

如果您的專案有外部依賴性,您可能希望將它們儲存在本地,以避免每次建置專案時都從網際網路下載它們。當在 CI 伺服器或 Docker 容器中建置專案,或修補或以其他方式修改遠端依賴性時,這尤其有用。

{
  "vendor": true
}

Deno 透過 deno.json 檔案中的設定提供此功能

deno install --entrypoint main.ts

將以上程式碼片段新增到您的 deno.json 檔案中,當專案執行時,Deno 會將所有依賴性在本機快取到 vendor 目錄中,或者您可以選擇執行 deno install --entrypoint 命令立即快取依賴性

deno run main.ts

然後,您可以像往常一樣使用 deno run 執行應用程式

在供應商化之後,您可以使用 --cached-only 標誌執行 main.ts 而無需網際網路連線,這會強制 Deno 僅使用本機可用的模組。

如需更進階的覆寫,例如在開發期間替換依賴性,請參閱覆寫依賴性

發布模組 跳到標題

  • 任何定義匯出的 Deno 程式都可以作為模組發布。這允許其他開發人員在他們自己的專案中匯入和使用您的程式碼。模組可以發布到
  • JSR - 推薦,原生支援 TypeScript 並為您自動產生文件
  • npm - 使用 dnt 建立 npm 套件

deno.land/x - 對於 HTTPS 匯入,請盡可能改用 JSR

重新載入模組 跳到標題

預設情況下,Deno 使用全域快取目錄 (DENO_DIR) 來存放下載的依賴性。此快取在所有專案之間共用。

# Reload everything
deno run --reload my_module.ts

# Reload a specific module
deno run --reload=jsr:@std/fs my_module.ts

您可以使用 --reload 標誌強制 deno 重新提取並重新編譯模組到快取中。

僅使用快取模組 跳到標題

deno run --cached-only mod.ts

若要強制 Deno 僅使用先前已快取的模組,請使用 --cached-only 標誌

如果 mod.ts 的依賴樹中有任何尚未快取的依賴性,這將會失敗。

完整性檢查與鎖定檔 跳到標題

想像一下,您的模組依賴於位於 https://some.url/a.ts 的遠端模組。當您第一次編譯模組時,會提取、編譯和快取 a.ts。這個快取版本將會被使用,直到您在不同的機器上執行模組(例如在生產環境中),或手動重新載入快取(使用像 deno install --reload 這樣的命令)。

但是,如果 https://some.url/a.ts 的內容發生變化呢?這可能會導致您的生產模組運行的依賴程式碼與您的本地模組不同。為了檢測到這一點,Deno 使用完整性檢查和鎖定檔。

  1. Deno 使用 deno.lock 檔案來檢查外部模組的完整性。若要選擇加入鎖定檔,請執行以下任一操作

    在目前目錄或祖先目錄中建立 deno.json 檔案,這將自動在 deno.lock 建立一個附加鎖定檔。

    deno.json
    {
      "lock": false
    }
    
  2. 請注意,可以透過在您的 deno.json 中指定以下內容來停用此功能

使用 --lock 標誌啟用並指定鎖定檔檢查。

凍結鎖定檔 跳到標題

預設情況下,Deno 使用附加鎖定檔,其中新的依賴性會新增到鎖定檔中,而不是產生錯誤。

deno.json
{
  "lock": {
    "frozen": true
  }
}

在某些情況下(例如 CI 管道或生產環境),這可能不是期望的,在這些情況下,您寧願 Deno 在遇到它從未見過的依賴性時產生錯誤。若要啟用此功能,您可以指定 --frozen 標誌或在 deno.json 檔案中設定以下內容

當使用凍結鎖定檔執行 deno 命令時,任何更新鎖定檔內容的嘗試都會導致命令退出並顯示本應進行的修改。

如果您希望更新鎖定檔,請在命令列上指定 --frozen=false 以暫時停用凍結鎖定檔。

變更鎖定檔路徑 跳到標題

deno.json
{
  "lock": {
    "path": "deps.lock"
  }
}

可以透過指定 --lock=deps.lock 或在 Deno 設定檔中指定以下內容來設定鎖定檔路徑

私有儲存庫 跳到標題

注意

如果您正在尋找私有 npm 註冊表和 .npmrc 支援,請造訪 npm 支援頁面。

在某些情況下,您可能想要載入位於私有儲存庫中的遠端模組,例如 GitHub 上的私有儲存庫。

Deno 支援在請求遠端模組時發送持有者權杖。持有者權杖是 OAuth 2.0 中使用的主要存取權杖類型,並受到託管服務(例如 GitHub、GitLab、Bitbucket、Cloudsmith 等)的廣泛支援。

DENO_AUTH_TOKENS 跳到標題

  • Deno CLI 將尋找名為 DENO_AUTH_TOKENS 的環境變數,以確定在請求遠端模組時應考慮使用哪些身份驗證權杖。環境變數的值格式為 n 個權杖,以分號 (;) 分隔,其中每個權杖可以是
  • 格式為 {token}@{hostname[:port]} 的持有者權杖,或

格式為 {username}:{password}@{hostname[:port]} 的基本身份驗證資料

DENO_AUTH_TOKENS=a1b2c3d4e5f6@deno.land

例如,deno.land 的單一權杖看起來像這樣

DENO_AUTH_TOKENS=username:password@deno.land

DENO_AUTH_TOKENS=a1b2c3d4e5f6@deno.land;f1e2d3c4b5a6@example.com:8080;username:password@deno.land

多個權杖看起來像這樣

當 Deno 要提取遠端模組時,如果主機名稱與遠端模組的主機名稱相符,Deno 會將請求的 Authorization 標頭設定為 Bearer {token}Basic {base64EncodedData} 的值。這允許遠端伺服器識別請求是與特定經過身份驗證的使用者相關聯的授權請求,並提供對伺服器上適當資源和模組的存取權。

GitHub 跳到標題

Personal access tokens settings on GitHub

若要存取 GitHub 上的私有儲存庫,您需要為自己發行個人存取權杖。您可以透過登入 GitHub 並前往設定 -> 開發人員設定 -> 個人存取權杖來完成此操作

Creating a new personal access token on GitHub

然後,您將選擇產生新權杖,並為您的權杖提供描述和對 repo 範圍的適當存取權。repo 範圍將啟用讀取檔案內容(有關 GitHub 文件中的範圍的更多資訊

Display of newly created token on GitHub

一旦建立,GitHub 將單次顯示新權杖,您將希望在環境變數中使用該值

DENO_AUTH_TOKENS=a1b2c3d4e5f6@raw.githubusercontent.com

為了存取包含在 GitHub 私有儲存庫中的模組,您將希望在 DENO_AUTH_TOKENS 環境變數中使用針對 raw.githubusercontent.com 主機名稱範圍設定的產生權杖。例如

這應該允許 Deno 存取權杖頒發的使用者有權存取的任何模組。

當權杖不正確,或使用者無權存取模組時,GitHub 將發出 404 Not Found 狀態,而不是未經授權的狀態。因此,如果您在命令列上收到錯誤,指出您嘗試存取的模組未找到,請檢查環境變數設定和個人存取權杖設定。

此外,deno run -L debug 應印出關於從環境變數中解析出的權杖數量的除錯訊息。如果它認為任何權杖格式錯誤,它將印出錯誤訊息。出於安全目的,它不會印出有關權杖的任何詳細資訊。

發送其他回饋