Skip to content
Permalink
Browse files

esm: unflag --experimental-modules

PR-URL: #29866
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Myles Borins <myles.borins@gmail.com>
  • Loading branch information
guybedford authored and MylesBorins committed Oct 11, 2019
1 parent cc6f99d commit 796f3d0af49164314868c4778af90eca356f1fef
Showing with 194 additions and 331 deletions.
  1. +8 −8 doc/api/cli.md
  2. +15 −21 doc/api/esm.md
  3. +8 −8 doc/api/vm.md
  4. +2 −3 doc/node.1
  5. +8 −10 lib/internal/bootstrap/loaders.js
  6. +9 −21 lib/internal/bootstrap/pre_execution.js
  7. +12 −15 lib/internal/main/check_syntax.js
  8. +2 −3 lib/internal/main/run_main_module.js
  9. +3 −8 lib/internal/modules/cjs/helpers.js
  10. +39 −49 lib/internal/modules/cjs/loader.js
  11. +3 −0 lib/internal/process/esm_loader.js
  12. +3 −7 lib/repl.js
  13. +3 −28 src/node_options.cc
  14. +0 −1 src/node_options.h
  15. +0 −1 test/common/index.mjs
  16. +5 −3 test/es-module/test-cjs-esm-warn.js
  17. +0 −1 test/es-module/test-esm-basic-imports.mjs
  18. +7 −35 test/es-module/test-esm-cjs-load-error-note.mjs
  19. +1 −7 test/es-module/test-esm-cjs-main.js
  20. +0 −1 test/es-module/test-esm-cyclic-dynamic-import.mjs
  21. +0 −1 test/es-module/test-esm-data-urls.js
  22. +0 −1 test/es-module/test-esm-default-type.mjs
  23. +0 −1 test/es-module/test-esm-double-encoding.mjs
  24. +0 −2 test/es-module/test-esm-dynamic-import.js
  25. +1 −1 test/es-module/test-esm-encoded-path-native.js
  26. +0 −1 test/es-module/test-esm-encoded-path.mjs
  27. +0 −2 test/es-module/test-esm-error-cache.js
  28. +1 −1 test/es-module/test-esm-example-loader.js
  29. +1 −2 test/es-module/test-esm-exports.mjs
  30. +0 −1 test/es-module/test-esm-forbidden-globals.mjs
  31. +0 −1 test/es-module/test-esm-import-meta.mjs
  32. +1 −1 test/es-module/test-esm-invalid-extension.js
  33. +1 −1 test/es-module/test-esm-json-cache.mjs
  34. +1 −1 test/es-module/test-esm-json.mjs
  35. +0 −1 test/es-module/test-esm-live-binding.mjs
  36. +0 −1 test/es-module/test-esm-loader-cache-clearing.js
  37. +1 −1 test/es-module/test-esm-loader-dependency.mjs
  38. +1 −1 test/es-module/test-esm-loader-invalid-format.mjs
  39. +1 −1 test/es-module/test-esm-loader-invalid-url.mjs
  40. +1 −1 test/es-module/test-esm-loader-missing-dynamic-instantiate-hook.mjs
  41. +1 −1 test/es-module/test-esm-loader-modulemap.js
  42. +0 −1 test/es-module/test-esm-main-lookup.mjs
  43. +1 −1 test/es-module/test-esm-named-exports.mjs
  44. +0 −1 test/es-module/test-esm-namespace.mjs
  45. +1 −4 test/es-module/test-esm-no-extension.js
  46. +0 −2 test/es-module/test-esm-pkgname.mjs
  47. +1 −1 test/es-module/test-esm-preserve-symlinks-main.js
  48. +1 −1 test/es-module/test-esm-preserve-symlinks-not-found-plain.mjs
  49. +1 −1 test/es-module/test-esm-preserve-symlinks-not-found.mjs
  50. +1 −1 test/es-module/test-esm-preserve-symlinks.js
  51. +0 −1 test/es-module/test-esm-process.mjs
  52. +0 −1 test/es-module/test-esm-repl.js
  53. +0 −1 test/es-module/test-esm-require-cache.mjs
  54. +1 −1 test/es-module/test-esm-resolve-hook.mjs
  55. +0 −1 test/es-module/test-esm-scope-node-modules.mjs
  56. +1 −1 test/es-module/test-esm-shared-loader-dep.mjs
  57. +0 −1 test/es-module/test-esm-shebang.mjs
  58. +0 −1 test/es-module/test-esm-snapshot.mjs
  59. +1 −1 test/es-module/test-esm-specifiers.mjs
  60. +1 −1 test/es-module/test-esm-symlink-main.js
  61. +2 −2 test/es-module/test-esm-symlink-type.js
  62. +1 −1 test/es-module/test-esm-symlink.js
  63. +0 −1 test/es-module/test-esm-throw-undefined.mjs
  64. +0 −3 test/es-module/test-esm-type-flag-errors.js
  65. +0 −1 test/es-module/test-esm-type-flag.mjs
  66. +1 −1 test/es-module/test-esm-wasm.mjs
  67. +0 −1 test/es-module/test-esm-windows.js
  68. +0 −1 test/message/async_error_eval_esm.js
  69. +0 −1 test/message/async_error_eval_esm.out
  70. +0 −1 test/message/async_error_sync_esm.mjs
  71. +1 −1 test/message/async_error_sync_esm.out
  72. +0 −1 test/message/esm_display_syntax_error.mjs
  73. +1 −1 test/message/esm_display_syntax_error.out
  74. +0 −1 test/message/esm_display_syntax_error_import.mjs
  75. +1 −1 test/message/esm_display_syntax_error_import.out
  76. +0 −1 test/message/esm_display_syntax_error_import_module.mjs
  77. +0 −1 test/message/esm_display_syntax_error_module.mjs
  78. +1 −1 test/message/esm_loader_not_found.mjs
  79. +1 −1 test/message/esm_loader_syntax_error.mjs
  80. +8 −0 test/parallel/test-bootstrap-modules.js
  81. +1 −1 test/parallel/test-cli-eval.js
  82. +1 −1 test/parallel/test-cli-syntax-piped-bad.js
  83. +1 −1 test/parallel/test-cli-syntax-piped-good.js
  84. +7 −1 test/parallel/test-dns-lookupService.js
  85. +2 −2 test/parallel/test-inspector-esm.js
  86. +1 −1 test/parallel/test-loaders-unknown-builtin-module.mjs
  87. +2 −4 test/parallel/test-module-main-extension-lookup.js
  88. +8 −11 test/parallel/test-module-main-fail.js
  89. +1 −1 test/parallel/test-module-main-preserve-symlinks-fail.js
  90. +0 −2 test/parallel/test-source-map.js
  91. +1 −1 test/parallel/test-vm-module-dynamic-import.js
  92. +1 −2 test/parallel/test-worker-esm-exit.js
  93. +1 −1 test/parallel/test-worker-esm-missing-main.js
  94. +0 −1 test/parallel/test-worker-esmodule.js
  95. +1 −2 test/parallel/test-worker-mjs-workerdata.js
