Skip to content

Commit 0f01941

Browse files
committed
esm: link modules synchronously when no async loader hooks are used
When no async loader hooks are registered, perform the linking as synchronously as possible to reduce the chance of races from the the shared module loading cache.
1 parent af17d28 commit 0f01941

File tree

2 files changed

+18
-9
lines changed

2 files changed

+18
-9
lines changed

lib/internal/modules/esm/loader.js

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ let debug = require('internal/util/debuglog').debuglog('esm', (fn) => {
6565
debug = fn;
6666
});
6767

68+
const { isPromise } = require('internal/util/types');
69+
6870
/**
6971
* @typedef {import('./hooks.js').HooksProxy} HooksProxy
7072
* @typedef {import('./module_job.js').ModuleJobBase} ModuleJobBase
@@ -592,14 +594,21 @@ class ModuleLoader {
592594

593595
/**
594596
* Load a module and translate it into a ModuleWrap for ordinary imported ESM.
595-
* This is run asynchronously.
597+
* This may be run asynchronously if there are asynchronous module loader hooks registered.
596598
* @param {string} url URL of the module to be translated.
597599
* @param {object} loadContext See {@link load}
598600
* @param {boolean} isMain Whether the module to be translated is the entry point.
599-
* @returns {Promise<ModuleWrap>}
601+
* @returns {Promise<ModuleWrap>|ModuleWrap}
600602
*/
601-
async loadAndTranslate(url, loadContext, isMain) {
602-
const { format, source } = await this.load(url, loadContext);
603+
loadAndTranslate(url, loadContext, isMain) {
604+
const maybePromise = this.load(url, loadContext);
605+
if (isPromise(maybePromise)) {
606+
return maybePromise.then((loadResult) => {
607+
const { format, source } = loadResult;
608+
return this.#translate(url, format, source, isMain);
609+
});
610+
}
611+
const { format, source } = maybePromise;
603612
return this.#translate(url, format, source, isMain);
604613
}
605614

lib/internal/modules/esm/module_job.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ const {
3737
},
3838
} = internalBinding('util');
3939
const { decorateErrorStack, kEmptyObject } = require('internal/util');
40+
const { isPromise } = require('internal/util/types');
4041
const {
4142
getSourceMapsSupport,
4243
} = require('internal/source_map/source_map_cache');
@@ -138,12 +139,11 @@ class ModuleJob extends ModuleJobBase {
138139
this.#loader = loader;
139140

140141
// Expose the promise to the ModuleWrap directly for linking below.
141-
if (isForRequireInImportedCJS) {
142-
this.module = moduleOrModulePromise;
143-
assert(this.module instanceof ModuleWrap);
144-
this.modulePromise = PromiseResolve(this.module);
145-
} else {
142+
if (isPromise(moduleOrModulePromise)) {
146143
this.modulePromise = moduleOrModulePromise;
144+
} else {
145+
this.module = moduleOrModulePromise;
146+
this.modulePromise = PromiseResolve(moduleOrModulePromise);
147147
}
148148

149149
if (this.phase === kEvaluationPhase) {

0 commit comments

Comments
 (0)