import.meta.resolve()
import.meta.resolve() 是 JavaScript 模組的 import.meta 物件上定義的內建函式,它使用當前模組的 URL 作為基礎,將模組說明符解析為 URL。
語法
import.meta.resolve(moduleName)
引數
moduleName-
指定一個可能可匯入模組的字串。這可以是一個相對路徑(例如
"./lib/helper.js")、一個裸名稱(例如"my-module")或一個絕對 URL(例如"https://example.com/lib/helper.js")。
返回值
返回一個字串,該字串對應於如果將引數傳遞給 import() 將匯入的路徑。
描述
import.meta.resolve() 允許指令碼訪問名稱的模組說明符解析演算法,如下所示:
// 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() 返回將要匯入的路徑,而不嘗試訪問該路徑。因此,以下兩個程式碼片段實際上是相同的:
// 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()。例如,您可以在瀏覽器中使用匯入對映來定義它:
<!-- 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()。
const helperPath = new URL("./lib/helper.js", import.meta.url).href;
console.log(helperPath);
當針對舊版瀏覽器時,這也是一個有用的替代語法。但是,存在一些差異:
import.meta.resolve()返回一個字串,而new URL()返回一個URL物件。可以在構造的URL上使用href或toString(),但這在某些 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() 也可能在非瀏覽器環境中可用:
- Deno 實現了與瀏覽器行為的相容性。
- Node.js 也實現了
import.meta.resolve()函式,但如果使用--experimental-import-meta-resolve標誌,則會新增一個額外的parent引數。
示例
為 Worker() 建構函式解析路徑
import.meta.resolve() 對於接受指令碼檔案路徑作為引數的 API 特別有價值,例如 Worker() 建構函式:
// main.js
const workerPath = import.meta.resolve("./worker.js");
const worker = new Worker(workerPath, { type: "module" });
worker.addEventListener("message", console.log);
// worker.js
self.postMessage("hello!");
這對於計算其他 Worker 的路徑也很有用,例如服務 Worker 和共享 Worker。但是,如果您使用相對路徑來計算服務 Worker 的 URL,請記住,已解析路徑的目錄預設決定了它的註冊範圍(儘管可以在註冊期間指定不同的範圍)。
規範
| 規範 |
|---|
| HTML # import-meta-resolve |
瀏覽器相容性
載入中…