@@ -161,8 +161,8 @@ Currently, overriding `Error.prepareStackTrace` is ignored when the
added: v12.0.0
-->

To be used in conjunction with `--experimental-modules`. Sets the resolution
algorithm for resolving specifiers. Valid options are `explicit` and `node`.
Sets the resolution algorithm for resolving ES module 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
@@ -191,7 +191,8 @@ Enable experimental JSON support for the ES Module loader.
added: v8.5.0
-->

Enable experimental ES module support and caching modules.
Enable latest experimental modules features (currently
`--experimental-conditional-exports` and `--experimental-self-resolve`).

### `--experimental-policy`
<!-- YAML
@@ -342,9 +343,8 @@ Specify ICU data load path. (Overrides `NODE_ICU_DATA`.)
added: v12.0.0
-->

Used with `--experimental-modules`, this configures Node.js to interpret string
input as CommonJS or as an ES module. String input is input via `--eval`,
`--print`, or `STDIN`.
This configures Node.js to interpret string input as CommonJS or as an ES
module. String input is input via `--eval`, `--print`, or `STDIN`.

Valid values are `"commonjs"` and `"module"`. The default is `"commonjs"`.

@@ -409,7 +409,7 @@ endpoint on `http://host:port/json/list`.
added: v9.0.0
-->

