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

esm: add --experimental-import-non-javascript-without-assertion flag #40210

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions doc/api/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,14 @@ added:

Enable experimental `import.meta.resolve()` support.

### `--experimental-import-non-javascript-without-assertion`
<!-- YAML
added: REPLACEME
-->

Enable experimental support importing non-JS modules without using an import
assertion.

### `--experimental-json-modules`
<!-- YAML
added: v12.9.0
Expand Down
25 changes: 25 additions & 0 deletions doc/api/errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -1109,6 +1109,14 @@ The JS execution context is not associated with a Node.js environment.
This may occur when Node.js is used as an embedded library and some hooks
for the JS engine are not set up properly.

<a id="ERR_FAILED_IMPORT_ASSERTION"></a>
### `ERR_FAILED_IMPORT_ASSERTION`
<!-- YAML
added: REPLACEME
-->

An import assertion has failed, preventing the specified module to be imported.

<a id="ERR_FALSY_VALUE_REJECTION"></a>
### `ERR_FALSY_VALUE_REJECTION`

Expand Down Expand Up @@ -1660,6 +1668,14 @@ for more information.

An invalid HTTP token was supplied.

<a id="ERR_INVALID_IMPORT_ASSERTION"></a>
### `ERR_INVALID_IMPORT_ASSERTION`
<!-- YAML
added: REPLACEME
-->

An import assertion is not supported by this version of Node.js.

<a id="ERR_INVALID_IP_ADDRESS"></a>
### `ERR_INVALID_IP_ADDRESS`

