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

Commit b80ef53

Browse files
committed
doc: esm features, differences/interoperability with commonjs
1 parent 7912f34 commit b80ef53

File tree

1 file changed

+77
-26
lines changed

1 file changed

+77
-26
lines changed

doc/api/esm.md

Lines changed: 77 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -120,17 +120,7 @@ You can use the `.mjs` and `.cjs` extensions to mix types within the same packag
120120

121121
- Within a `"type": "commonjs"` package scope, Node.js can be instructed to interpret a particular file as an ES module by naming it with an `.mjs` extension (since both `.js` and `.cjs` files are treated as CommonJS within a `"commonjs"` package scope).
122122

123-
## Features
124-
125-
<!-- type=misc -->
126-
127-
### Supported
128-
129-
Only the CLI argument for the main entry point to the program can be an entry
130-
point into an ESM graph. Dynamic import can also be used to create entry points
131-
into ESM graphs at runtime.
132-
133-
#### import.meta
123+
## import.meta
134124

135125
* {Object}
136126

@@ -139,37 +129,44 @@ property:
139129

140130
* `url` {string} The absolute `file:` URL of the module.
141131

142-
### Unsupported
143-
144-
| Feature | Reason |
145-
| --- | --- |
146-
| `require('./foo.mjs')` | ES Modules have differing resolution and timing, use dynamic import |
147-
148-
## Notable differences between `import` and `require`
132+
## Differences Between ES Modules and CommonJS
149133

150134
### Mandatory file extensions
151135

152-
You must provide a file extension when using the `import` keyword.
136+
You must provide a file extension when using the `import` keyword. Directory
137+
indexes (e.g. `'./startup/index.js'`) must also be fully specified.
153138

154-
### No NODE_PATH
139+
This behavior matches how `import` behaves in browser environments, assuming a
140+
typically configured server.
141+
142+
### No <code>NODE_PATH</code>
155143

156144
`NODE_PATH` is not part of resolving `import` specifiers. Please use symlinks
157145
if this behavior is desired.
158146

159-
### No `require.extensions`
147+
### No <code>require</code>, <code>exports</code>, <code>module.exports</code>, <code>__filename</code>, <code>__dirname</code>
148+
149+
These CommonJS variables are not available in ES modules.
150+
151+
`require` can be imported into an ES module using
152+
[`module.createRequireFromPath()`][].
153+
154+
An equivalent for `__filename` and `__dirname` is [`import.meta.url`][].
155+
156+
### No <code>require.extensions</code>
160157

161158
`require.extensions` is not used by `import`. The expectation is that loader
162159
hooks can provide this workflow in the future.
163160

164-
### No `require.cache`
161+
### No <code>require.cache</code>
165162

166163
`require.cache` is not used by `import`. It has a separate cache.
167164

168-
### URL based paths
165+
### URL-based paths
169166

170-
ESM are resolved and cached based upon [URL](https://url.spec.whatwg.org/)
171-
semantics. This means that files containing special characters such as `#` and
172-
`?` need to be escaped.
167+
ES modules are resolved and cached based upon
168+
[URL](https://url.spec.whatwg.org/) semantics. This means that files containing
169+
special characters such as `#` and `?` need to be escaped.
173170

174171
Modules will be loaded multiple times if the `import` specifier used to resolve
175172
them have a different query or fragment.
@@ -181,6 +178,58 @@ import './foo.mjs?query=2'; // loads ./foo.mjs with query of "?query=2"
181178

182179
For now, only modules using the `file:` protocol can be loaded.
183180

181+
## Interoperability with CommonJS
182+
183+
### <code>require</code>
184+
185+
`require` always treats the files it references as CommonJS. This applies
186+
whether `require` is used the traditional way within a CommonJS environment, or
187+
in an ES module environment using [`module.createRequireFromPath()`][].
188+
189+
To include an ES module into CommonJS, use [`import()`][].
190+
191+
### <code>import</code> statements
192+
193+
An `import` statement can reference either ES module or CommonJS JavaScript.
194+
Other file types such as JSON and Native modules are not supported. For those,
195+
use [`module.createRequireFromPath()`][].
196+
197+
`import` statements are permitted only in ES modules. For similar functionality
198+
in CommonJS, see [`import()`][].
199+
200+
The _specifier_ of an `import` statement (the string after the `from` keyword)
201+
can either be an URL-style relative path like `'./file.mjs'` or a package name
202+
like `'fs'`.
203+
204+
Like in CommonJS, files within packages can be accessed by appending a path to
205+
the package name.
206+
207+
```js
208+
import { sin, cos } from 'geometry/trigonometry-functions.mjs';
209+
```
210+
211+
> Currently only the “default export” is supported for CommonJS files or
212+
> packages:
213+
>
214+
> ```js
215+
> import _ from 'underscore'; // Works
216+
>
217+
> import { shuffle } from 'underscore'; // Errors
218+
> ```
219+
>
220+
> There are ongoing efforts to make the latter code possible.
221+
222+
### <code>import()</code> expressions
223+
224+
Dynamic `import()` is supported in both CommonJS and ES modules. It can be used
225+
to include ES module files from CommonJS code.
226+
227+
```js
228+
(async () => {
229+
await import('./my-app.mjs');
230+
})();
231+
```
232+
184233
## CommonJS, JSON, and Native Modules
185234

186235
CommonJS, JSON, and Native modules can be used with [`module.createRequireFromPath()`][].
@@ -505,4 +554,6 @@ in the import tree.
505554
[Node.js EP for ES Modules]: https://github.com/nodejs/node-eps/blob/master/002-es-modules.md
506555
[dynamic instantiate hook]: #esm_dynamic_instantiate_hook
507556
[`module.createRequireFromPath()`]: modules.html#modules_module_createrequirefrompath_filename
557+
[`import.meta.url`]: esm.html#importmeta
558+
[`import()`]: esm.html#import-expressions
508559
[ecmascript-modules implementation]: https://github.com/nodejs/modules/blob/master/doc/plan-for-new-modules-implementation.md

0 commit comments

Comments
 (0)