Specify the `module` of a custom [experimental ECMAScript Module][] loader.
Specify the `module` of a custom [experimental ECMAScript Module loader][].
`module` may be either a path to a file, or an ECMAScript Module name.

### `--max-http-header-size=size`
@@ -1330,7 +1330,7 @@ greater than `4` (its current default value). For more information, see the
[debugger]: debugger.html
[debugging security implications]: https://nodejs.org/en/docs/guides/debugging-getting-started/#security-implications
[emit_warning]: process.html#process_process_emitwarning_warning_type_code_ctor
[experimental ECMAScript Module]: esm.html#esm_resolve_hook
[experimental ECMAScript Module loader]: esm.html#esm_resolve_hook
[libuv threadpool documentation]: http://docs.libuv.org/en/latest/threadpool.html
[remote code execution]: https://www.owasp.org/index.php/Code_Injection
[context-aware]: addons.html#addons_context_aware_addons
@@ -27,12 +27,9 @@ specifier resolution, and default behavior.

<!-- type=misc -->

The `--experimental-modules` flag can be used to enable support for
ECMAScript modules (ES modules).

Once enabled, Node.js will treat the following as ES modules when passed to
`node` as the initial input, or when referenced by `import` statements within
ES module code:
Experimental support for ECMAScript modules is enabled by default.
Node.js will treat the following as ES modules when passed to `node` as the
initial input, or when referenced by `import` statements within ES module code:

* Files ending in `.mjs`.

@@ -80,7 +77,7 @@ until the root of the volume is reached.

```sh
# In same folder as above package.json
node --experimental-modules my-app.js # Runs as ES module
node my-app.js # Runs as ES module
```

If the nearest parent `package.json` lacks a `"type"` field, or contains
@@ -114,9 +111,8 @@ own `package.json` file, so each project’s dependencies have their own package
scopes. A `package.json` lacking a `"type"` field is treated as if it contained
`"type": "commonjs"`.

The package scope applies not only to initial entry points (`node
--experimental-modules my-app.js`) but also to files referenced by `import`
statements and `import()` expressions.
The package scope applies not only to initial entry points (`node my-app.js`)
but also to files referenced by `import` statements and `import()` expressions.

