File size: 7,682 Bytes
bc20498
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
# 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