mirror of
https://github.com/zebrajr/node.git
synced 2026-01-15 12:15:26 +00:00
esm: fix erroneous re-initialization of ESMLoader
PR-URL: https://github.com/nodejs/node/pull/43763 Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com> Reviewed-By: Minwoo Jung <nodecorelab@gmail.com> Reviewed-By: Guy Bedford <guybedford@gmail.com>
This commit is contained in:
@@ -40,14 +40,20 @@ async function importModuleDynamicallyCallback(wrap, specifier, assertions) {
|
||||
};
|
||||
|
||||
const esmLoader = new ESMLoader();
|
||||
|
||||
exports.esmLoader = esmLoader;
|
||||
|
||||
// Module.runMain() causes loadESM() to re-run (which it should do); however, this should NOT cause
|
||||
// ESM to be re-initialised; doing so causes duplicate custom loaders to be added to the public
|
||||
// esmLoader.
|
||||
let isESMInitialized = false;
|
||||
|
||||
/**
|
||||
* Causes side-effects: user-defined loader hooks are added to esmLoader.
|
||||
* @returns {void}
|
||||
*/
|
||||
async function initializeLoader() {
|
||||
if (isESMInitialized) { return; }
|
||||
|
||||
const { getOptionValue } = require('internal/options');
|
||||
const customLoaders = getOptionValue('--experimental-loader');
|
||||
|
||||
@@ -75,6 +81,8 @@ async function initializeLoader() {
|
||||
// Hooks must then be added to external/public loader
|
||||
// (so they're triggered in userland)
|
||||
await esmLoader.addCustomLoaders(keyedExportsList);
|
||||
|
||||
isESMInitialized = true;
|
||||
}
|
||||
|
||||
exports.loadESM = async function loadESM(callback) {
|
||||
|
||||
30
test/es-module/test-esm-initialization.mjs
Normal file
30
test/es-module/test-esm-initialization.mjs
Normal file
@@ -0,0 +1,30 @@
|
||||
import '../common/index.mjs';
|
||||
import * as fixtures from '../common/fixtures.mjs';
|
||||
import assert from 'node:assert';
|
||||
import { spawnSync } from 'node:child_process';
|
||||
|
||||
|
||||
{ // Verify unadulterated source is loaded when there are no loaders
|
||||
const { status, stderr, stdout } = spawnSync(
|
||||
process.execPath,
|
||||
[
|
||||
'--loader',
|
||||
fixtures.fileURL('es-module-loaders', 'loader-resolve-passthru.mjs'),
|
||||
'--no-warnings',
|
||||
fixtures.path('es-modules', 'runmain.mjs'),
|
||||
],
|
||||
{ encoding: 'utf8' },
|
||||
);
|
||||
|
||||
// Length minus 1 because the first match is the needle.
|
||||
const resolveHookRunCount = (stdout.match(/resolve passthru/g)?.length ?? 0) - 1;
|
||||
|
||||
assert.strictEqual(stderr, '');
|
||||
/**
|
||||
* resolveHookRunCount = 2:
|
||||
* 1. fixtures/…/runmain.mjs
|
||||
* 2. node:module (imported by fixtures/…/runmain.mjs)
|
||||
*/
|
||||
assert.strictEqual(resolveHookRunCount, 2);
|
||||
assert.strictEqual(status, 0);
|
||||
}
|
||||
7
test/fixtures/es-modules/runmain.mjs
vendored
Normal file
7
test/fixtures/es-modules/runmain.mjs
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
import { runMain } from 'node:module';
|
||||
|
||||
try { await import.meta.resolve('doesnt-matter.mjs') } catch {}
|
||||
|
||||
runMain();
|
||||
|
||||
try { await import.meta.resolve('doesnt-matter.mjs') } catch {}
|
||||
Reference in New Issue
Block a user