```js
// my-app.js, in an ES module package scope because there is a package.json
@@ -169,11 +165,9 @@ piped to `node` via `STDIN`, will be treated as ES modules when the
`--input-type=module` flag is set.

```sh
node --experimental-modules --input-type=module --eval \
"import { sep } from 'path'; console.log(sep);"
node --input-type=module --eval "import { sep } from 'path'; console.log(sep);"
echo "import { sep } from 'path'; console.log(sep);" | \
node --experimental-modules --input-type=module
echo "import { sep } from 'path'; console.log(sep);" | node --input-type=module
```

For completeness there is also `--input-type=commonjs`, for explicitly running
@@ -927,8 +921,8 @@ The `--experimental-json-modules` flag is needed for the module
to work.
```bash
node --experimental-modules index.mjs # fails
node --experimental-modules --experimental-json-modules index.mjs # works
node index.mjs # fails
node --experimental-json-modules index.mjs # works
```
## Experimental Wasm Modules
@@ -950,7 +944,7 @@ console.log(M);
executed under:
```bash
node --experimental-modules --experimental-wasm-modules index.mjs
node --experimental-wasm-modules index.mjs
```
would provide the exports interface for the instantiation of `module.wasm`.
@@ -1061,7 +1055,7 @@ export async function resolve(specifier,
With this loader, running:
```console
NODE_OPTIONS='--experimental-modules --experimental-loader ./custom-loader.mjs' node x.js
NODE_OPTIONS='--experimental-loader ./custom-loader.mjs' node x.js
```
would load the module `x.js` as an ES module with relative resolution support
@@ -1352,11 +1346,11 @@ automatic extension resolution and importing from directories that include an
index file use the `node` mode.
```bash
$ node --experimental-modules index.mjs
$ node index.mjs
success!
$ node --experimental-modules index #Failure!
$ node index # Failure!
Error: Cannot find module
$ node --experimental-modules --es-module-specifier-resolution=node index
$ node --es-module-specifier-resolution=node index
success!
```
@@ -88,8 +88,8 @@ changes:
* `importModuleDynamically` {Function} Called during evaluation of this module
when `import()` is called. If this option is not specified, calls to
`import()` will reject with [`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING`][].
This option is part of the experimental API for the `--experimental-modules`
flag, and should not be considered stable.
This option is part of the experimental modules API, and should not be
considered stable.
* `specifier` {string} specifier passed to `import()`
* `module` {vm.Module}
* Returns: {Module Namespace Object|vm.Module} Returning a `vm.Module` is
@@ -854,8 +854,8 @@ changes:
* `importModuleDynamically` {Function} Called during evaluation of this module
when `import()` is called. If this option is not specified, calls to
`import()` will reject with [`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING`][].
This option is part of the experimental API for the `--experimental-modules`
flag, and should not be considered stable.
This option is part of the experimental modules API, and should not be
considered stable.
* `specifier` {string} specifier passed to `import()`
* `module` {vm.Module}
* Returns: {Module Namespace Object|vm.Module} Returning a `vm.Module` is
@@ -951,8 +951,8 @@ changes:
* `importModuleDynamically` {Function} Called during evaluation of this module
when `import()` is called. If this option is not specified, calls to
`import()` will reject with [`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING`][].
This option is part of the experimental API for the `--experimental-modules`
flag, and should not be considered stable.
This option is part of the experimental modules API, and should not be
considered stable.
* `specifier` {string} specifier passed to `import()`
* `module` {vm.Module}
* Returns: {Module Namespace Object|vm.Module} Returning a `vm.Module` is
@@ -1028,8 +1028,8 @@ changes:
* `importModuleDynamically` {Function} Called during evaluation of this module
when `import()` is called. If this option is not specified, calls to
`import()` will reject with [`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING`][].
This option is part of the experimental API for the `--experimental-modules`
flag, and should not be considered stable.
This option is part of the experimental modules API, and should not be
considered stable.
* `specifier` {string} specifier passed to `import()`
* `module` {vm.Module}
* Returns: {Module Namespace Object|vm.Module} Returning a `vm.Module` is
@@ -120,7 +120,7 @@ Enable experimental support for "require" and "node" conditional export targets.
Enable experimental JSON interop support for the ES Module loader.
.
.It Fl -experimental-modules
Enable experimental ES module support and caching modules.
Enable experimental latest experimental modules features.
.
.It Fl -experimental-resolve-self
Enable experimental support for a package to load itself.
@@ -208,8 +208,7 @@ It uses the Chrome DevTools Protocol.
.It Fl -experimental-loader Ns = Ns Ar module
Specify the
.Ar module
as a custom loader, to load
.Fl -experimental-modules .
to use as a custom module loader.
.
.It Fl -max-http-header-size Ns = Ns Ar size
Specify the maximum size of HTTP headers in bytes. Defaults to 8KB.
@@ -211,23 +211,21 @@ function requireWithFallbackInDeps(request) {
}

// This is exposed for public loaders
NativeModule.prototype.compileForPublicLoader = function(needToSyncExports) {
NativeModule.prototype.compileForPublicLoader = function() {
if (!this.canBeRequiredByUsers) {
// No code because this is an assertion against bugs
// eslint-disable-next-line no-restricted-syntax
throw new Error(`Should not compile ${this.id} for public use`);
}
this.compile();
if (needToSyncExports) {
if (!this.exportKeys) {
// When using --expose-internals, we do not want to reflect the named
// exports from core modules as this can trigger unnecessary getters.
const internal = this.id.startsWith('internal/');
this.exportKeys = internal ? [] : Object.keys(this.exports);
}
this.getESMFacade();
this.syncExports();
if (!this.exportKeys) {
// When using --expose-internals, we do not want to reflect the named
// exports from core modules as this can trigger unnecessary getters.
const internal = this.id.startsWith('internal/');
this.exportKeys = internal ? [] : Object.keys(this.exports);
}
this.getESMFacade();
this.syncExports();
return this.exports;
};

@@ -401,24 +401,15 @@ function initializeESMLoader() {
// Create this WeakMap in js-land because V8 has no C++ API for WeakMap.
internalBinding('module_wrap').callbackMap = new SafeWeakMap();

const experimentalModules = getOptionValue('--experimental-modules');
const experimentalVMModules = getOptionValue('--experimental-vm-modules');
if (experimentalModules || experimentalVMModules) {
if (experimentalModules) {
process.emitWarning(
'The ESM module loader is experimental.',
'ExperimentalWarning', undefined);
}
const {
setImportModuleDynamicallyCallback,
setInitializeImportMetaObjectCallback
} = internalBinding('module_wrap');
const esm = require('internal/process/esm_loader');
// Setup per-isolate callbacks that locate data or callbacks that we keep
// track of for different ESM modules.
setInitializeImportMetaObjectCallback(esm.initializeImportMetaObject);
setImportModuleDynamicallyCallback(esm.importModuleDynamicallyCallback);
}
const {
setImportModuleDynamicallyCallback,
setInitializeImportMetaObjectCallback
} = internalBinding('module_wrap');
const esm = require('internal/process/esm_loader');
// Setup per-isolate callbacks that locate data or callbacks that we keep
// track of for different ESM modules.
setInitializeImportMetaObjectCallback(esm.initializeImportMetaObject);
setImportModuleDynamicallyCallback(esm.importModuleDynamicallyCallback);
}

function initializeFrozenIntrinsics() {
@@ -460,9 +451,6 @@ function resolveMainPath(main) {
}

function shouldUseESMLoader(mainPath) {
const experimentalModules = getOptionValue('--experimental-modules');
if (!experimentalModules)
return false;
const userLoader = getOptionValue('--experimental-loader');
if (userLoader)
return true;
@@ -47,21 +47,18 @@ if (process.argv[1] && process.argv[1] !== '-') {

function checkSyntax(source, filename) {
const { getOptionValue } = require('internal/options');
const experimentalModules = getOptionValue('--experimental-modules');
if (experimentalModules) {
let isModule = false;
if (filename === '[stdin]' || filename === '[eval]') {
isModule = getOptionValue('--input-type') === 'module';
} else {
const resolve = require('internal/modules/esm/default_resolve');
const { format } = resolve(pathToFileURL(filename).toString());
isModule = format === 'module';
}
if (isModule) {
const { ModuleWrap } = internalBinding('module_wrap');
new ModuleWrap(filename, undefined, source, 0, 0);
return;
}
let isModule = false;
if (filename === '[stdin]' || filename === '[eval]') {
isModule = getOptionValue('--input-type') === 'module';
} else {
const resolve = require('internal/modules/esm/default_resolve');
const { format } = resolve(pathToFileURL(filename).toString());
isModule = format === 'module';
}
if (isModule) {
const { ModuleWrap } = internalBinding('module_wrap');
new ModuleWrap(filename, undefined, source, 0, 0);
return;
}

wrapSafe(filename, source);
@@ -10,7 +10,6 @@ const CJSModule = require('internal/modules/cjs/loader').Module;

markBootstrapComplete();

// Note: this loads the module through the ESM loader if
// --experimental-loader is provided or --experimental-modules is on
// and the module is determined to be an ES module
// Note: this loads the module through the ESM loader if the module is
// determined to be an ES module
CJSModule.runMain(process.argv[1]);
@@ -6,8 +6,6 @@ const {
ERR_UNKNOWN_BUILTIN_MODULE
} = require('internal/errors').codes;
const { NativeModule } = require('internal/bootstrap/loaders');
const { getOptionValue } = require('internal/options');
const experimentalModules = getOptionValue('--experimental-modules');

const { validateString } = require('internal/validators');
const path = require('path');
@@ -16,11 +14,11 @@ const { URL } = require('url');

const debug = require('internal/util/debuglog').debuglog('module');

function loadNativeModule(filename, request, experimentalModules) {
function loadNativeModule(filename, request) {
const mod = NativeModule.map.get(filename);
if (mod) {
debug('load native module %s', request);
mod.compileForPublicLoader(experimentalModules);
mod.compileForPublicLoader();
return mod;
}
}
@@ -45,10 +43,7 @@ function makeRequireFunction(mod, redirects) {
const href = destination.href;
if (destination.protocol === 'node:') {
const specifier = destination.pathname;
const mod = loadNativeModule(
specifier,
href,
experimentalModules);
const mod = loadNativeModule(specifier, href);
if (mod && mod.canBeRequiredByUsers) {
return mod.exports;
}

0 comments on commit 796f3d0

Please sign in to comment.
You can’t perform that action at this time.