Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

new ESM implementation #26745

merged 1 commit into from Mar 27, 2019
Changes from all commits
File filter...
Filter file types
Jump to…
Jump to file or symbol
Failed to load files and symbols.
+1,822 −482
Diff settings


Just for now

esm: phase two of new esm implementation

This PR updates the current `--experimental-modules` implementation
based on the work of the modules team  and reflects Phase 2 of our
new modules plan.

The largest differences from the current implementation include

* `packge.type` which can be either `module` or `commonjs`
  - `type: "commonjs"`:
    - `.js` is parsed as commonjs
    - default for entry point without an extension is commonjs
  - `type: "module"`:
    - `.js` is parsed as esm
    - does not support loading JSON or Native Module by default
    - default for entry point without an extension is esm
* `--entry-type=[mode]`
  - allows you set the type on entry point.
* A new file extension `.cjs`.
  - this is specifically to support importing commonjs in the
    `module` mode.
  - this is only in the esm loader, the commonjs loader remains
    untouched, but the extension will work in the old loader if you use
    the full file path.
* `--es-module-specifier-resolution=[type]`
  - options are `explicit` (default) and `node`
  - by default our loader will not allow for optional extensions in
    the import, the path for a module must include the extension if
    there is one
  - by default our loader will not allow for importing directories that
    have an index file
  - developers can use `--es-module-specifier-resolution=node` to
    enable the commonjs specifier resolution algorithm
  - This is not a “feature” but rather an implementation for
    experimentation. It is expected to change before the flag is
* `--experimental-json-loader`
  - the only way to import json when `"type": "module"`
  - when enable all `import 'thing.json'` will go through the
    experimental loader independent of mode
  - based on whatwg/html#4315
* You can use `package.main` to set an entry point for a module
  - the file extensions used in main will be resolved based on the
    `type` of the module

Refs: nodejs/modules#180
Refs: nodejs/ecmascript-modules#6
Refs: nodejs/ecmascript-modules#12
Refs: nodejs/ecmascript-modules#28
Refs: nodejs/modules#255
Refs: whatwg/html#4315
Refs: w3c/webcomponents#770
Co-authored-by: Myles Borins <>
Co-authored-by: John-David Dalton <>
Co-authored-by: Evan Plaice <>
Co-authored-by: Geoffrey Booth <>
Co-authored-by: Michaël Zasso <>

PR-URL: #26745
Reviewed-By: Gus Caplan <>
Reviewed-By: Guy Bedford <>
Reviewed-By: Ben Coe <>
Reviewed-By: James M Snell <>
Reviewed-By: Joyee Cheung <>
Reviewed-By: Ruben Bridgewater <>
Reviewed-By: Сковорода Никита Андреевич <>
  • Loading branch information...
