import.meta.resolve()
Baseline2023Newly available
Since March 2023, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.
import.meta.resolve()
is a built-in function defined on theimport.meta
object of a JavaScript module that resolves a module specifier to a URL using the current module's URL as base.
Syntax
import.meta.resolve(moduleName)
Parameters
moduleName
A string that specifies a potentially importable module. This may be a relative path (such as
"./lib/helper.js"
), a bare name (such as"my-module"
), or an absolute URL (such as"https://example.com/lib/helper.js"
).
Return value
Returns a string corresponding to the path that would be imported if the argument were passed toimport()
.
Description
import.meta.resolve()
allows a script to access themodule specifier resolution algorithm for a name, like this:
// Script at https://example.com/main.jsconst helperPath = import.meta.resolve("./lib/helper.js");console.log(helperPath); // "https://example.com/lib/helper.js"
Note thatimport.meta.resolve()
only performs resolution and does not attempt to load or import the resulting path. Therefore, its return value is the sameregardless of whether the returned path corresponds to a file that exists, and regardless of whether that file contains valid code for a module. This allowsimport.meta.resolve()
to be asynchronous operation.
It is different fromdynamic import, because although both accept a module specifier as the first argument,import.meta.resolve()
returns the path thatwould be imported without making any attempt to access that path. Therefore, the following two are effectively the same code:
// Approach 1console.log(await import("./lib/helper.js"));// Approach 2const helperPath = import.meta.resolve("./lib/helper.js");console.log(await import(helperPath));
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
You can pass a bare module name (also known as a bare module specifier) toimport.meta.resolve()
, as long as module resolution is defined for the name. For example, you can define this using animport map inside a browser:
<!-- 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>
Again, since this snippet does not try to importmoduleEntryPath
— neither does the import map — it prints the resolved URL regardless of whether./modules/my-module/index.js
actually exists.
Comparison with new URL()
TheURL()
constructor accepts a secondbase URL argument. When the first argument is a relative path and the base URL isimport.meta.url
, the effect is similar toimport.meta.resolve()
.
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()
returns a string, whilenew URL()
returns aURL
object. It is possible to usehref
ortoString()
on the constructedURL
, but this may still not produce the exact same result in some JavaScript environments or when using tools like bundlers to statically analyze the code.import.meta.resolve()
is aware of additional resolution configurations, such as resolving bare module names using import maps, as described above.new URL()
is not aware of import maps and treats bare module names as relative paths (i.e.,new URL("my-module", import.meta.url)
meansnew URL("./my-module", import.meta.url)
).
Some tools recognizenew 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, sinceimport.meta.resolve()
is less ambiguous and specifically designed to indicate a module path resolution dependency, you should useimport.meta.resolve(moduleName)
instead ofnew URL(moduleName, import.meta.url)
for these use cases wherever possible.
Not an ECMAScript feature
import.meta.resolve()
is not specified or documented as part of theECMAScript specification for JavaScript modules. Instead, the specification definestheimport.meta
object butleaves all its properties as "host-defined". The WHATWG HTML standard picks up where the ECMAScript standard leaves off, anddefinesimport.meta.resolve
using itsmodule specifier resolution.
This means thatimport.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:
- Deno implementscompatibility with browser behavior.
- Node.js also implementsthe
import.meta.resolve()
function, but adds an additionalparent
parameter if you use the--experimental-import-meta-resolve
flag.
Examples
Resolve a path for the Worker() constructor
import.meta.resolve()
is particularly valuable for APIs that take a path to a script file as an argument, such as theWorker()
constructor:
// main.jsconst workerPath = import.meta.resolve("./worker.js");const worker = new Worker(workerPath, { type: "module" });worker.addEventListener("message", console.log);
// worker.jsself.postMessage("hello!");
This is also useful to calculate paths for other workers, such asservice workers andshared 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 itsregistration scope by default (although a different scope can be specifiedduring registration).
Specifications
Specification |
---|
HTML # import-meta-resolve |