From d22b640a3281c98b6d826f9e9f5c30b329b2ce37 Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Sat, 14 Oct 2023 05:52:38 +0200 Subject: [PATCH] esm: use import attributes instead of import assertions The old import assertions proposal has been renamed to "import attributes" with the follwing major changes: 1. The keyword is now `with` instead of `assert`. 2. Unknown assertions cause an error rather than being ignored, This commit updates the documentation to encourage folks to use the new syntax, and add aliases for module customization hooks. PR-URL: https://github.com/nodejs/node/pull/50140 Fixes: https://github.com/nodejs/node/issues/50134 Refs: https://github.com/v8/v8/commit/159c82c5e6392e78b9bba7161b1bed6e23758984 Reviewed-By: Geoffrey Booth Reviewed-By: Jacob Smith Reviewed-By: Benjamin Gruenbaum --- .eslintignore | 2 + .eslintrc.js | 4 +- doc/api/errors.md | 17 +++- doc/api/esm.md | 39 ++++++---- doc/api/module.md | 19 +++-- lib/internal/errors.js | 9 ++- lib/internal/modules/cjs/loader.js | 8 +- lib/internal/modules/esm/assert.js | 53 ++++++------- lib/internal/modules/esm/hooks.js | 54 ++++++++++--- lib/internal/modules/esm/load.js | 22 ++++-- lib/internal/modules/esm/loader.js | 77 ++++++++++--------- lib/internal/modules/esm/module_job.js | 10 +-- lib/internal/modules/esm/module_map.js | 16 ++-- lib/internal/modules/esm/translators.js | 16 ++-- lib/internal/modules/esm/utils.js | 15 +++- lib/internal/process/execution.js | 4 +- lib/repl.js | 8 +- src/module_wrap.cc | 44 +++++------ src/module_wrap.h | 2 +- src/node.cc | 7 ++ .../test-esm-assertionless-json-import.js | 10 +-- test/es-module/test-esm-data-urls.js | 10 +-- ...s => test-esm-dynamic-import-attribute.js} | 8 +- ... => test-esm-dynamic-import-attribute.mjs} | 8 +- .../es-module/test-esm-import-assertion-2.mjs | 6 -- .../test-esm-import-assertion-validation.js | 45 ----------- .../test-esm-import-assertion-warning.mjs | 43 +++++++++-- ...1.mjs => test-esm-import-attributes-1.mjs} | 2 +- ...4.mjs => test-esm-import-attributes-2.mjs} | 4 +- ...3.mjs => test-esm-import-attributes-3.mjs} | 4 +- ...s => test-esm-import-attributes-errors.js} | 26 +++---- ... => test-esm-import-attributes-errors.mjs} | 24 ++---- .../test-esm-import-attributes-validation.js | 45 +++++++++++ test/es-module/test-esm-json-cache.mjs | 2 +- test/es-module/test-esm-json.mjs | 11 ++- test/es-module/test-esm-virtual-json.mjs | 6 +- .../assertionless-json-import.mjs | 14 ++-- .../builtin-named-exports-loader.mjs | 2 +- .../es-module-loaders/hooks-custom.mjs | 4 +- .../es-module-loaders/hooks-input.mjs | 12 +-- .../loader-invalid-format.mjs | 2 +- .../es-module-loaders/loader-invalid-url.mjs | 4 +- .../es-module-loaders/loader-with-dep.mjs | 4 +- .../not-found-assert-loader.mjs | 4 +- .../es-module-loaders/string-sources.mjs | 2 +- .../es-modules/import-json-named-export.mjs | 2 +- test/fixtures/es-modules/json-modules.mjs | 2 +- .../parallel/test-vm-module-dynamic-import.js | 6 +- tools/dep_updaters/update-eslint.sh | 4 +- .../lib/index.js | 19 ----- .../LICENSE | 0 .../lib/index.js | 31 ++++++++ .../package.json | 10 ++- .../data/features/css-display-contents.js | 2 +- .../node_modules/caniuse-lite/package.json | 2 +- .../full-chromium-versions.js | 50 +++++++++++- .../full-chromium-versions.json | 2 +- .../electron-to-chromium/full-versions.js | 32 +++++++- .../electron-to-chromium/full-versions.json | 2 +- .../electron-to-chromium/package.json | 2 +- 60 files changed, 541 insertions(+), 353 deletions(-) rename test/es-module/{test-esm-dynamic-import-assertion.js => test-esm-dynamic-import-attribute.js} (78%) rename test/es-module/{test-esm-dynamic-import-assertion.mjs => test-esm-dynamic-import-attribute.mjs} (75%) delete mode 100644 test/es-module/test-esm-import-assertion-2.mjs delete mode 100644 test/es-module/test-esm-import-assertion-validation.js rename test/es-module/{test-esm-import-assertion-1.mjs => test-esm-import-attributes-1.mjs} (57%) rename test/es-module/{test-esm-import-assertion-4.mjs => test-esm-import-attributes-2.mjs} (70%) rename test/es-module/{test-esm-import-assertion-3.mjs => test-esm-import-attributes-3.mjs} (69%) rename test/es-module/{test-esm-import-assertion-errors.js => test-esm-import-attributes-errors.js} (59%) rename test/es-module/{test-esm-import-assertion-errors.mjs => test-esm-import-attributes-errors.mjs} (56%) create mode 100644 test/es-module/test-esm-import-attributes-validation.js delete mode 100644 tools/node_modules/eslint/node_modules/@babel/plugin-syntax-import-assertions/lib/index.js rename tools/node_modules/eslint/node_modules/@babel/{plugin-syntax-import-assertions => plugin-syntax-import-attributes}/LICENSE (100%) create mode 100644 tools/node_modules/eslint/node_modules/@babel/plugin-syntax-import-attributes/lib/index.js rename tools/node_modules/eslint/node_modules/@babel/{plugin-syntax-import-assertions => plugin-syntax-import-attributes}/package.json (66%) diff --git a/.eslintignore b/.eslintignore index 268232d911bbb5..64f34660d87a8f 100644 --- a/.eslintignore +++ b/.eslintignore @@ -9,5 +9,7 @@ tools/github_reporter benchmark/tmp benchmark/fixtures doc/**/*.js +doc/changelogs/CHANGELOG_v1*.md +!doc/changelogs/CHANGELOG_v18.md !doc/api_assets/*.js !.eslintrc.js diff --git a/.eslintrc.js b/.eslintrc.js index 47b218c55e9171..82481b3d2be1c6 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -18,7 +18,7 @@ const hacks = [ 'eslint-plugin-jsdoc', 'eslint-plugin-markdown', '@babel/eslint-parser', - '@babel/plugin-syntax-import-assertions', + '@babel/plugin-syntax-import-attributes', ]; Module._findPath = (request, paths, isMain) => { const r = ModuleFindPath(request, paths, isMain); @@ -44,7 +44,7 @@ module.exports = { parserOptions: { babelOptions: { plugins: [ - Module._findPath('@babel/plugin-syntax-import-assertions'), + Module._findPath('@babel/plugin-syntax-import-attributes'), ], }, requireConfigFile: false, diff --git a/doc/api/errors.md b/doc/api/errors.md index 95ad3c9c671954..89048c6485df0f 100644 --- a/doc/api/errors.md +++ b/doc/api/errors.md @@ -1759,7 +1759,8 @@ added: - v16.14.0 --> -An import assertion has failed, preventing the specified module to be imported. +An import `type` attribute was provided, but the specified module is of a +different type. @@ -1771,7 +1772,7 @@ added: - v16.14.0 --> -An import assertion is missing, preventing the specified module to be imported. +An import attribute is missing, preventing the specified module to be imported. @@ -1783,7 +1784,17 @@ added: - v16.14.0 --> -An import assertion is not supported by this version of Node.js. +An import attribute is not supported by this version of Node.js. + + + +### `ERR_IMPORT_ATTRIBUTE_UNSUPPORTED` + + + +An import attribute is not supported by this version of Node.js. diff --git a/doc/api/esm.md b/doc/api/esm.md index b40b4ccb6f0865..a96badcf91b55d 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -7,6 +7,9 @@ -> Stability: 1 - Experimental +> Stability: 1.1 - Active development + +> This feature was previously named "Import assertions", and using the `assert` +> keyword instead of `with`. Any uses in code of the prior `assert` keyword +> should be updated to use `with` instead. -The [Import Assertions proposal][] adds an inline syntax for module import +The [Import Attributes proposal][] adds an inline syntax for module import statements to pass on more information alongside the module specifier. ```js -import fooData from './foo.json' assert { type: 'json' }; +import fooData from './foo.json' with { type: 'json' }; const { default: barData } = - await import('./bar.json', { assert: { type: 'json' } }); + await import('./bar.json', { with: { type: 'json' } }); ``` -Node.js supports the following `type` values, for which the assertion is +Node.js supports the following `type` values, for which the attribute is mandatory: -| Assertion `type` | Needed for | +| Attribute `type` | Needed for | | ---------------- | ---------------- | | `'json'` | [JSON modules][] | @@ -544,10 +557,10 @@ separate cache. JSON files can be referenced by `import`: ```js -import packageConfig from './package.json' assert { type: 'json' }; +import packageConfig from './package.json' with { type: 'json' }; ``` -The `assert { type: 'json' }` syntax is mandatory; see [Import Assertions][]. +The `with { type: 'json' }` syntax is mandatory; see [Import Attributes][]. The imported JSON only exposes a `default` export. There is no support for named exports. A cache entry is created in the CommonJS cache to avoid duplication. @@ -1050,8 +1063,8 @@ resolution for ESM specifiers is [commonjs-extension-resolution-loader][]. [Determining module system]: packages.md#determining-module-system [Dynamic `import()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import [ES Module Integration Proposal for WebAssembly]: https://github.com/webassembly/esm-integration -[Import Assertions]: #import-assertions -[Import Assertions proposal]: https://github.com/tc39/proposal-import-assertions +[Import Attributes]: #import-attributes +[Import Attributes proposal]: https://github.com/tc39/proposal-import-attributes [JSON modules]: #json-modules [Module customization hooks]: module.md#customization-hooks [Node.js Module Resolution And Loading Algorithm]: #resolution-algorithm-specification diff --git a/doc/api/module.md b/doc/api/module.md index 8bf5c09041a41a..857c02142b199f 100644 --- a/doc/api/module.md +++ b/doc/api/module.md @@ -458,6 +458,11 @@ register('./path-to-my-hooks.js', {