module: refactor ESM loader initialization and entry point handling

Split the `internal/process/esm_loader` file which contains the
singleton cascaded loader:

- The the singleton cascaded loader now directly resides in
  `internal/modules/esm/loader`, where the constructor also lives.
  This file is the root of most circular dependency of ESM code,
  (because components of the loader need the singleton itself),
  so this makes the dependency more obvious. Added comments about
  loading it lazily to avoid circular dependency.
- The getter to the cascaded loader is also turned into a method
  to make the side effect explicit.
- The sequence of `loadESM()` and `handleMainPromise` is now merged
  together into `runEntryPointWithESMLoader()` in
  `internal/modules/run_main` because this is intended to run entry
  points with the ESM loader and not just any module.
- Documents how top-level await is handled.

PR-URL: https://github.com/nodejs/node/pull/51999
Fixes: https://github.com/nodejs/node/issues/42868
Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com>
This commit is contained in:
Joyee Cheung 2024-03-02 03:23:22 +01:00
parent 257f32296d
commit 075c95f61f
No known key found for this signature in database
GPG key ID: 92B78A53C8303B8D
17 changed files with 136 additions and 140 deletions

View file

@ -32,7 +32,6 @@ const {
const {
emitExperimentalWarning,
getCWDURL,
getLazy,
} = require('internal/util');
const {
setImportModuleDynamicallyCallback,
@ -181,9 +180,6 @@ function initializeImportMetaObject(symbol, meta) {
}
}
}
const getCascadedLoader = getLazy(
() => require('internal/process/esm_loader').esmLoader,
);
/**
* Proxy the dynamic import to the default loader.
@ -194,7 +190,8 @@ const getCascadedLoader = getLazy(
*/
function defaultImportModuleDynamically(specifier, attributes, referrerName) {
const parentURL = normalizeReferrerURL(referrerName);
return getCascadedLoader().import(specifier, parentURL, attributes);
const cascadedLoader = require('internal/modules/esm/loader').getOrInitializeCascadedLoader();
return cascadedLoader.import(specifier, parentURL, attributes);
}
/**
@ -263,10 +260,10 @@ async function initializeHooks() {
const customLoaderURLs = getOptionValue('--experimental-loader');
const { Hooks } = require('internal/modules/esm/hooks');
const esmLoader = require('internal/process/esm_loader').esmLoader;
const cascadedLoader = require('internal/modules/esm/loader').getOrInitializeCascadedLoader();
const hooks = new Hooks();
esmLoader.setCustomizations(hooks);
cascadedLoader.setCustomizations(hooks);
// We need the loader customizations to be set _before_ we start invoking
// `--require`, otherwise loops can happen because a `--require` script