mirror of
https://github.com/nodejs/node.git
synced 2024-11-21 10:59:27 +00:00
esm: do not call getSource
when format is commonjs
Ensure that `defaultLoad` does not uselessly access the file system to get the source of modules that are known to be in CommonJS format. This allows CommonJS imports to resolve in the current phase of the event loop. Refs: https://github.com/eslint/eslint/pull/17683 PR-URL: https://github.com/nodejs/node/pull/50465 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
This commit is contained in:
parent
4eafcf8ff5
commit
2602c4642b
@ -132,20 +132,21 @@ async function defaultLoad(url, context = kEmptyObject) {
|
||||
if (urlInstance.protocol === 'node:') {
|
||||
source = null;
|
||||
format ??= 'builtin';
|
||||
} else {
|
||||
let contextToPass = context;
|
||||
} else if (format !== 'commonjs' || defaultType === 'module') {
|
||||
if (source == null) {
|
||||
({ responseURL, source } = await getSource(urlInstance, context));
|
||||
contextToPass = { __proto__: context, source };
|
||||
context = { __proto__: context, source };
|
||||
}
|
||||
|
||||
// Now that we have the source for the module, run `defaultGetFormat` again in case we detect ESM syntax.
|
||||
format ??= await defaultGetFormat(urlInstance, contextToPass);
|
||||
if (format == null) {
|
||||
// Now that we have the source for the module, run `defaultGetFormat` to detect its format.
|
||||
format = await defaultGetFormat(urlInstance, context);
|
||||
|
||||
if (format === 'commonjs' && contextToPass !== context && defaultType !== 'module') {
|
||||
// For backward compatibility reasons, we need to discard the source in
|
||||
// order for the CJS loader to re-fetch it.
|
||||
source = null;
|
||||
if (format === 'commonjs') {
|
||||
// For backward compatibility reasons, we need to discard the source in
|
||||
// order for the CJS loader to re-fetch it.
|
||||
source = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
19
test/es-module/test-esm-dynamic-import-commonjs.js
Normal file
19
test/es-module/test-esm-dynamic-import-commonjs.js
Normal file
@ -0,0 +1,19 @@
|
||||
'use strict';
|
||||
|
||||
const common = require('../common');
|
||||
const fixtures = require('../common/fixtures');
|
||||
const assert = require('node:assert');
|
||||
|
||||
(async () => {
|
||||
|
||||
// Make sure that the CommonJS module lexer has been initialized.
|
||||
// See https://github.com/nodejs/node/blob/v21.1.0/lib/internal/modules/esm/translators.js#L61-L81.
|
||||
await import(fixtures.fileURL('empty.js'));
|
||||
|
||||
let tickDuringCJSImport = false;
|
||||
process.nextTick(() => { tickDuringCJSImport = true; });
|
||||
await import(fixtures.fileURL('empty.cjs'));
|
||||
|
||||
assert(!tickDuringCJSImport);
|
||||
|
||||
})().then(common.mustCall());
|
9
test/es-module/test-esm-dynamic-import-commonjs.mjs
Normal file
9
test/es-module/test-esm-dynamic-import-commonjs.mjs
Normal file
@ -0,0 +1,9 @@
|
||||
import '../common/index.mjs';
|
||||
import fixtures from '../common/fixtures.js';
|
||||
import assert from 'node:assert';
|
||||
|
||||
let tickDuringCJSImport = false;
|
||||
process.nextTick(() => { tickDuringCJSImport = true; });
|
||||
await import(fixtures.fileURL('empty.cjs'));
|
||||
|
||||
assert(!tickDuringCJSImport);
|
10
test/es-module/test-esm-loader-with-source.mjs
Normal file
10
test/es-module/test-esm-loader-with-source.mjs
Normal file
@ -0,0 +1,10 @@
|
||||
// Flags: --experimental-loader ./test/fixtures/es-module-loaders/preset-cjs-source.mjs
|
||||
import '../common/index.mjs';
|
||||
import * as fixtures from '../common/fixtures.mjs';
|
||||
import assert from 'assert';
|
||||
|
||||
const { default: existingFileSource } = await import(fixtures.fileURL('es-modules', 'cjs-file.cjs'));
|
||||
const { default: noSuchFileSource } = await import(new URL('./no-such-file.cjs', import.meta.url));
|
||||
|
||||
assert.strictEqual(existingFileSource, 'no .cjs file was read to get this source');
|
||||
assert.strictEqual(noSuchFileSource, 'no .cjs file was read to get this source');
|
0
test/fixtures/empty.cjs
vendored
Normal file
0
test/fixtures/empty.cjs
vendored
Normal file
21
test/fixtures/es-module-loaders/preset-cjs-source.mjs
vendored
Normal file
21
test/fixtures/es-module-loaders/preset-cjs-source.mjs
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
export function resolve(specifier, context, next) {
|
||||
if (specifier.endsWith('/no-such-file.cjs')) {
|
||||
// Shortcut to avoid ERR_MODULE_NOT_FOUND for non-existing file, but keep the url for the load hook.
|
||||
return {
|
||||
shortCircuit: true,
|
||||
url: specifier,
|
||||
};
|
||||
}
|
||||
return next(specifier);
|
||||
}
|
||||
|
||||
export function load(href, context, next) {
|
||||
if (href.endsWith('.cjs')) {
|
||||
return {
|
||||
format: 'commonjs',
|
||||
shortCircuit: true,
|
||||
source: 'module.exports = "no .cjs file was read to get this source";',
|
||||
};
|
||||
}
|
||||
return next(href);
|
||||
}
|
Loading…
Reference in New Issue
Block a user