Expand Down Expand Up @@ -1909,6 +1925,15 @@ strict compliance with the API specification (which in some cases may accept
`func(undefined)` and `func()` are treated identically, and the
[`ERR_INVALID_ARG_TYPE`][] error code may be used instead.

<a id="ERR_MISSING_IMPORT_ASSERTION"></a>
### `ERR_MISSING_IMPORT_ASSERTION`
<!-- YAML
added: REPLACEME
-->

An attempt was made to impor without an assertion a module that requires a
specific import assertion to be loaded.
Comment on lines +1934 to +1935
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
An attempt was made to impor without an assertion a module that requires a
specific import assertion to be loaded.
An attempt was made to import a module without an assertion that requires
a specific import assertion to be loaded.


<a id="ERR_MISSING_OPTION"></a>
### `ERR_MISSING_OPTION`

Expand Down
27 changes: 25 additions & 2 deletions doc/api/esm.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
<!-- YAML
added: v8.5.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/39921
description: Add support for import assertions.
- version:
- REPLACEME
pr-url: https://github.com/nodejs/node/pull/37468
Expand Down Expand Up @@ -230,6 +233,25 @@ absolute URL strings.
import fs from 'node:fs/promises';
```

## Import assertions
<!-- YAML
added: REPLACEME
-->

The [Import Assertions proposal][] adds an inline syntax for module import
statements to pass on more information alongside the module specifier.

```js
import json from './foo.json' assert { type: "json" };
await import('foo.json', { assert: { type: "json" } });
```

Node.js supports the following `type` values:

| `type` | Resolves to |
| -------- | ---------------- |
| `"json"` | [JSON modules][] |

## Builtin modules

[Core modules][] provide named exports of their public API. A
Expand Down Expand Up @@ -518,9 +540,8 @@ same path.

Assuming an `index.mjs` with

<!-- eslint-skip -->
```js
import packageConfig from './package.json';
import packageConfig from './package.json' assert { type: 'json' };
```

The `--experimental-json-modules` flag is needed for the module
Expand Down Expand Up @@ -1351,6 +1372,8 @@ success!
[Dynamic `import()`]: https://wiki.developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#Dynamic_Imports
[ECMAScript Top-Level `await` proposal]: https://github.com/tc39/proposal-top-level-await/
[ES Module Integration Proposal for Web Assembly]: https://github.com/webassembly/esm-integration
[Import Assertions proposal]: https://github.com/tc39/proposal-import-assertions
[JSON modules]: #json-modules
[Node.js Module Resolution Algorithm]: #resolver-algorithm-specification
[Terminology]: #terminology
[URL]: https://url.spec.whatwg.org/
Expand Down
39 changes: 39 additions & 0 deletions doc/api/vm.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ executed in specific contexts.
<!-- YAML
added: v0.3.1
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/39921
description: Added suppoort of import assertions to the
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
description: Added suppoort of import assertions to the
description: Added support of import assertions to the

Typo.

`importModuleDynamically` parameter.
- version: v10.6.0
pr-url: https://github.com/nodejs/node/pull/20300
description: The `produceCachedData` is deprecated in favour of
Expand Down Expand Up @@ -91,6 +95,8 @@ changes:
using it in a production environment.
* `specifier` {string} specifier passed to `import()`
* `script` {vm.Script}
* `import_assertions` {Object} The `"assert"` value passed to the
`optionExpression` optional parameter.
* Returns: {Module Namespace Object|vm.Module} Returning a `vm.Module` is
recommended in order to take advantage of error tracking, and to avoid
issues with namespaces that contain `then` function exports.
Expand Down Expand Up @@ -642,6 +648,13 @@ The `vm.SourceTextModule` class provides the [Source Text Module Record][] as
defined in the ECMAScript specification.

### `new vm.SourceTextModule(code[, options])`
<!-- YAML
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/39921
description: Added suppoort of import assertions to the
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
description: Added suppoort of import assertions to the
description: Added support of import assertions to the

Typo.

`importModuleDynamically` parameter.
-->

* `code` {string} JavaScript Module code to parse
* `options`
Expand All @@ -667,6 +680,8 @@ defined in the ECMAScript specification.
`import()` will reject with [`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING`][].
* `specifier` {string} specifier passed to `import()`
* `module` {vm.Module}
* `import_assertions` {Object} The `"assert"` value passed to the
`optionExpression` optional parameter.
* Returns: {Module Namespace Object|vm.Module} Returning a `vm.Module` is
recommended in order to take advantage of error tracking, and to avoid
issues with namespaces that contain `then` function exports.
Expand Down Expand Up @@ -852,6 +867,10 @@ const vm = require('vm');
<!-- YAML
added: v10.10.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/39921
description: Added suppoort of import assertions to the
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
description: Added suppoort of import assertions to the
description: Added support of import assertions to the

Typo.

`importModuleDynamically` parameter.
- version: v15.9.0
pr-url: https://github.com/nodejs/node/pull/35431
description: Added `importModuleDynamically` option again.
Expand Down Expand Up @@ -893,6 +912,8 @@ changes:
considered stable.
* `specifier` {string} specifier passed to `import()`
* `function` {Function}
* `import_assertions` {Object} The `"assert"` value passed to the
`optionExpression` optional parameter.
* Returns: {Module Namespace Object|vm.Module} Returning a `vm.Module` is
recommended in order to take advantage of error tracking, and to avoid
issues with namespaces that contain `then` function exports.
Expand Down Expand Up @@ -1068,6 +1089,10 @@ vm.measureMemory({ mode: 'detailed', execution: 'eager' })
<!-- YAML
added: v0.3.1
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/39921
description: Added suppoort of import assertions to the
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
description: Added suppoort of import assertions to the
description: Added support of import assertions to the

Typo.

`importModuleDynamically` parameter.
- version: v6.3.0
pr-url: https://github.com/nodejs/node/pull/6635
description: The `breakOnSigint` option is supported now.
Expand Down Expand Up @@ -1113,6 +1138,8 @@ changes:
using it in a production environment.
* `specifier` {string} specifier passed to `import()`
* `script` {vm.Script}
* `import_assertions` {Object} The `"assert"` value passed to the
`optionExpression` optional parameter.
* Returns: {Module Namespace Object|vm.Module} Returning a `vm.Module` is
recommended in order to take advantage of error tracking, and to avoid
issues with namespaces that contain `then` function exports.
Expand Down Expand Up @@ -1145,6 +1172,10 @@ console.log(contextObject);
<!-- YAML
added: v0.3.1
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/39921
description: Added suppoort of import assertions to the
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
description: Added suppoort of import assertions to the
description: Added support of import assertions to the

Typo.

`importModuleDynamically` parameter.
- version: v14.6.0
pr-url: https://github.com/nodejs/node/pull/34023
description: The `microtaskMode` option is supported now.
Expand Down Expand Up @@ -1211,6 +1242,8 @@ changes:
using it in a production environment.
* `specifier` {string} specifier passed to `import()`
* `script` {vm.Script}
* `import_assertions` {Object} The `"assert"` value passed to the
`optionExpression` optional parameter.
* Returns: {Module Namespace Object|vm.Module} Returning a `vm.Module` is
recommended in order to take advantage of error tracking, and to avoid
issues with namespaces that contain `then` function exports.
Expand Down Expand Up @@ -1247,6 +1280,10 @@ console.log(contextObject);
<!-- YAML
added: v0.3.1
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/39921
description: Added suppoort of import assertions to the
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
description: Added suppoort of import assertions to the
description: Added support of import assertions to the

Typo.

`importModuleDynamically` parameter.
- version: v6.3.0
pr-url: https://github.com/nodejs/node/pull/6635
description: The `breakOnSigint` option is supported now.
Expand Down Expand Up @@ -1290,6 +1327,8 @@ changes:
using it in a production environment.
* `specifier` {string} specifier passed to `import()`
* `script` {vm.Script}
* `import_assertions` {Object} The `"assert"` value passed to the
`optionExpression` optional parameter.
* Returns: {Module Namespace Object|vm.Module} Returning a `vm.Module` is
recommended in order to take advantage of error tracking, and to avoid
issues with namespaces that contain `then` function exports.
Expand Down
9 changes: 9 additions & 0 deletions lib/internal/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -953,6 +953,9 @@ E('ERR_ENCODING_NOT_SUPPORTED', 'The "%s" encoding is not supported',
RangeError);
E('ERR_EVAL_ESM_CANNOT_PRINT', '--print cannot be used with ESM input', Error);
E('ERR_EVENT_RECURSION', 'The event "%s" is already being dispatched', Error);
E('ERR_FAILED_IMPORT_ASSERTION', (request, key, expectedValue, actualValue) => {
return `Failed to load module "${request}", expected ${key} to be ${JSONStringify(expectedValue)}, got ${JSONStringify(actualValue)} instead`;
}, TypeError);
E('ERR_FALSY_VALUE_REJECTION', function(reason) {
this.reason = reason;
return 'Promise was rejected with falsy value';
Expand Down Expand Up @@ -1250,6 +1253,9 @@ E('ERR_INVALID_FILE_URL_HOST',
E('ERR_INVALID_FILE_URL_PATH', 'File URL path %s', TypeError);
E('ERR_INVALID_HANDLE_TYPE', 'This handle type cannot be sent', TypeError);
E('ERR_INVALID_HTTP_TOKEN', '%s must be a valid HTTP token ["%s"]', TypeError);
E('ERR_INVALID_IMPORT_ASSERTION',
(type, value) => `Invalid ${JSONStringify(type)} import assertion: ${JSONStringify(value)}`,
TypeError);
E('ERR_INVALID_IP_ADDRESS', 'Invalid IP address: %s', TypeError);
E('ERR_INVALID_MODULE_SPECIFIER', (request, reason, base = undefined) => {
return `Invalid module "${request}" ${reason}${base ?
Expand Down Expand Up @@ -1394,6 +1400,9 @@ E('ERR_MISSING_ARGS',
}
return `${msg} must be specified`;
}, TypeError);
E('ERR_MISSING_IMPORT_ASSERTION',
'Failed to load %s: Node.js requires modules of format "%s" to be loaded ' +
'using an assertion "%s" with value "%s"', TypeError);
E('ERR_MISSING_OPTION', '%s is required', TypeError);
E('ERR_MODULE_NOT_FOUND', (path, base, type = 'package') => {
return `Cannot find ${type} '${path}' imported from ${base}`;
Expand Down
10 changes: 6 additions & 4 deletions lib/internal/modules/cjs/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -1015,9 +1015,10 @@ function wrapSafe(filename, content, cjsModuleInstance) {
filename,
lineOffset: 0,
displayErrors: true,
importModuleDynamically: async (specifier) => {
importModuleDynamically: async (specifier, _, import_assertions) => {
const loader = asyncESM.esmLoader;
return loader.import(specifier, normalizeReferrerURL(filename));
return loader.import(specifier, normalizeReferrerURL(filename),
import_assertions);
},
});
}
Expand All @@ -1030,9 +1031,10 @@ function wrapSafe(filename, content, cjsModuleInstance) {
'__dirname',
], {
filename,
importModuleDynamically(specifier) {
importModuleDynamically(specifier, _, import_assertions) {
const loader = asyncESM.esmLoader;
return loader.import(specifier, normalizeReferrerURL(filename));
return loader.import(specifier, normalizeReferrerURL(filename),
import_assertions);
},
});
} catch (err) {
Expand Down
Loading