import.meta.resolve()

import.meta.resolve() 是在 JavaScript 模块的 import.meta 对象上定义的内置函数,它使用当前模块的 URL 作为基础将模块说明符解析为 URL。

¥**import.meta.resolve()** is a built-in function defined on the import.meta object of a JavaScript module that resolves a module specifier to a URL using the current module's URL as base.

语法

¥Syntax

js
import.meta.resolve(moduleName)

参数

¥Parameters

moduleName

指定潜在可导入模块的字符串。这可以是相对路径(例如 "./lib/helper.js")、裸名称(例如 "my-module")或绝对 URL(例如 "https://example.com/lib/helper.js")。

返回值

¥Return value

返回一个与参数传递给 import() 时将导入的路径相对应的字符串。

¥Returns a string corresponding to the path that would be imported if the argument were passed to import().

描述

¥Description

import.meta.resolve() 允许脚本访问名称的模块说明符解析算法,如下所示:

¥import.meta.resolve() allows a script to access the module specifier resolution algorithm for a name, like this:

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() 仅执行解析,并不尝试加载或导入结果路径。(规范解释者 描述了此行为的原因。)因此,无论返回的路径是否对应于存在的文件,也无论该文件是否包含模块的有效代码,其返回值都是相同的。

¥Note that import.meta.resolve() only performs resolution and does not attempt to load or import the resulting path. (The explainer for the specification describes the reasoning for this behavior.) Therefore, its return value is the same regardless of whether the returned path corresponds to a file that exists, and regardless of whether that file contains valid code for a module.

它与 动态导入 不同,因为尽管两者都接受模块说明符作为第一个参数,但 import.meta.resolve() 返回将导入的路径,而不尝试访问该路径。因此,以下两个实际上是相同的代码:

¥It is different from dynamic import, because although both accept a module specifier as the first argument, import.meta.resolve() returns the path that would be imported without making any attempt to access that path. Therefore, the following two are effectively the same code:

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 行执行导入。

¥However, even if "./lib/helper.js" cannot be successfully imported, the second snippet will not encounter an error until it attempts to perform the import on line 2.

裸模块名称

¥Bare module names

你可以将裸模块名称(也称为裸模块说明符)传递给 import.meta.resolve(),只要为该名称定义了模块解析即可。例如,你可以在浏览器中使用 导入地图 来定义它:

¥You can pass a bare module name (also known as a bare module specifier) to import.meta.resolve(), as long as module resolution is defined for the name. For example, you can define this using an import map inside a browser:

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。

¥Again, since this snippet does not try to import moduleEntryPath — neither does the import map — it prints the resolved URL regardless of whether ./modules/my-module/index.js actually exists.

与 new URL() 的比较

¥Comparison with new URL()

URL() 构造函数接受第二个基本 URL 参数。当第一个参数是相对路径且基本 URL 为 import.meta.url 时,效果与 import.meta.resolve() 类似。

¥The URL() constructor accepts a second base URL argument. When the first argument is a relative path and the base URL is import.meta.url, the effect is similar to import.meta.resolve().

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

当针对较旧的浏览器时,这也是一种有用的替换语法。但是,也存在一些差异:

¥This is also a useful replacement syntax when targeting older browsers. However, there are some differences:

  • 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)

¥Some tools recognize new URL("./lib/helper.js", import.meta.url).href as a dependency on "./lib/helper.js" (similar to an import), and take this into account for features like bundling, rewriting imports for moved files, "go to source" functionality, etc. However, since import.meta.resolve() is less ambiguous and specifically designed to indicate a module path resolution dependency, you should use import.meta.resolve(moduleName) instead of new URL(moduleName, import.meta.url) for these use cases wherever possible.

不是 ECMAScript 功能

¥Not an ECMAScript feature

import.meta.resolve() 未指定或记录为 JavaScript 模块 ECMAScript 规范 的一部分。相反,规范定义了 import.meta 对象 但定义了 将其所有属性保留为 "host-defined"。WHATWG HTML 标准继承了 ECMAScript 标准的不足,并且 定义 import.meta.resolve 使用了 模块说明符分辨率

¥import.meta.resolve() is not specified or documented as part of the ECMAScript specification for JavaScript modules. Instead, the specification defines the import.meta object but leaves all its properties as "host-defined". The WHATWG HTML standard picks up where the ECMAScript standard leaves off, and defines import.meta.resolve using its module specifier resolution.

这意味着 import.meta.resolve() 不需要由所有符合的 JavaScript 实现来实现。但是,import.meta.resolve() 也可能在非浏览器环境中可用:

¥This means that import.meta.resolve() is not required to be implemented by all conformant JavaScript implementations. However, import.meta.resolve() may also be available in non-browser environments:

示例

¥Examples

解析 Worker() 构造函数的路径

¥Resolve a path for the Worker() constructor

import.meta.resolve() 对于将脚本文件的路径作为参数的 API 特别有价值,例如 Worker() 构造函数:

¥import.meta.resolve() is particularly valuable for APIs that take a path to a script file as an argument, such as the Worker() constructor:

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!");

这对于计算其他工作人员的路径也很有用,例如 服务工作进程共享工人。但是,如果你使用相对路径来计算 Service Worker 的 URL,请记住,解析路径的目录默认确定其 注册范围(尽管可以指定不同的范围 注册期间)。

¥This is also useful to calculate paths for other workers, such as service workers and shared workers. However, if you are using a relative path to calculate the URL of a service worker, keep in mind that the directory of the resolved path determines its registration scope by default (although a different scope can be specified during registration).

规范

Specification
HTML Standard
# hostgetimportmetaproperties

¥Specifications

浏览器兼容性

BCD tables only load in the browser

¥Browser compatibility

也可以看看