Skip to content

Commit

Permalink
Allow JSON imports in NodeJS 16.15 (#1792)
Browse files Browse the repository at this point in the history
* Allow JSON imports in NodeJS 16.15

* Update tests

* Run formatter

* tweak testing

* fix

Co-authored-by: Andrew Bradley <cspotcode@gmail.com>
  • Loading branch information
queengooborg and cspotcode committed Jun 17, 2022
1 parent 14323f9 commit bf13086
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 35 deletions.
1 change: 1 addition & 0 deletions dist-raw/node-internal-modules-esm-get_format.js
Expand Up @@ -12,6 +12,7 @@ const [nodeMajor, nodeMinor] = process.versions.node.split('.').map(s => parseIn
const experimentalJsonModules =
nodeMajor > 17
|| (nodeMajor === 17 && nodeMinor >= 5)
|| (nodeMajor === 16 && nodeMinor >= 15)
|| getOptionValue('--experimental-json-modules');
const experimentalWasmModules = getOptionValue('--experimental-wasm-modules');
const { URL, fileURLToPath } = require('url');
Expand Down
64 changes: 33 additions & 31 deletions src/test/esm-loader.spec.ts
Expand Up @@ -15,10 +15,13 @@ import {
EXPERIMENTAL_MODULES_FLAG,
nodeSupportsEsmHooks,
nodeSupportsImportAssertions,
nodeSupportsUnflaggedJsonImports,
nodeSupportsSpawningChildProcess,
nodeUsesNewHooksApi,
resetNodeEnvironment,
TEST_DIR,
tsSupportsImportAssertions,
tsSupportsResolveJsonModule,
} from './helpers';
import { createExec, createSpawn, ExecReturn } from './exec-helpers';
import { join, resolve } from 'path';
Expand Down Expand Up @@ -268,40 +271,39 @@ test.suite('esm', (test) => {
});

test.suite('supports import assertions', (test) => {
test.runIf(nodeSupportsImportAssertions);

test.suite('node >=17.5.0', (test) => {
test.runIf(semver.gte(process.version, '17.5.0'));
test.runIf(
nodeSupportsImportAssertions &&
tsSupportsImportAssertions &&
tsSupportsResolveJsonModule
);

test('Can import JSON modules with appropriate assertion', async (t) => {
const { err, stdout } = await exec(
`${CMD_ESM_LOADER_WITHOUT_PROJECT} ./importJson.ts`,
{
cwd: resolve(TEST_DIR, 'esm-import-assertions'),
}
);
expect(err).toBe(null);
expect(stdout.trim()).toBe(
'A fuchsia car has 2 seats and the doors are open.\nDone!'
);
});
const macro = test.macro((flags: string) => async (t) => {
const { err, stdout } = await exec(
`${CMD_ESM_LOADER_WITHOUT_PROJECT} ${flags} ./importJson.ts`,
{
cwd: resolve(TEST_DIR, 'esm-import-assertions'),
}
);
expect(err).toBe(null);
expect(stdout.trim()).toBe(
'A fuchsia car has 2 seats and the doors are open.\nDone!'
);
});

test.suite('node <17.5.0', (test) => {
test.runIf(semver.lt(process.version, '17.5.0'));

test('Can import JSON using the appropriate flag and assertion', async (t) => {
const { err, stdout } = await exec(
`${CMD_ESM_LOADER_WITHOUT_PROJECT} --experimental-json-modules ./importJson.ts`,
{
cwd: resolve(TEST_DIR, 'esm-import-assertions'),
}
);
expect(err).toBe(null);
expect(stdout.trim()).toBe(
'A fuchsia car has 2 seats and the doors are open.\nDone!'
);
});
test.suite(
'when node does not require --experimental-json-modules',
(test) => {
test.runIf(nodeSupportsUnflaggedJsonImports);
test('Can import JSON modules with appropriate assertion', macro, '');
}
);
test.suite('when node requires --experimental-json-modules', (test) => {
test.runIf(!nodeSupportsUnflaggedJsonImports);
test(
'Can import JSON using the appropriate flag and assertion',
macro,
'--experimental-json-modules'
);
});
});

Expand Down
19 changes: 15 additions & 4 deletions src/test/helpers.ts
Expand Up @@ -64,10 +64,19 @@ export const nodeSupportsSpawningChildProcess = semver.gte(
'12.17.0'
);
export const nodeUsesNewHooksApi = semver.gte(process.version, '16.12.0');
export const nodeSupportsImportAssertions = semver.gte(
process.version,
'17.1.0'
);
// 16.14.0: https://github.com/nodejs/node/blob/main/doc/changelogs/CHANGELOG_V16.md#notable-changes-4
// 17.1.0: https://github.com/nodejs/node/blob/main/doc/changelogs/CHANGELOG_V17.md#2021-11-09-version-1710-current-targos
export const nodeSupportsImportAssertions =
(semver.gte(process.version, '16.14.0') &&
semver.lt(process.version, '17.0.0')) ||
semver.gte(process.version, '17.1.0');
// These versions do not require `--experimental-json-modules`
// 16.15.0: https://github.com/nodejs/node/blob/main/doc/changelogs/CHANGELOG_V16.md#2022-04-26-version-16150-gallium-lts-danielleadams
// 17.5.0: https://github.com/nodejs/node/blob/main/doc/changelogs/CHANGELOG_V17.md#2022-02-10-version-1750-current-ruyadorno
export const nodeSupportsUnflaggedJsonImports =
(semver.gte(process.version, '16.15.0') &&
semver.lt(process.version, '17.0.0')) ||
semver.gte(process.version, '17.5.0');
// Node 14.13.0 has a bug where it tries to lex CJS files to discover named exports *before*
// we transform the code.
// In other words, it tries to parse raw TS as CJS and balks at `export const foo =`, expecting to see `exports.foo =`
Expand All @@ -76,6 +85,7 @@ export const nodeSupportsImportingTransformedCjsFromEsm = semver.gte(
process.version,
'14.13.1'
);
export const tsSupportsResolveJsonModule = semver.gte(ts.version, '2.9.0');
/** Supports tsconfig "extends" >= v3.2.0 */
export const tsSupportsTsconfigInheritanceViaNodePackages = semver.gte(
ts.version,
Expand All @@ -88,6 +98,7 @@ export const tsSupportsStableNodeNextNode16 =
ts.version.startsWith('4.7.') || semver.gte(ts.version, '4.7.0');
// TS 4.5 is first version to understand .cts, .mts, .cjs, and .mjs extensions
export const tsSupportsMtsCtsExtensions = semver.gte(ts.version, '4.5.0');
export const tsSupportsImportAssertions = semver.gte(ts.version, '4.5.0');
//#endregion

export const xfs = new NodeFS(fs);
Expand Down

0 comments on commit bf13086

Please sign in to comment.