Skip to content

Commit bf13086

Browse files
Allow JSON imports in NodeJS 16.15 (#1792)
* Allow JSON imports in NodeJS 16.15 * Update tests * Run formatter * tweak testing * fix Co-authored-by: Andrew Bradley <[email protected]>
1 parent 14323f9 commit bf13086

File tree

3 files changed

+49
-35
lines changed

3 files changed

+49
-35
lines changed

dist-raw/node-internal-modules-esm-get_format.js

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const [nodeMajor, nodeMinor] = process.versions.node.split('.').map(s => parseIn
1212
const experimentalJsonModules =
1313
nodeMajor > 17
1414
|| (nodeMajor === 17 && nodeMinor >= 5)
15+
|| (nodeMajor === 16 && nodeMinor >= 15)
1516
|| getOptionValue('--experimental-json-modules');
1617
const experimentalWasmModules = getOptionValue('--experimental-wasm-modules');
1718
const { URL, fileURLToPath } = require('url');

src/test/esm-loader.spec.ts

+33-31
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,13 @@ import {
1515
EXPERIMENTAL_MODULES_FLAG,
1616
nodeSupportsEsmHooks,
1717
nodeSupportsImportAssertions,
18+
nodeSupportsUnflaggedJsonImports,
1819
nodeSupportsSpawningChildProcess,
1920
nodeUsesNewHooksApi,
2021
resetNodeEnvironment,
2122
TEST_DIR,
23+
tsSupportsImportAssertions,
24+
tsSupportsResolveJsonModule,
2225
} from './helpers';
2326
import { createExec, createSpawn, ExecReturn } from './exec-helpers';
2427
import { join, resolve } from 'path';
@@ -268,40 +271,39 @@ test.suite('esm', (test) => {
268271
});
269272

270273
test.suite('supports import assertions', (test) => {
271-
test.runIf(nodeSupportsImportAssertions);
272-
273-
test.suite('node >=17.5.0', (test) => {
274-
test.runIf(semver.gte(process.version, '17.5.0'));
274+
test.runIf(
275+
nodeSupportsImportAssertions &&
276+
tsSupportsImportAssertions &&
277+
tsSupportsResolveJsonModule
278+
);
275279

276-
test('Can import JSON modules with appropriate assertion', async (t) => {
277-
const { err, stdout } = await exec(
278-
`${CMD_ESM_LOADER_WITHOUT_PROJECT} ./importJson.ts`,
279-
{
280-
cwd: resolve(TEST_DIR, 'esm-import-assertions'),
281-
}
282-
);
283-
expect(err).toBe(null);
284-
expect(stdout.trim()).toBe(
285-
'A fuchsia car has 2 seats and the doors are open.\nDone!'
286-
);
287-
});
280+
const macro = test.macro((flags: string) => async (t) => {
281+
const { err, stdout } = await exec(
282+
`${CMD_ESM_LOADER_WITHOUT_PROJECT} ${flags} ./importJson.ts`,
283+
{
284+
cwd: resolve(TEST_DIR, 'esm-import-assertions'),
285+
}
286+
);
287+
expect(err).toBe(null);
288+
expect(stdout.trim()).toBe(
289+
'A fuchsia car has 2 seats and the doors are open.\nDone!'
290+
);
288291
});
289292

290-
test.suite('node <17.5.0', (test) => {
291-
test.runIf(semver.lt(process.version, '17.5.0'));
292-
293-
test('Can import JSON using the appropriate flag and assertion', async (t) => {
294-
const { err, stdout } = await exec(
295-
`${CMD_ESM_LOADER_WITHOUT_PROJECT} --experimental-json-modules ./importJson.ts`,
296-
{
297-
cwd: resolve(TEST_DIR, 'esm-import-assertions'),
298-
}
299-
);
300-
expect(err).toBe(null);
301-
expect(stdout.trim()).toBe(
302-
'A fuchsia car has 2 seats and the doors are open.\nDone!'
303-
);
304-
});
293+
test.suite(
294+
'when node does not require --experimental-json-modules',
295+
(test) => {
296+
test.runIf(nodeSupportsUnflaggedJsonImports);
297+
test('Can import JSON modules with appropriate assertion', macro, '');
298+
}
299+
);
300+
test.suite('when node requires --experimental-json-modules', (test) => {
301+
test.runIf(!nodeSupportsUnflaggedJsonImports);
302+
test(
303+
'Can import JSON using the appropriate flag and assertion',
304+
macro,
305+
'--experimental-json-modules'
306+
);
305307
});
306308
});
307309

src/test/helpers.ts

+15-4
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,19 @@ export const nodeSupportsSpawningChildProcess = semver.gte(
6464
'12.17.0'
6565
);
6666
export const nodeUsesNewHooksApi = semver.gte(process.version, '16.12.0');
67-
export const nodeSupportsImportAssertions = semver.gte(
68-
process.version,
69-
'17.1.0'
70-
);
67+
// 16.14.0: https://github.com/nodejs/node/blob/main/doc/changelogs/CHANGELOG_V16.md#notable-changes-4
68+
// 17.1.0: https://github.com/nodejs/node/blob/main/doc/changelogs/CHANGELOG_V17.md#2021-11-09-version-1710-current-targos
69+
export const nodeSupportsImportAssertions =
70+
(semver.gte(process.version, '16.14.0') &&
71+
semver.lt(process.version, '17.0.0')) ||
72+
semver.gte(process.version, '17.1.0');
73+
// These versions do not require `--experimental-json-modules`
74+
// 16.15.0: https://github.com/nodejs/node/blob/main/doc/changelogs/CHANGELOG_V16.md#2022-04-26-version-16150-gallium-lts-danielleadams
75+
// 17.5.0: https://github.com/nodejs/node/blob/main/doc/changelogs/CHANGELOG_V17.md#2022-02-10-version-1750-current-ruyadorno
76+
export const nodeSupportsUnflaggedJsonImports =
77+
(semver.gte(process.version, '16.15.0') &&
78+
semver.lt(process.version, '17.0.0')) ||
79+
semver.gte(process.version, '17.5.0');
7180
// Node 14.13.0 has a bug where it tries to lex CJS files to discover named exports *before*
7281
// we transform the code.
7382
// In other words, it tries to parse raw TS as CJS and balks at `export const foo =`, expecting to see `exports.foo =`
@@ -76,6 +85,7 @@ export const nodeSupportsImportingTransformedCjsFromEsm = semver.gte(
7685
process.version,
7786
'14.13.1'
7887
);
88+
export const tsSupportsResolveJsonModule = semver.gte(ts.version, '2.9.0');
7989
/** Supports tsconfig "extends" >= v3.2.0 */
8090
export const tsSupportsTsconfigInheritanceViaNodePackages = semver.gte(
8191
ts.version,
@@ -88,6 +98,7 @@ export const tsSupportsStableNodeNextNode16 =
8898
ts.version.startsWith('4.7.') || semver.gte(ts.version, '4.7.0');
8999
// TS 4.5 is first version to understand .cts, .mts, .cjs, and .mjs extensions
90100
export const tsSupportsMtsCtsExtensions = semver.gte(ts.version, '4.5.0');
101+
export const tsSupportsImportAssertions = semver.gte(ts.version, '4.5.0');
91102
//#endregion
92103

93104
export const xfs = new NodeFS(fs);

0 commit comments

Comments
 (0)