guybedford authored and MylesBorins committed Aug 28, 2018
commit b1094dbe19f31f7a69ad16d193748f610b159073
@@ -38,6 +38,8 @@ module.exports = {
files: [
@@ -131,9 +131,43 @@ conjunction with native stack and other runtime environment data.
added: v6.0.0

### `--entry-type=type`
<!-- YAML

Used with `--experimental-modules`, this configures Node.js to interpret the
initial entry point as CommonJS or as an ES module.

Valid values are `"commonjs"` and `"module"`. The default is to infer from
the file extension and the `"type"` field in the nearest parent `package.json`.

Works for executing a file as well as `--eval`, `--print`, `STDIN`.

Enable FIPS-compliant crypto at startup. (Requires Node.js to be built with
`./configure --openssl-fips`.)

### `--es-module-specifier-resolution=mode`
<!-- YAML

To be used in conjunction with `--experimental-modules`. Sets the resolution
algorithm for resolving specifiers. Valid options are `explicit` and `node`.

The default is `explicit`, which requires providing the full path to a
module. The `node` mode will enable support for optional file extensions and
the ability to import a directory that has an index file.

Please see [customizing esm specifier resolution][] for example usage.

### `--experimental-json-modules`
<!-- YAML

Enable experimental JSON support for the ES Module loader.

### `--experimental-modules`
<!-- YAML
added: v8.5.0
@@ -927,9 +961,10 @@ greater than `4` (its current default value). For more information, see the
[REPL]: repl.html
[V8 JavaScript code coverage]:
[customizing esm specifier resolution]: esm.html#esm_customizing_esm_specifier_resolution_algorithm
[debugger]: debugger.html
[debugging security implications]:
[emit_warning]: process.html#process_process_emitwarning_warning_type_code_ctor
[experimental ECMAScript Module]: esm.html#esm_loader_hooks
[experimental ECMAScript Module]: esm.html#esm_resolve_hook
[libuv threadpool documentation]:
[remote code execution]:
@@ -844,6 +844,18 @@ provided.
Encoding provided to `TextDecoder()` API was not one of the
[WHATWG Supported Encodings][].


> Stability: 1 - Experimental
The `--entry-type=commonjs` flag was used to attempt to execute an `.mjs` file
or a `.js` file where the nearest parent `package.json` contains
`"type": "module"`; or
the `--entry-type=module` flag was used to attempt to execute a `.cjs` file or
a `.js` file where the nearest parent `package.json` either lacks a `"type"`
field or contains `"type": "commonjs"`.


@@ -1267,6 +1279,11 @@ An invalid or unexpected value was passed in an options object.

An invalid or unknown file encoding was passed.


An invalid `package.json` file was found which failed parsing.


@@ -1440,7 +1457,7 @@ strict compliance with the API specification (which in some cases may accept

> Stability: 1 - Experimental
An [ES6 module][] loader hook specified `format: 'dynamic'` but did not provide
An [ES Module][] loader hook specified `format: 'dynamic'` but did not provide
a `dynamicInstantiate` hook.

@@ -1449,26 +1466,19 @@ a `dynamicInstantiate` hook.
A `MessagePort` was found in the object passed to a `postMessage()` call,
but not provided in the `transferList` for that call.


> Stability: 1 - Experimental
An [ES6 module][] could not be resolved.


The V8 platform used by this instance of Node.js does not support creating
Workers. This is caused by lack of embedder support for Workers. In particular,
this error will not occur with standard builds of Node.js.


> Stability: 1 - Experimental
A failure occurred resolving imports in an [ES6 module][].
An [ES Module][] could not be resolved.

@@ -1555,7 +1565,7 @@ A given value is out of the accepted range.

> Stability: 1 - Experimental
An attempt was made to `require()` an [ES6 module][].
An attempt was made to `require()` an [ES Module][].

@@ -2220,10 +2230,17 @@ A non-specific HTTP/2 error has occurred.
Used in the `repl` in case the old history file is used and an error occurred
while trying to read and parse it.


> Stability: 1 - Experimental
The `--entry-type=...` flag is not compatible with the Node.js REPL.


Used when an [ES6 module][] loader hook specifies `format: 'dynamic'` but does
Used when an [ES Module][] loader hook specifies `format: 'dynamic'` but does
not provide a `dynamicInstantiate` hook.

@@ -2250,7 +2267,6 @@ size.
This `Error` is thrown when a read is attempted on a TTY `WriteStream`,
such as `process.stdout.on('data')`.

[`'uncaughtException'`]: process.html#process_event_uncaughtexception
[`--force-fips`]: cli.html#cli_force_fips
[`Class: assert.AssertionError`]: assert.html#assert_class_assert_assertionerror
@@ -2293,7 +2309,7 @@ such as `process.stdout.on('data')`.
[`subprocess.kill()`]: child_process.html#child_process_subprocess_kill_signal
[`subprocess.send()`]: child_process.html#child_process_subprocess_send_message_sendhandle_options_callback
[`zlib`]: zlib.html
[ES6 module]: esm.html
[ES Module]: esm.html
[ICU]: intl.html#intl_internationalization_support
[Node.js Error Codes]: #nodejs-error-codes
[V8's stack trace API]:
Oops, something went wrong.
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.