Skip to content

Commit

Permalink
module: Unflag JSON modules
Browse files Browse the repository at this point in the history
JSON modules TC39 proposal has reached stage 3.

Fixes: #37141
  • Loading branch information
aduh95 committed Feb 15, 2021
1 parent bcb1964 commit 2890a79
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 63 deletions.
7 changes: 0 additions & 7 deletions doc/api/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,13 +222,6 @@ added:

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

### `--experimental-json-modules`
<!-- YAML
added: v12.9.0
-->

Enable experimental JSON support for the ES Module loader.

### `--experimental-loader=module`
<!-- YAML
added: v9.0.0
Expand Down
52 changes: 20 additions & 32 deletions doc/api/esm.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
<!-- YAML
added: v8.5.0
changes:
- version: REPLACEME
pr-url: https://githubcom/nodejs/node/pull/00000
description: Loading JSON modules no longer requires a command-line flag.
- version:
- v15.3.0
pr-url: https://github.com/nodejs/node/pull/35781
Expand Down Expand Up @@ -422,21 +425,6 @@ These CommonJS variables are not available in ES modules.
`__filename` and `__dirname` use cases can be replicated via
[`import.meta.url`][].
#### No JSON Module Loading
JSON imports are still experimental and only supported via the
`--experimental-json-modules` flag.
Local JSON files can be loaded relative to `import.meta.url` with `fs` directly:
<!-- eslint-skip -->
```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.
Expand Down Expand Up @@ -471,35 +459,35 @@ separate cache.
<i id="esm_experimental_json_modules"></i>
## JSON modules
<!--YAML
added: v12.9.0
changes:
- version: REPLACEME
pr-url: https://githubcom/nodejs/node/pull/00000
description: Loading JSON modules no longer requires a command-line flag.
-->
> 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
<!-- eslint-skip -->
```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);
```
<i id="esm_experimental_wasm_modules"></i>
Expand Down
9 changes: 3 additions & 6 deletions lib/internal/modules/esm/get_format.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand All @@ -18,7 +17,8 @@ const extensionFormatMap = {
'__proto__': null,
'.cjs': 'commonjs',
'.js': 'module',
'.mjs': 'module'
'.mjs': 'module',
'.json': 'json',
};

const legacyExtensionFormatMap = {
Expand All @@ -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' };
Expand All @@ -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 };
Expand Down
3 changes: 1 addition & 2 deletions src/node_options.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
26 changes: 10 additions & 16 deletions test/es-module/test-esm-non-js.js
Original file line number Diff line number Diff line change
@@ -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');
}));

0 comments on commit 2890a79

Please sign in to comment.