@@ -55,10 +55,6 @@ property:
55
55
56
56
## Notable differences between ` import ` and ` require `
57
57
58
- ### Only Support for .mjs
59
-
60
- ESM must have the ` .mjs ` extension.
61
-
62
58
### Mandatory file extensions
63
59
64
60
You must provide a file extension when using the ` import ` keyword.
@@ -157,37 +153,132 @@ The resolver has the following properties:
157
153
158
154
### Resolver Algorithm
159
155
160
- The algorithm to resolve an ES module specifier is provided through
161
- _ESM_RESOLVE_:
156
+ The algorithm to load an ES module specifier is given through the
157
+ **ESM_RESOLVE** method below. It returns the resolved URL for a
158
+ module specifier relative to a parentURL, in addition to the unique module
159
+ format for that resolved URL given by the **ESM_FORMAT** routine.
160
+
161
+ In the following algorithms, all subroutine errors are propogated as errors
162
+ of these top-level routines.
162
163
163
- ** ESM_RESOLVE** (_specifier_, _parentURL_)
164
- > 1. Let _resolvedURL_ be _undefined_ .
165
- > 1. If _specifier_ is a valid URL then,
164
+ #### ESM_RESOLVE(_specifier_, _parentURL_)
165
+ > 1. Let _resolvedURL_ be *undefined* .
166
+ > 1. If _specifier_ is a valid URL, then
166
167
> 1. Set _resolvedURL_ to the result of parsing and reserializing
167
168
> _specifier_ as a URL.
168
- > 1. Otherwise, if _specifier_ starts with _"/"_, _"./"_ or _"../"_ then,
169
+ > 1. Otherwise, if _specifier_ starts with _"/"_, then
170
+ > 1. Throw an _Invalid Specifier_ error.
171
+ > 1. Otherwise, if _specifier_ starts with _"./"_ or _"../"_, then
169
172
> 1. Set _resolvedURL_ to the URL resolution of _specifier_ relative to
170
173
> _parentURL_.
171
174
> 1. Otherwise,
172
175
> 1. Note: _specifier_ is now a bare specifier.
173
176
> 1. Set _resolvedURL_ the result of
174
177
> **PACKAGE_RESOLVE**(_specifier_, _parentURL_).
175
- > 1. If the file at _resolvedURL_ does not exist then,
178
+ > 1. If the file at _resolvedURL_ does not exist, then
176
179
> 1. Throw a _Module Not Found_ error.
177
- > 1. Return _resolvedURL_.
178
-
179
- **PACKAGE_RESOLVE**(_packageSpecifier_, _parentURL_)
180
- > 1. Assert: _packageSpecifier_ is a bare specifier.
181
- > 1. If _packageSpecifier_ is a Node.js builtin module then,
180
+ > 1. Let _format_ be the result of **ESM_FORMAT**(_url_).
181
+ > 1. Return _{ resolvedURL, format }_.
182
+
183
+ PACKAGE_RESOLVE(_packageSpecifier_, _parentURL_)
184
+ > 1. Let _packageName_ be *undefined*.
185
+ > 1. Let _packagePath_ be *undefined*.
186
+ > 1. If _packageSpecifier_ does not start with _"@"_, then
187
+ > 1. If _packageSpecifier_ is an empty string, then
188
+ > 1. Throw an _Invalid Package Name_ error.
189
+ > 1. Set _packageName_ to the substring of _packageSpecifier_ until the
190
+ > first _"/"_ separator or the end of the string.
191
+ > 1. If _packageSpecifier_ starts with _"@"_, then
192
+ > 1. If _packageSpecifier_ does not contain a _"/"_ separator, then
193
+ > 1. Throw an _Invalid Package Name_ error.
194
+ > 1. Set _packageName_ to the substring of _packageSpecifier_
195
+ > until the second _"/"_ separator or the end of the string.
196
+ > 1. Let _packagePath_ be the substring of _packageSpecifier_ from the
197
+ > position at the length of _packageName_ plus one, if any.
198
+ > 1. Assert: _packageName_ is a valid package name or scoped package name.
199
+ > 1. Assert: _packagePath_ is either empty, or a path without a leading
200
+ > separator.
201
+ > 1. Note: Further package name validations can be added here.
202
+ > 1. If _packagePath_ is empty and _packageName_ is a Node.js builtin
203
+ > module, then
182
204
> 1. Return the string _"node:"_ concatenated with _packageSpecifier_.
183
- > 1. While _parentURL_ contains a non-empty _pathname_ ,
205
+ > 1. While _parentURL_ is not the file system root ,
184
206
> 1. Set _parentURL_ to the parent folder URL of _parentURL_.
185
207
> 1. Let _packageURL_ be the URL resolution of the string concatenation of
186
- > _parentURL_, _"/node_modules/"_ and _"packageSpecifier"_.
187
- > 1. If the file at _packageURL_ exists then,
188
- > 1. Return _packageURL_.
208
+ > _parentURL_, _"/node_modules/"_ and _packageSpecifier_.
209
+ > 1. If the folder at _packageURL_ does not exist, then
210
+ > 1. Note: This check can be optimized out where possible in
211
+ > implementation.
212
+ > 1. Set _parentURL_ to the parent URL path of _parentURL_.
213
+ > 1. Continue the next loop iteration.
214
+ > 1. If _packagePath_ is empty, then
215
+ > 1. Let _url_ be the result of **PACKAGE_MAIN_RESOLVE**(_packageURL_).
216
+ > 1. If _url_ is *null*, then
217
+ > 1. Throw a _Module Not Found_ error.
218
+ > 1. Return _url_.
219
+ > 1. Otherwise,
220
+ > 1. Return the URL resolution of _packagePath_ in _packageURL_.
189
221
> 1. Throw a _Module Not Found_ error.
190
222
223
+ PACKAGE_MAIN_RESOLVE(_packageURL_)
224
+ > 1. Let _pjsonURL_ be the URL of the file _"package.json"_ within the parent
225
+ path _packageURL_.
226
+ > 1. If the file at _pjsonURL_ exists, then
227
+ > 1. Let _pjson_ be the result of **READ_JSON_FILE**(_pjsonURL_).
228
+ > 1. If **HAS_ESM_PROPERTIES**(_pjson_) is *true*, then
229
+ > 1. Let _mainURL_ be the result applying the legacy
230
+ > **LOAD_AS_DIRECTORY** CommonJS resolver to _packageURL_, returning
231
+ > *undefined* for no resolution.
232
+ > 1. If _mainURL_ is not *undefined* and **ESM_FORMAT**(_mainURL_) is not
233
+ > equal to _"cjs"_, then
234
+ > 1. Throw a _"Invalid Module Format"_ error.
235
+ > 1. Return _mainURL_.
236
+ > 1. _Note: ESM main yet to be implemented here._
237
+ > 1. Return *null*.
238
+
239
+ #### ESM_FORMAT(_url_)
240
+ > 1. Assert: _url_ corresponds to an existing file.
241
+ > 1. Let _pjsonURL_ be the result of **READ_PACKAGE_BOUNDARY**(_url_).
242
+ > 1. Let _pjson_ be *undefined*.
243
+ > 1. If _pjsonURL_ is not *null*, then
244
+ > 1. Set _pjson_ to the result of **READ_JSON_FILE**(_pjsonURL_).
245
+ > 1. If _pjsonURL_ is *null* or **HAS_ESM_PROPERTIES**(_pjson_) is *true*, then
246
+ > 1. If _url_ does not end in _".js"_ or _".mjs"_ then,
247
+ > 1. Throw an _Unkonwn Module Format_ error.
248
+ > 1. Return _"esm"_.
249
+ > 1. Otherwise,
250
+ > 1. If _url_ does not end in _".js"_ then,
251
+ > 1. Throw an _Unknown Module Format_ error.
252
+ > 1. Return _"cjs"_.
253
+
254
+ > 1. If **HAS_ESM_PROPERTIES**(_pjson_) is *true*, then
255
+ > 1. Return _"esm"_.
256
+ > 1. Return _"cjs"_.
257
+
258
+ READ_PACKAGE_BOUNDARY(_url_)
259
+ > 1. Let _boundaryURL_ be the URL resolution of _"package.json"_ relative to
260
+ > _url_.
261
+ > 1. While _boundaryURL_ is not the file system root,
262
+ > 1. If the file at _boundaryURL_ exists, then
263
+ > 1. Return _boundaryURL_.
264
+ > 1. Set _boundaryURL_ to the URL resolution of _"../package.json"_ relative
265
+ > to _boundaryURL_.
266
+ > 1. Return *null*.
267
+
268
+ READ_JSON_FILE(_url_)
269
+ > 1. If the file at _url_ does not parse as valid JSON, then
270
+ > 1. Throw an _Invalid Package Configuration_ error.
271
+ > 1. Let _pjson_ be the parsed JSON source of the file at _url_.
272
+ > 1. Return _pjson_.
273
+
274
+ HAS_ESM_PROPERTIES(_pjson_)
275
+ > 1. Note: To be specified.
276
+
277
+ _ESM properties_ in a package.json file are yet to be specified.
278
+ The current possible specifications for this are the
279
+ [_"exports"_](https://github.com/jkrems/proposal-pkg-exports)
280
+ or [_"mode"_](https://github.com/nodejs/node/pull/18392) flag.
281
+
191
282
[Node.js EP for ES Modules]: https://github.com/nodejs/node-eps/blob/master/002-es-modules.md
192
283
[` module .createRequireFromPath ()` ]: modules.html#modules_module_createrequirefrompath_filename
193
284
[ESM Minimal Kernel]: https://github.com/nodejs/modules/blob/master/doc/plan-for-new-modules-implementation.md
0 commit comments