Skip to content

nujarum/resolve-esm

Repository files navigation

resolve-esm

Shim for import.meta.resolve.

npm downloads install size license node types vulnerabilities CodeQL

import.meta.resolve is currently Experimental, and is only available with the --experimental-import-meta-resolve command flag enabled.
This module provides functions equivalent to import.meta.resolve without the experimental flag.

⚠️ BREAKING CHANGES at v2.0.0

Change return types from asynchronous to synchronous

Following the change at Node.js v20 that import.meta.resolve now returns synchronously, the functions in this module have also been changed to synchronous functions.

However, asynchronous functions equivalent to v1.x can also be imported from resolve-esm/async, so users can still use asynchronous functions in situations such as when blocking is undesirable.

Change supported Node.js versions

Node.js v14 (already EOL) is no longer supported and requires Node.js v16 or higher.

Differences from similar modules

This module is just a lightweight wrapper that internally calls the original import.meta.resolve and has no resolution logic of its own.
Therefore, it will be easy to follow if the original specification changes, and easy to migrate when the original becomes Stable in the future.

Usage

Warning This module only works in Node.js (v16+) ES Modules.

$ npm i resolve-esm

Sync API

import { importMetaResolve } from 'resolve-esm'; // or 'resolve-esm/sync'

Examples
importMetaResolve('./other.js');
// => "file://path/to/__dirname/other.js"

importMetaResolve('./other.js', 'file://different/path/base.js');
// => "file://different/path/other.js"

importMetaResolve('dependency');
// => "file://path/to/node_modules/dependency/main.js"

importMetaResolve('dependency', 'file://different/path/base.js');
// => "file://different/path/node_modules/dependency/main.js"

importMetaResolve('fs');
// => "node:fs"

Async API

import { importMetaResolve } from 'resolve-esm/async';

Examples
await importMetaResolve('./other.js');
// => "file://path/to/__dirname/other.js"

await importMetaResolve('./other.js', 'file://different/path/base.js');
// => "file://different/path/other.js"

await importMetaResolve('dependency');
// => "file://path/to/node_modules/dependency/main.js"

await importMetaResolve('dependency', 'file://different/path/base.js');
// => "file://different/path/node_modules/dependency/main.js"

await importMetaResolve('fs');
// => "node:fs"

APIs

importMetaResolve

Resolve a (single) module specifier.

Sync API
function importMetaResolve(specifier: string, parent?: string | URL): string;

Async API
function importMetaResolve(specifier: string, parent?: string | URL): Promise<string>;

Parameters

  • specifier (Type: string)
    • The module specifier to resolve relative to parent.
  • parent (Type: string | URL | undefined)
    • The absolute parent module URL to resolve from.
    • If none is specified, the value of import.meta.url is used as the default.

importMetaResolveAll

Resolve multiple module specifiers with the same parent.

Sync API
function importMetaResolveAll(iterable: Readonly<Iterable<string>>, parent?: string | URL): string[];

Async API
function importMetaResolveAll(iterable: Readonly<Iterable<string>>, parent?: string | URL): Promise<string[]>;

Parameters

  • iterable (Type: Iterable<string>)
    • An iterable (such as an array) of module specifiers to resolve relative to parent.
  • parent (Type: string | URL | undefined)
    • The absolute parent module URL to resolve from.
    • If none is specified, the value of import.meta.url is used as the default.

What is this function for?

For internal implementation reasons, it is more efficient than calling importMetaResolve multiple times on your own.

  • works, but inefficient
    const results = [
        importMetaResolve('specifier1'),
        importMetaResolve('specifier2'),
        importMetaResolve('specifier3'),
    ];
  • better
    const results = importMetaResolveAll([
        'specifier1',
        'specifier2',
        'specifier3',
    ]);