|
# import-meta-resolve |
|
|
|
[![Build][build-badge]][build] |
|
[![Coverage][coverage-badge]][coverage] |
|
[![Downloads][downloads-badge]][downloads] |
|
|
|
Resolve things like Node.js. |
|
|
|
## Contents |
|
|
|
* [What is this?](#what-is-this) |
|
* [When to use this?](#when-to-use-this) |
|
* [Install](#install) |
|
* [Use](#use) |
|
* [API](#api) |
|
* [`resolve(specifier, parent)`](#resolvespecifier-parent) |
|
* [`moduleResolve(specifier, parent, conditions, preserveSymlinks)`](#moduleresolvespecifier-parent-conditions-preservesymlinks) |
|
* [`ErrnoException`](#errnoexception) |
|
* [Algorithm](#algorithm) |
|
* [Differences to Node](#differences-to-node) |
|
* [Types](#types) |
|
* [Compatibility](#compatibility) |
|
* [Contribute](#contribute) |
|
* [License](#license) |
|
|
|
## What is this? |
|
|
|
This package is a ponyfill for [`import.meta.resolve`][native-resolve]. |
|
It supports everything you need to resolve files just like modern Node does: |
|
import maps, export maps, loading CJS and ESM projects, all of that! |
|
|
|
## When to use this? |
|
|
|
As of Node.js 20.0, `import.meta.resolve` is still behind an experimental flag. |
|
This package can be used to do what it does in Node 16–20. |
|
|
|
## Install |
|
|
|
This package is [ESM only][esm]. |
|
In Node.js (version 16+), install with [npm][]: |
|
|
|
```sh |
|
npm install import-meta-resolve |
|
``` |
|
|
|
## Use |
|
|
|
```js |
|
import {resolve} from 'import-meta-resolve' |
|
|
|
// A file: |
|
console.log(resolve('./index.js', import.meta.url)) |
|
//=> file:///Users/tilde/Projects/oss/import-meta-resolve/index.js |
|
|
|
// A CJS package: |
|
console.log(resolve('builtins', import.meta.url)) |
|
//=> file:///Users/tilde/Projects/oss/import-meta-resolve/node_modules/builtins/index.js |
|
|
|
// A scoped CJS package: |
|
console.log(resolve('@eslint/eslintrc', import.meta.url)) |
|
//=> file:///Users/tilde/Projects/oss/import-meta-resolve/node_modules/@eslint/eslintrc/lib/index.js |
|
|
|
// A package with an export map: |
|
console.log(resolve('micromark/lib/parse', import.meta.url)) |
|
//=> file:///Users/tilde/Projects/oss/import-meta-resolve/node_modules/micromark/lib/parse.js |
|
|
|
// A node builtin: |
|
console.log(resolve('fs', import.meta.url)) |
|
//=> node:fs |
|
``` |
|
|
|
## API |
|
|
|
This package exports the identifiers [`moduleResolve`][moduleresolve] and |
|
[`resolve`][resolve]. |
|
There is no default export. |
|
|
|
### `resolve(specifier, parent)` |
|
|
|
Match `import.meta.resolve` except that `parent` is required (you can pass |
|
`import.meta.url`). |
|
|
|
###### Parameters |
|
|
|
* `specifier` (`string`) |
|
— the module specifier to resolve relative to parent |
|
(`/example.js`, `./example.js`, `../example.js`, `some-package`, `fs`, etc) |
|
* `parent` (`string`, example: `import.meta.url`) |
|
— the absolute parent module URL to resolve from; you must pass |
|
`import.meta.url` or something else |
|
|
|
###### Returns |
|
|
|
Full `file:`, `data:`, or `node:` URL (`string`) to the found thing |
|
|
|
###### Throws |
|
|
|
Throws an [`ErrnoException`][errnoexception]. |
|
|
|
### `moduleResolve(specifier, parent, conditions, preserveSymlinks)` |
|
|
|
The [“Resolver Algorithm Specification”][algo] as detailed in the Node docs |
|
(which is slightly lower-level than `resolve`). |
|
|
|
###### Parameters |
|
|
|
* `specifier` (`string`) |
|
— `/example.js`, `./example.js`, `../example.js`, `some-package`, `fs`, etc |
|
* `parent` (`URL`, example: `import.meta.url`) |
|
— full URL (to a file) that `specifier` is resolved relative from |
|
* `conditions` (`Set<string>`, default: `new Set(['node', 'import'])`) |
|
— conditions |
|
* `preserveSymlinks` (`boolean`, default: `false`) |
|
— keep symlinks instead of resolving them |
|
|
|
###### Returns |
|
|
|
A URL object (`URL`) to the found thing. |
|
|
|
###### Throws |
|
|
|
Throws an [`ErrnoException`][errnoexception]. |
|
|
|
### `ErrnoException` |
|
|
|
One of many different errors that occur when resolving (TypeScript type). |
|
|
|
###### Type |
|
|
|
```ts |
|
type ErrnoExceptionFields = Error & { |
|
errnode?: number | undefined |
|
code?: string | undefined |
|
path?: string | undefined |
|
syscall?: string | undefined |
|
url?: string | undefined |
|
} |
|
``` |
|
|
|
The `code` field on errors is one of the following strings: |
|
|
|
* `'ERR_INVALID_MODULE_SPECIFIER'` |
|
— when `specifier` is invalid (example: `'#'`) |
|
* `'ERR_INVALID_PACKAGE_CONFIG'` |
|
— when a `package.json` is invalid (example: invalid JSON) |
|
* `'ERR_INVALID_PACKAGE_TARGET'` |
|
— when a `package.json` `exports` or `imports` is invalid (example: when it |
|
does not start with `'./'`) |
|
* `'ERR_MODULE_NOT_FOUND'` |
|
— when `specifier` cannot be found in `parent` (example: `'some-missing-package'`) |
|
* `'ERR_NETWORK_IMPORT_DISALLOWED'` |
|
— thrown when trying to resolve a local file or builtin from a remote file |
|
(`node:fs` relative to `'https://example.com'`) |
|
* `'ERR_PACKAGE_IMPORT_NOT_DEFINED'` |
|
— when a local import is not defined in an import map (example: `'#local'` |
|
when not defined) |
|
* `'ERR_PACKAGE_PATH_NOT_EXPORTED'` |
|
— when an export is not defined in an export map (example: `'tape/index.js'`, |
|
which is not in its export map) |
|
* `'ERR_UNSUPPORTED_DIR_IMPORT'` |
|
— when attempting to import a directory (example: `'./lib/'`) |
|
* `'ERR_UNKNOWN_FILE_EXTENSION'` |
|
— when somehow reading a file that has an unexpected extensions (`'./readme.md'`) |
|
* `'ERR_INVALID_ARG_VALUE'` |
|
— when `conditions` is incorrect |
|
|
|
## Algorithm |
|
|
|
The algorithm for `resolve` matches how Node handles `import.meta.resolve`, with |
|
a couple of differences. |
|
|
|
The algorithm for `moduleResolve` matches the [Resolver Algorithm |
|
Specification][algo] as detailed in the Node docs (which is sync and slightly |
|
lower-level than `resolve`). |
|
|
|
## Differences to Node |
|
|
|
* `parent` defaulting to `import.meta.url` cannot be ponyfilled: you have to |
|
explicitly pass it |
|
* no support for loaders (that would mean implementing all of loaders) |
|
* no support for CLI flags: |
|
`--conditions`, |
|
`--experimental-default-type`, |
|
`--experimental-json-modules`, |
|
`--experimental-network-imports`, |
|
`--experimental-policy`, |
|
`--experimental-wasm-modules`, |
|
`--input-type`, |
|
`--no-addons`, |
|
`--preserve-symlinks`, nor |
|
`--preserve-symlinks-main` |
|
work |
|
* no support for `WATCH_REPORT_DEPENDENCIES` env variable |
|
* no attempt is made to add a suggestion based on how things used to work in |
|
CJS before to not-found errors |
|
* prototypal methods are not guarded: Node protects for example `String#slice` |
|
or so from being tampered with, whereas this doesn’t |
|
|
|
## Types |
|
|
|
This package is fully typed with [TypeScript][]. |
|
It exports the additional type [`ErrnoException`][errnoexception]. |
|
|
|
## Compatibility |
|
|
|
This package is at least compatible with all maintained versions of Node.js. |
|
As of now, that is Node.js 16 and later. |
|
|
|
## Contribute |
|
|
|
Yes please! |
|
See [How to Contribute to Open Source][contribute]. |
|
|
|
## License |
|
|
|
[MIT][license] © [Titus Wormer][author] and Node.js contributors |
|
|
|
<!-- Definitions --> |
|
|
|
[build-badge]: https://github.com/wooorm/import-meta-resolve/workflows/main/badge.svg |
|
|
|
[build]: https://github.com/wooorm/import-meta-resolve/actions |
|
|
|
[coverage-badge]: https://img.shields.io/codecov/c/github/wooorm/import-meta-resolve.svg |
|
|
|
[coverage]: https://codecov.io/github/wooorm/import-meta-resolve |
|
|
|
[downloads-badge]: https://img.shields.io/npm/dm/import-meta-resolve.svg |
|
|
|
[downloads]: https://www.npmjs.com/package/import-meta-resolve |
|
|
|
[npm]: https://docs.npmjs.com/cli/install |
|
|
|
[license]: license |
|
|
|
[author]: https://wooorm.com |
|
|
|
[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c |
|
|
|
[typescript]: https://www.typescriptlang.org |
|
|
|
[contribute]: https://opensource.guide/how-to-contribute/ |
|
|
|
[algo]: https://nodejs.org/dist/latest-v14.x/docs/api/esm.html#esm_resolver_algorithm |
|
|
|
[native-resolve]: https://nodejs.org/api/esm.html#esm_import_meta_resolve_specifier_parent |
|
|
|
[resolve]: #resolvespecifier-parent |
|
|
|
[moduleresolve]: #moduleResolvespecifier-parent-conditions-preserveSymlinks |
|
|
|
[errnoexception]: #errnoexception |
|
|