import.meta.resolve()

Baseline 已廣泛支援

此功能已成熟,並可在許多裝置和瀏覽器版本上執行。自 2023 年 3 月以來,它已在各種瀏覽器中可用。

import.meta.resolve() 是 JavaScript 模組的 import.meta 物件上定義的內建函式,它使用當前模組的 URL 作為基礎,將模組說明符解析為 URL。

語法

js
import.meta.resolve(moduleName)

引數

moduleName

指定一個可能可匯入模組的字串。這可以是一個相對路徑(例如 "./lib/helper.js")、一個裸名稱(例如 "my-module")或一個絕對 URL(例如 "https://example.com/lib/helper.js")。

返回值

返回一個字串,該字串對應於如果將引數傳遞給 import() 將匯入的路徑。

描述

import.meta.resolve() 允許指令碼訪問名稱的模組說明符解析演算法,如下所示:

js
// Script at https://example.com/main.js

const helperPath = import.meta.resolve("./lib/helper.js");
console.log(helperPath); // "https://example.com/lib/helper.js"

請注意,import.meta.resolve() 只執行解析,不嘗試載入或匯入結果路徑。因此,它的返回值是相同的,無論返回的路徑是否對應於存在的檔案,也無論該檔案是否包含模組的有效程式碼。這使得 import.meta.resolve() 成為一個同步操作。

它與動態匯入不同,因為儘管兩者都接受模組說明符作為第一個引數,但 import.meta.resolve() 返回將要匯入的路徑,而不嘗試訪問該路徑。因此,以下兩個程式碼片段實際上是相同的:

js
// Approach 1
console.log(await import("./lib/helper.js"));

// Approach 2
const helperPath = import.meta.resolve("./lib/helper.js");
console.log(await import(helperPath));

然而,即使 "./lib/helper.js" 無法成功匯入,第二個程式碼片段在嘗試在第 2 行執行匯入之前也不會遇到錯誤。

裸模組名稱

只要為名稱定義了模組解析,就可以將裸模組名稱(也稱為裸模組說明符)傳遞給 import.meta.resolve()。例如,您可以在瀏覽器中使用匯入對映來定義它:

html
<!-- index.html -->
<script type="importmap">
  {
    "imports": {
      "my-module": "./modules/my-module/index.js"
    }
  }
</script>

<script type="module">
  const moduleEntryPath = import.meta.resolve("my-module");
  console.log(moduleEntryPath);
</script>

同樣,由於此程式碼片段不嘗試匯入 moduleEntryPath(匯入對映也不嘗試),因此無論 ./modules/my-module/index.js 是否實際存在,它都會列印已解析的 URL。

與 new URL() 的比較

URL() 建構函式接受第二個基礎 URL 引數。當第一個引數是相對路徑,並且基礎 URL 是 import.meta.url 時,效果類似於 import.meta.resolve()

js
const helperPath = new URL("./lib/helper.js", import.meta.url).href;
console.log(helperPath);

當針對舊版瀏覽器時,這也是一個有用的替代語法。但是,存在一些差異:

  • import.meta.resolve() 返回一個字串,而 new URL() 返回一個 URL 物件。可以在構造的 URL 上使用 hreftoString(),但這在某些 JavaScript 環境中或在使用打包工具進行靜態分析時,可能仍然無法產生完全相同的結果。
  • import.meta.resolve() 能夠識別額外的解析配置,例如使用匯入對映解析裸模組名稱,如上所述。new URL() 不識別匯入對映,並將裸模組名稱視為相對路徑(即 new URL("my-module", import.meta.url) 表示 new URL("./my-module", import.meta.url))。

一些工具將 new URL("./lib/helper.js", import.meta.url).href 識別為對 "./lib/helper.js" 的依賴(類似於匯入),並將其考慮用於諸如打包、重寫移動檔案的匯入、“轉到源”功能等特性。但是,由於 import.meta.resolve() 歧義較少,並且專門用於指示模組路徑解析依賴關係,因此在可能的情況下,您應該使用 import.meta.resolve(moduleName) 而不是 new URL(moduleName, import.meta.url) 來處理這些用例。

不是 ECMAScript 特性

import.meta.resolve() 未作為 JavaScript 模組的 ECMAScript 規範的一部分進行指定或文件化。相反,該規範定義了 import.meta 物件,但 將其所有屬性保留為“宿主定義”。WHATWG HTML 標準從 ECMAScript 標準未涵蓋的地方開始,並使用其 模組說明符解析定義 import.meta.resolve

這意味著並非所有符合標準的 JavaScript 實現都必須實現 import.meta.resolve()。但是,import.meta.resolve() 也可能在非瀏覽器環境中可用:

示例

為 Worker() 建構函式解析路徑

import.meta.resolve() 對於接受指令碼檔案路徑作為引數的 API 特別有價值,例如 Worker() 建構函式:

js
// main.js
const workerPath = import.meta.resolve("./worker.js");
const worker = new Worker(workerPath, { type: "module" });
worker.addEventListener("message", console.log);
js
// worker.js
self.postMessage("hello!");

這對於計算其他 Worker 的路徑也很有用,例如服務 Worker共享 Worker。但是,如果您使用相對路徑來計算服務 Worker 的 URL,請記住,已解析路徑的目錄預設決定了它的註冊範圍(儘管可以在註冊期間指定不同的範圍)。

規範

規範
HTML
# import-meta-resolve

瀏覽器相容性

另見