module: handle cached linked async jobs in require(esm) · nodejs/node@46b06be · GitHub
Skip to content

Commit 46b06be

Browse files
joyeecheungaduh95
authored andcommitted
module: handle cached linked async jobs in require(esm)
This handles two cases caused by using Promise.all() with multiple dynamic import() that can make an asynchronously linked module job that has finished/failed linking but has not yet started actual evaluation appear in the load cache when another require request is in turn to handle it. - When the cached async job has finished linking but has not started its evaluation because the async run() task would be later in line, start the evaluation from require() with runSync(). - When the cached async job have already encountered a linking error that gets wrapped into a rejection, but is still later in line to throw on it, just unwrap and throw the linking error from require(). PR-URL: #57187 Fixes: #57172 Refs: shufo/prettier-plugin-blade#311 Refs: https://github.com/fisker/prettier-plugin-blade-311 Refs: mochajs/mocha#5290 Refs: https://github.com/JoshuaKGoldberg/repros/tree/mocha-missing-module-cyclic Reviewed-By: Guy Bedford <guybedford@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
1 parent b402799 commit 46b06be

3 files changed

Lines changed: 114 additions & 49 deletions

File tree

lib/internal/modules/esm/loader.js

Lines changed: 65 additions & 21 deletions

lib/internal/modules/esm/module_job.js

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ let debug = require('internal/util/debuglog').debuglog('esm', (fn) => {
2222
debug = fn;
2323
});
2424

25-
const { ModuleWrap, kInstantiated } = internalBinding('module_wrap');
25+
const { ModuleWrap, kEvaluationPhase, kInstantiated } = internalBinding('module_wrap');
2626
const {
2727
privateSymbols: {
2828
entry_point_module_private_symbol,
@@ -246,19 +246,20 @@ class ModuleJob extends ModuleJobBase {
246246
}
247247
}
248248

249-
runSync() {
249+
runSync(parent) {
250+
assert(this.phase === kEvaluationPhase);
250251
assert(this.module instanceof ModuleWrap);
251252
if (this.instantiated !== undefined) {
252253
return { __proto__: null, module: this.module };
253254
}
254255

255256
this.module.instantiate();
256257
this.instantiated = PromiseResolve();
257-
const timeout = -1;
258-
const breakOnSigint = false;
259258
setHasStartedUserESMExecution();
260-
this.module.evaluate(timeout, breakOnSigint);
261-
return { __proto__: null, module: this.module };
259+
const filename = urlToFilename(this.url);
260+
const parentFilename = urlToFilename(parent?.filename);
261+
const namespace = this.module.evaluateSync(filename, parentFilename);
262+
return { __proto__: null, module: this.module, namespace };
262263
}
263264

264265
async run(isEntryPoint = false) {

src/module_wrap.cc

Lines changed: 42 additions & 22 deletions

0 commit comments

Comments
 (0)