diff --git a/doc/api/cli.md b/doc/api/cli.md index 70cb69cd54a451..449aff30cbfa0e 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -222,13 +222,6 @@ added: Enable experimental `import.meta.resolve()` support. -### `--experimental-json-modules` - - -Enable experimental JSON support for the ES Module loader. - ### `--experimental-loader=module` -```js -import { readFile } from 'fs/promises'; -const json = JSON.parse(await readFile(new URL('./dat.json', import.meta.url))); -``` - -Alterantively `module.createRequire()` can be used. - #### No Native Module Loading Native modules are not currently supported with ES module imports. @@ -471,35 +459,35 @@ separate cache. ## JSON modules + > Stability: 1 - Experimental -Currently importing JSON modules are only supported in the `commonjs` mode -and are loaded using the CJS loader. [WHATWG JSON modules specification][] are -still being standardized, and are experimentally supported by including the -additional flag `--experimental-json-modules` when running Node.js. - -When the `--experimental-json-modules` flag is included, both the -`commonjs` and `module` mode use the new experimental JSON -loader. The imported JSON only exposes a `default`. There is no +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. The same object is returned in CommonJS if the JSON module has already been imported from the same path. -Assuming an `index.mjs` with - - -```js +```js esm import packageConfig from './package.json'; +const { version, name } = packageConfig; + +console.log(version); ``` -The `--experimental-json-modules` flag is needed for the module -to work. +```js cjs +(async () => { + const { default: { version, name } } = await import('./package.json'); -```bash -node index.mjs # fails -node --experimental-json-modules index.mjs # works + console.log(version); +})().catch(console.error); ``` diff --git a/lib/internal/modules/esm/get_format.js b/lib/internal/modules/esm/get_format.js index f02bb5cde70772..5afff8ac56a338 100644 --- a/lib/internal/modules/esm/get_format.js +++ b/lib/internal/modules/esm/get_format.js @@ -6,7 +6,6 @@ const { const { extname } = require('path'); const { getOptionValue } = require('internal/options'); -const experimentalJsonModules = getOptionValue('--experimental-json-modules'); const experimentalSpecifierResolution = getOptionValue('--experimental-specifier-resolution'); const experimentalWasmModules = getOptionValue('--experimental-wasm-modules'); @@ -18,7 +17,8 @@ const extensionFormatMap = { '__proto__': null, '.cjs': 'commonjs', '.js': 'module', - '.mjs': 'module' + '.mjs': 'module', + '.json': 'json', }; const legacyExtensionFormatMap = { @@ -33,9 +33,6 @@ const legacyExtensionFormatMap = { if (experimentalWasmModules) extensionFormatMap['.wasm'] = legacyExtensionFormatMap['.wasm'] = 'wasm'; -if (experimentalJsonModules) - extensionFormatMap['.json'] = legacyExtensionFormatMap['.json'] = 'json'; - function defaultGetFormat(url, context, defaultGetFormatUnused) { if (StringPrototypeStartsWith(url, 'node:')) { return { format: 'builtin' }; @@ -49,7 +46,7 @@ function defaultGetFormat(url, context, defaultGetFormatUnused) { const format = ({ '__proto__': null, 'text/javascript': 'module', - 'application/json': experimentalJsonModules ? 'json' : null, + 'application/json': 'json', 'application/wasm': experimentalWasmModules ? 'wasm' : null })[mime] || null; return { format }; diff --git a/src/node_options.cc b/src/node_options.cc index d292231218f1fc..3b50df159268e3 100644 --- a/src/node_options.cc +++ b/src/node_options.cc @@ -303,8 +303,7 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() { kAllowedInEnvironment); AddOption("--experimental-abortcontroller", "", NoOp{}, kAllowedInEnvironment); - AddOption("--experimental-json-modules", - "experimental JSON interop support for the ES Module loader", + AddOption("--experimental-json-modules", "", &EnvironmentOptions::experimental_json_modules, kAllowedInEnvironment); AddOption("--experimental-loader", diff --git a/test/es-module/test-esm-non-js.js b/test/es-module/test-esm-non-js.js index 3e572809bbdf35..7505a988798a38 100644 --- a/test/es-module/test-esm-non-js.js +++ b/test/es-module/test-esm-non-js.js @@ -1,21 +1,15 @@ 'use strict'; const common = require('../common'); -const { spawn } = require('child_process'); -const assert = require('assert'); - -const entry = require.resolve('./test-esm-json.mjs'); +const fixtures = require('../common/fixtures'); -// Verify non-js extensions fail for ESM -const child = spawn(process.execPath, [entry]); - -let stderr = ''; -child.stderr.setEncoding('utf8'); -child.stderr.on('data', (data) => { - stderr += data; -}); -child.on('close', common.mustCall((code, signal) => { - assert.strictEqual(code, 1); - assert.strictEqual(signal, null); - assert.ok(stderr.indexOf('ERR_UNKNOWN_FILE_EXTENSION') !== -1); +const assert = require('assert'); +const { pathToFileURL } = require('url'); +const { Worker } = require('worker_threads'); + +new Worker(new URL( + 'data:text/javascript,' + + `import ${JSON.stringify(pathToFileURL(fixtures.path('altdocs.md')))};` +)).on('error', common.mustCall((err) => { + assert.strictEqual(err.code, 'ERR_UNKNOWN_FILE_EXTENSION'); }));