module: fix submodules loaded by require() and import() · nodejs/node@7625dc4
@@ -18,6 +18,9 @@ const {
1818 StringPrototypeSplit,
1919 StringPrototypeStartsWith,
2020} = primordials;
21+let debug = require('internal/util/debuglog').debuglog('esm', (fn) => {
22+debug = fn;
23+});
21242225const { ModuleWrap, kEvaluated } = internalBinding('module_wrap');
2326@@ -48,8 +51,7 @@ const isCommonJSGlobalLikeNotDefinedError = (errorMessage) =>
4851);
49525053class ModuleJobBase {
51-constructor(loader, url, importAttributes, moduleWrapMaybePromise, isMain, inspectBrk) {
52-this.loader = loader;
54+constructor(url, importAttributes, moduleWrapMaybePromise, isMain, inspectBrk) {
5355this.importAttributes = importAttributes;
5456this.isMain = isMain;
5557this.inspectBrk = inspectBrk;
@@ -62,11 +64,13 @@ class ModuleJobBase {
6264/* A ModuleJob tracks the loading of a single Module, and the ModuleJobs of
6365 * its dependencies, over time. */
6466class ModuleJob extends ModuleJobBase {
67+ #loader = null;
6568// `loader` is the Loader instance used for loading dependencies.
6669constructor(loader, url, importAttributes = { __proto__: null },
6770moduleProvider, isMain, inspectBrk, sync = false) {
6871const modulePromise = ReflectApply(moduleProvider, loader, [url, isMain]);
69-super(loader, url, importAttributes, modulePromise, isMain, inspectBrk);
72+super(url, importAttributes, modulePromise, isMain, inspectBrk);
73+this.#loader = loader;
7074// Expose the promise to the ModuleWrap directly for linking below.
7175// `this.module` is also filled in below.
7276this.modulePromise = modulePromise;
@@ -89,7 +93,8 @@ class ModuleJob extends ModuleJobBase {
8993// these `link` callbacks depending on each other.
9094const dependencyJobs = [];
9195const promises = this.module.link(async (specifier, attributes) => {
92-const job = await this.loader.getModuleJob(specifier, url, attributes);
96+const job = await this.#loader.getModuleJob(specifier, url, attributes);
97+debug(`async link() ${this.url} -> ${specifier}`, job);
9398ArrayPrototypePush(dependencyJobs, job);
9499return job.modulePromise;
95100});
@@ -121,6 +126,8 @@ class ModuleJob extends ModuleJobBase {
121126async _instantiate() {
122127const jobsInGraph = new SafeSet();
123128const addJobsToDependencyGraph = async (moduleJob) => {
129+debug(`async addJobsToDependencyGraph() ${this.url}`, moduleJob);
130+124131if (jobsInGraph.has(moduleJob)) {
125132return;
126133}
@@ -156,7 +163,7 @@ class ModuleJob extends ModuleJobBase {
156163const { 1: childSpecifier, 2: name } = RegExpPrototypeExec(
157164/module '(.*)' does not provide an export named '(.+)'/,
158165e.message);
159-const { url: childFileURL } = await this.loader.resolve(
166+const { url: childFileURL } = await this.#loader.resolve(
160167childSpecifier,
161168parentFileUrl,
162169kEmptyObject,
@@ -167,7 +174,7 @@ class ModuleJob extends ModuleJobBase {
167174// in the import attributes and some formats require them; but we only
168175// care about CommonJS for the purposes of this error message.
169176({ format } =
170-await this.loader.load(childFileURL));
177+await this.#loader.load(childFileURL));
171178} catch {
172179// Continue regardless of error.
173180}
@@ -257,18 +264,27 @@ class ModuleJob extends ModuleJobBase {
257264// All the steps are ensured to be synchronous and it throws on instantiating
258265// an asynchronous graph.
259266class ModuleJobSync extends ModuleJobBase {
267+ #loader = null;
260268constructor(loader, url, importAttributes, moduleWrap, isMain, inspectBrk) {
261-super(loader, url, importAttributes, moduleWrap, isMain, inspectBrk, true);
269+super(url, importAttributes, moduleWrap, isMain, inspectBrk, true);
262270assert(this.module instanceof ModuleWrap);
271+this.#loader = loader;
263272const moduleRequests = this.module.getModuleRequestsSync();
273+const linked = [];
264274for (let i = 0; i < moduleRequests.length; ++i) {
265275const { 0: specifier, 1: attributes } = moduleRequests[i];
266-const wrap = this.loader.getModuleWrapForRequire(specifier, url, attributes);
276+const job = this.#loader.getModuleWrapForRequire(specifier, url, attributes);
267277const isLast = (i === moduleRequests.length - 1);
268278// TODO(joyeecheung): make the resolution callback deal with both promisified
269279// an raw module wraps, then we don't need to wrap it with a promise here.
270-this.module.cacheResolvedWrapsSync(specifier, PromiseResolve(wrap), isLast);
280+this.module.cacheResolvedWrapsSync(specifier, PromiseResolve(job.module), isLast);
281+ArrayPrototypePush(linked, job);
271282}
283+this.linked = linked;
284+}
285+286+get modulePromise() {
287+return PromiseResolve(this.module);
272288}
273289274290async run() {