匯入斷言
基線 2025 *
新推出
注意: 此提案的先前版本使用了 assert 關鍵字而不是 with。斷言功能現在是非標準的。請檢視瀏覽器相容性表瞭解詳細資訊。
匯入屬性功能指示執行時如何載入模組,包括模組解析、獲取、解析和評估的行為。它在import宣告、export...from宣告和動態import()中都受支援。
屬性可以附加到任何型別的 import/export from 語句,包括預設匯入、名稱空間匯入等。它們跟在模組說明符字串後面,並以 with 關鍵字開頭。當與 import() 一起使用時,屬性在 options 引數中作為 with 屬性指定。
語法
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" };
引數
描述
匯入屬性告訴執行時如何載入特定模組。
主要用例是載入非 JS 模組,例如 JSON 模組和 CSS 模組。考慮以下語句:
import data from "https://example.com/data.json";
在 Web 上,每個 import 語句都會導致一個 HTTP 請求。然後,響應被準備成一個 JavaScript 值,並透過執行時提供給程式。例如,響應可能看起來像這樣:
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 規範單獨指定。
因此,上面的程式碼應改寫為:
import data from "https://example.com/data.json" with { type: "json" };
type 屬性改變了模組的獲取方式(瀏覽器傳送帶有 頭的請求),但並不改變模組的解析或評估方式。執行時已經知道根據響應 MIME 型別將模組解析為 JSON。它只使用該屬性來對 Accept: application/jsondata.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 物件:
import styles from "https://example.com/styles.css" with { type: "css" };
屬性語法被設計為可擴充套件的——儘管語言只指定了 type,但執行時可以讀取和處理其他屬性。屬性可以改變執行時在模組載入過程的每個階段的行為:
-
解析:該屬性是模組說明符(
from子句中的字串)的一部分。因此,給定相同的字串路徑,不同的屬性可能導致載入完全不同的模組。例如,TypeScript 支援resolution-mode屬性。tsimport type { TypeFromRequire } from "pkg" with { "resolution-mode": "require" }; -
獲取:例如,CSS 模組以
設定為destination"style"獲取,JSON 模組以destination: "json"獲取。這意味著給定相同的目標 URL,伺服器仍可能返回不同的內容。 -
解析和評估:執行時可以使用該屬性來確定如何解析和評估模組。
但是,您不能使用未知屬性——如果執行時遇到未知屬性,它會丟擲錯誤。
示例
使用型別屬性匯入 JSON 模組
在 data.json 中
{
"name": "Shilpa"
}
在 index.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 |
瀏覽器相容性
載入中…