@@ -17,15 +17,17 @@ specifier resolution, and default behavior.
17
17
18
18
<!-- type=misc -->
19
19
20
- The ` --experimental-modules ` flag can be used to enable features for loading
21
- ECMAScript modules.
20
+ The ` --experimental-modules ` flag can be used to enable support for
21
+ ECMAScript modules (ES modules) .
22
22
23
- Once this has been set, there are a few different ways to run a file as an ES
24
- module:
23
+ ## Running Node.js with an ECMAScript Module
25
24
26
- ### < code >.mjs</ code > extension
25
+ There are a few ways to start Node.js with an ES module as its input.
27
26
28
- Files ending with ` .mjs ` will be loaded as ES modules.
27
+ ### Initial entry point with an <code >.mjs</code > extension
28
+
29
+ A file ending with ` .mjs ` passed to Node.js as an initial entry point will be
30
+ loaded as an ES module.
29
31
30
32
``` sh
31
33
node --experimental-modules my-app.mjs
@@ -55,7 +57,7 @@ to Node.js via `STDIN`.
55
57
node --experimental-modules --type=module --eval \
56
58
" import { sep } from 'path'; console.log(sep);"
57
59
58
- coffee --print file-containing- import-statements.coffee | \
60
+ echo " import { sep } from 'path'; console.log(sep); " | \
59
61
node --experimental-modules --type=module
60
62
```
61
63
@@ -111,11 +113,11 @@ import './startup/init.js';
111
113
// Loaded as ES module since ./startup contains no package.json file,
112
114
// and therefore inherits the ES module package scope from one level up
113
115
114
- import ' ./node_modules/ commonjs-package/index.js ' ;
116
+ import ' commonjs-package' ;
115
117
// Loaded as CommonJS since ./node_modules/commonjs-package/package.json
116
118
// lacks a "type" field or contains "type": "commonjs"
117
119
118
- import ' commonjs-package' ;
120
+ import ' ./node_modules/ commonjs-package/index.js ' ;
119
121
// Loaded as CommonJS since ./node_modules/commonjs-package/package.json
120
122
// lacks a "type" field or contains "type": "commonjs"
121
123
```
@@ -172,23 +174,52 @@ An attempt to `require` the above `es-module-package` would attempt to load
172
174
an error as Node.js would not be able to parse the ` export ` statement in
173
175
CommonJS.
174
176
175
- Even if the ` package.json ` ` "main" ` points to a file ending in ` .mjs ` , the
176
- ` "type": "module" ` is required.
177
-
178
177
As with ` import ` statements, for ES module usage the value of ` "main" ` must be
179
178
a full path including extension: ` "./index.mjs" ` , not ` "./index" ` .
180
179
181
- > Currently a package can define _ either_ a CommonJS entry point or an ES module
182
- > entry point; there is no way to specify separate entry points for CommonJS and
183
- > ES module usage. This means that a package entry point can be included via
184
- > ` require ` or via ` import ` but not both.
180
+ > Currently a package can define _ either_ a CommonJS entry point ** or ** an ES
181
+ > module entry point; there is no way to specify separate entry points for
182
+ > CommonJS and ES module usage. This means that a package entry point can be
183
+ > included via ` require ` or via ` import ` but not both.
185
184
>
186
185
> Such a limitation makes it difficult for packages to support both new versions
187
186
> of Node.js that understand ES modules and older versions of Node.js that
188
187
> understand only CommonJS. There is work ongoing to remove this limitation, and
189
188
> it will very likely entail changes to the behavior of ` "main" ` as defined
190
189
> here.
191
190
191
+ ## <code >import</code > Specifiers
192
+
193
+ ### Terminology
194
+
195
+ The _ specifier_ of an ` import ` statement is the string after the ` from ` keyword,
196
+ e.g. ` 'path' ` in ` import { sep } from 'path' ` . Specifiers are also used in
197
+ ` export from ` statements, and as the argument to an ` import() ` expression.
198
+
199
+ There are four types of specifiers:
200
+
201
+ - _ Bare specifiers_ like ` 'some-package' ` . They refer to an entry point of a
202
+ package by the package name.
203
+
204
+ - _ Deep import specifiers_ like ` 'some-package/lib/shuffle.mjs' ` . They refer to
205
+ a path within a package prefixed by the package name.
206
+
207
+ - _ Relative specifiers_ like ` './startup.js' ` or ` '../config.mjs' ` . They refer
208
+ to a path relative to the location of the importing file.
209
+
210
+ - _ Absolute specifiers_ like ` 'file:///opt/nodejs/config.js' ` . They refer
211
+ directly and explicitly to a full path.
212
+
213
+ Bare specifiers, and the bare specifier portion of deep import specifiers, are
214
+ strings; but everything else in a specifier is a URL.
215
+
216
+ Only ` file:// ` URLs are supported. A specifier like
217
+ ` 'https://example.com/app.js' ` may be supported by browsers but it is not
218
+ supported in Node.js.
219
+
220
+ Specifiers may not begin with ` / ` or ` // ` . These are reserved for potential
221
+ future use. The root of the current volume may be referenced via ` file:/// ` .
222
+
192
223
## import.meta
193
224
194
225
* {Object}
@@ -282,9 +313,9 @@ import { sin, cos } from 'geometry/trigonometry-functions.mjs';
282
313
>
283
314
> <!-- eslint-disable no-duplicate-imports -->
284
315
> ``` js
285
- > import _ from ' underscore ' ; // Works
316
+ > import packageMain from ' commonjs-package ' ; // Works
286
317
>
287
- > import { shuffle } from ' underscore ' ; // Errors
318
+ > import { method } from ' commonjs-package ' ; // Errors
288
319
> ` ` `
289
320
>
290
321
> There are ongoing efforts to make the latter code possible.
@@ -385,6 +416,9 @@ entirely for the CommonJS loader.
385
416
If the top-level ` -- type` is _"module"_, then the ESM resolver is used
386
417
as described here, with the conditional ` -- type` check in **ESM_FORMAT**.
387
418
419
+ <details>
420
+ <summary>Resolver algorithm psuedocode</summary>
421
+
388
422
**ESM_RESOLVE(_specifier_, _parentURL_, _isMain_)**
389
423
> 1. Let _resolvedURL_ be **undefined**.
390
424
> 1. If _specifier_ is a valid URL, then
@@ -500,6 +534,8 @@ READ_PACKAGE_JSON(_packageURL_)
500
534
> 1. Throw an _Invalid Package Configuration_ error.
501
535
> 1. Return the parsed JSON source of the file at _pjsonURL_.
502
536
537
+ </details>
538
+
503
539
[Node.js EP for ES Modules]: https://github.com/nodejs/node-eps/blob/master/002-es-modules.md
504
540
[` module .createRequireFromPath ()` ]: modules.html#modules_module_createrequirefrompath_filename
505
541
[` import .meta.url` ]: esm.html#importmeta
0 commit comments