匯入斷言

基線 2025 *
新推出

自 ⁨2025 年 4 月⁩起,此功能適用於最新裝置和瀏覽器版本。此功能可能不適用於較舊的裝置或瀏覽器。

* 此特性的某些部分可能存在不同級別的支援。

注意: 此提案的先前版本使用了 assert 關鍵字而不是 with。斷言功能現在是非標準的。請檢視瀏覽器相容性表瞭解詳細資訊。

匯入屬性功能指示執行時如何載入模組,包括模組解析、獲取、解析和評估的行為。它在import宣告、export...from宣告和動態import()中都受支援。

屬性可以附加到任何型別的 import/export from 語句,包括預設匯入、名稱空間匯入等。它們跟在模組說明符字串後面,並以 with 關鍵字開頭。當與 import() 一起使用時,屬性在 options 引數中作為 with 屬性指定。

語法

js
import { names } from "module-name" with {};
import { names } from "module-name" with { key: "data" };
import { names } from "module-name" with { key: "data", key2: "data2" };
import { names } from "module-name" with { key: "data", key2: "data2", /* …, */ keyN: "dataN" };

export { names } from "module-name" with {};
export { names } from "module-name" with { key: "data" };
export { names } from "module-name" with { key: "data", key2: "data2" };
export { names } from "module-name" with { key: "data", key2: "data2", /* …, */ keyN: "dataN" };

引數

keyN

屬性鍵。可以是識別符號或字串字面量。所有鍵必須是唯一的,並且必須為執行時所知。

"dataN"

屬性值。必須是字串字面量。

描述

匯入屬性告訴執行時如何載入特定模組。

主要用例是載入非 JS 模組,例如 JSON 模組和 CSS 模組。考慮以下語句:

js
import data from "https://example.com/data.json";

在 Web 上,每個 import 語句都會導致一個 HTTP 請求。然後,響應被準備成一個 JavaScript 值,並透過執行時提供給程式。例如,響應可能看起來像這樣:

http
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
...
{"name":"Maria"}

模組僅根據其提供的 MIME 型別進行識別和解析——URL 中的副檔名不能用於識別檔案型別。在這種情況下,MIME 型別是 application/json,它告訴瀏覽器檔案是 JSON 並且必須解析為 JSON。如果由於某種原因(例如,伺服器被劫持或虛假),伺服器響應中的 MIME 型別設定為 text/javascript(用於 JavaScript 原始碼),那麼該檔案將被解析並作為程式碼執行。如果“JSON”檔案實際上包含惡意程式碼,import 宣告將無意中執行外部程式碼,構成嚴重的安全威脅。

匯入屬性透過允許作者明確指定應如何驗證模組來解決此問題。例如,上述缺少屬性的匯入語句實際上會失敗:

Failed to load module script: Expected a JavaScript module script but the server responded with a MIME type of "application/json". Strict MIME type checking is enforced for module scripts per HTML spec.

相反,你必須提供一個屬性來告訴執行時此檔案必須包含 JSON。要驗證模組的型別(透過 MIME 型別),請使用名為 type 的屬性鍵。要驗證模組是 JSON 模組,值為 "json"

注意: 實際的 type 屬性值不直接對應於 MIME 型別。它由 HTML 規範單獨指定。

因此,上面的程式碼應改寫為:

js
import data from "https://example.com/data.json" with { type: "json" };

type 屬性改變了模組的獲取方式(瀏覽器傳送帶有 Accept: application/json 頭的請求),但並改變模組的解析或評估方式。執行時已經知道根據響應 MIME 型別將模組解析為 JSON。它只使用該屬性來對 data.json 模組進行事後檢查,以確保它確實是一個 JSON 模組。例如,如果響應頭改為 Content-Type: text/javascript,程式將以與上述類似的錯誤失敗。

規範明確要求支援 type: "json" — 如果模組被斷言為 type: "json" 且執行時不使此匯入失敗,則它必須被解析為 JSON。但是,否則沒有行為要求:對於沒有 type: "json" 屬性的匯入,如果在此環境中安全不是問題,執行時仍可能將其解析為 JSON。另一方面,瀏覽器隱式假定模組是 JavaScript,如果模組不是 JavaScript(例如 JSON),則會失敗。這確保了模組型別始終嚴格驗證並防止任何安全風險。實際上,Node 和 Deno 等非瀏覽器執行時與瀏覽器語義保持一致,並對 JSON 模組強制執行 type

type 屬性還支援其他模組型別。例如,HTML 規範還定義了 css 型別,它匯入一個 CSSStyleSheet 物件:

js
import styles from "https://example.com/styles.css" with { type: "css" };

屬性語法被設計為可擴充套件的——儘管語言只指定了 type,但執行時可以讀取和處理其他屬性。屬性可以改變執行時在模組載入過程的每個階段的行為:

  • 解析:該屬性是模組說明符(from 子句中的字串)的一部分。因此,給定相同的字串路徑,不同的屬性可能導致載入完全不同的模組。例如,TypeScript 支援 resolution-mode 屬性

    ts
    import type { TypeFromRequire } from "pkg" with { "resolution-mode": "require" };
    
  • 獲取:例如,CSS 模組以 destination 設定為 "style" 獲取,JSON 模組以 destination: "json" 獲取。這意味著給定相同的目標 URL,伺服器仍可能返回不同的內容。

  • 解析和評估:執行時可以使用該屬性來確定如何解析和評估模組。

但是,您不能使用未知屬性——如果執行時遇到未知屬性,它會丟擲錯誤。

示例

使用型別屬性匯入 JSON 模組

data.json

json
{
  "name": "Shilpa"
}

index.html

html
<!doctype html>
<html lang="en-US">
  <head>
    <meta charset="utf-8" />
    <script type="module">
      import data from "./data.json" with { type: "json" };

      const p = document.createElement("p");
      p.textContent = `name: ${data.name}`;
      document.body.appendChild(p);
    </script>
  </head>
  <body></body>
</html>

啟動本地 HTTP 伺服器(參見故障排除)並訪問 index.html 頁面。您應該在頁面上看到 Shilpa

注意: JSON 模組只有一個預設匯出。您不能從它們進行命名匯入(例如 import { name } from "data.json")。

規範

規範
ECMAScript® 2026 語言規範
# prod-WithClause

瀏覽器相容性

另見