Skip to content
This repository was archived by the owner on Apr 16, 2020. It is now read-only.

Commit 8794ce5

Browse files
committed
doc: notes from call
1 parent 7b57407 commit 8794ce5

File tree

1 file changed

+54
-18
lines changed

1 file changed

+54
-18
lines changed

doc/api/esm.md

Lines changed: 54 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,17 @@ specifier resolution, and default behavior.
1717

1818
<!-- type=misc -->
1919

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).
2222

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
2524

26-
### <code>.mjs</code> extension
25+
There are a few ways to start Node.js with an ES module as its input.
2726

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.
2931

3032
```sh
3133
node --experimental-modules my-app.mjs
@@ -55,7 +57,7 @@ to Node.js via `STDIN`.
5557
node --experimental-modules --type=module --eval \
5658
"import { sep } from 'path'; console.log(sep);"
5759

58-
coffee --print file-containing-import-statements.coffee | \
60+
echo "import { sep } from 'path'; console.log(sep);" | \
5961
node --experimental-modules --type=module
6062
```
6163

@@ -111,11 +113,11 @@ import './startup/init.js';
111113
// Loaded as ES module since ./startup contains no package.json file,
112114
// and therefore inherits the ES module package scope from one level up
113115

114-
import './node_modules/commonjs-package/index.js';
116+
import 'commonjs-package';
115117
// Loaded as CommonJS since ./node_modules/commonjs-package/package.json
116118
// lacks a "type" field or contains "type": "commonjs"
117119

118-
import 'commonjs-package';
120+
import './node_modules/commonjs-package/index.js';
119121
// Loaded as CommonJS since ./node_modules/commonjs-package/package.json
120122
// lacks a "type" field or contains "type": "commonjs"
121123
```
@@ -172,23 +174,52 @@ An attempt to `require` the above `es-module-package` would attempt to load
172174
an error as Node.js would not be able to parse the `export` statement in
173175
CommonJS.
174176

175-
Even if the `package.json` `"main"` points to a file ending in `.mjs`, the
176-
`"type": "module"` is required.
177-
178177
As with `import` statements, for ES module usage the value of `"main"` must be
179178
a full path including extension: `"./index.mjs"`, not `"./index"`.
180179

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.
185184
>
186185
> Such a limitation makes it difficult for packages to support both new versions
187186
> of Node.js that understand ES modules and older versions of Node.js that
188187
> understand only CommonJS. There is work ongoing to remove this limitation, and
189188
> it will very likely entail changes to the behavior of `"main"` as defined
190189
> here.
191190
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+
192223
## import.meta
193224

194225
* {Object}
@@ -282,9 +313,9 @@ import { sin, cos } from 'geometry/trigonometry-functions.mjs';
282313
>
283314
> <!-- eslint-disable no-duplicate-imports -->
284315
> ```js
285-
> import _ from 'underscore'; // Works
316+
> import packageMain from 'commonjs-package'; // Works
286317
>
287-
> import { shuffle } from 'underscore'; // Errors
318+
> import { method } from 'commonjs-package'; // Errors
288319
> ```
289320
>
290321
> There are ongoing efforts to make the latter code possible.
@@ -385,6 +416,9 @@ entirely for the CommonJS loader.
385416
If the top-level `--type` is _"module"_, then the ESM resolver is used
386417
as described here, with the conditional `--type` check in **ESM_FORMAT**.
387418
419+
<details>
420+
<summary>Resolver algorithm psuedocode</summary>
421+
388422
**ESM_RESOLVE(_specifier_, _parentURL_, _isMain_)**
389423
> 1. Let _resolvedURL_ be **undefined**.
390424
> 1. If _specifier_ is a valid URL, then
@@ -500,6 +534,8 @@ READ_PACKAGE_JSON(_packageURL_)
500534
> 1. Throw an _Invalid Package Configuration_ error.
501535
> 1. Return the parsed JSON source of the file at _pjsonURL_.
502536
537+
</details>
538+
503539
[Node.js EP for ES Modules]: https://github.com/nodejs/node-eps/blob/master/002-es-modules.md
504540
[`module.createRequireFromPath()`]: modules.html#modules_module_createrequirefrompath_filename
505541
[`import.meta.url`]: esm.html#importmeta

0 commit comments

Comments
 (0)