module: cache synchronous module jobs before linking · nodejs/node@30ed93d
@@ -287,22 +287,33 @@ class ModuleJobSync extends ModuleJobBase {
287287 #loader = null;
288288constructor(loader, url, importAttributes, moduleWrap, isMain, inspectBrk) {
289289super(url, importAttributes, moduleWrap, isMain, inspectBrk, true);
290-assert(this.module instanceof ModuleWrap);
291290this.#loader = loader;
292-const moduleRequests = this.module.getModuleRequests();
293-// Specifiers should be aligned with the moduleRequests array in order.
294-const specifiers = Array(moduleRequests.length);
295-const modules = Array(moduleRequests.length);
296-const jobs = Array(moduleRequests.length);
297-for (let i = 0; i < moduleRequests.length; ++i) {
298-const { specifier, attributes } = moduleRequests[i];
299-const job = this.#loader.getModuleJobForRequire(specifier, url, attributes);
300-specifiers[i] = specifier;
301-modules[i] = job.module;
302-jobs[i] = job;
291+292+assert(this.module instanceof ModuleWrap);
293+// Store itself into the cache first before linking in case there are circular
294+// references in the linking.
295+loader.loadCache.set(url, importAttributes.type, this);
296+297+try {
298+const moduleRequests = this.module.getModuleRequests();
299+// Specifiers should be aligned with the moduleRequests array in order.
300+const specifiers = Array(moduleRequests.length);
301+const modules = Array(moduleRequests.length);
302+const jobs = Array(moduleRequests.length);
303+for (let i = 0; i < moduleRequests.length; ++i) {
304+const { specifier, attributes } = moduleRequests[i];
305+const job = this.#loader.getModuleJobForRequire(specifier, url, attributes);
306+specifiers[i] = specifier;
307+modules[i] = job.module;
308+jobs[i] = job;
309+}
310+this.module.link(specifiers, modules);
311+this.linked = jobs;
312+} finally {
313+// Restore it - if it succeeds, we'll reset in the caller; Otherwise it's
314+// not cached and if the error is caught, subsequent attempt would still fail.
315+loader.loadCache.delete(url, importAttributes.type);
303316}
304-this.module.link(specifiers, modules);
305-this.linked = jobs;
306317}
307318308319get modulePromise() {