@@ -18,6 +18,9 @@ const { |
18 | 18 | StringPrototypeSplit, |
19 | 19 | StringPrototypeStartsWith, |
20 | 20 | } = primordials; |
| 21 | +let debug = require('internal/util/debuglog').debuglog('esm', (fn) => { |
| 22 | + debug = fn; |
| 23 | +}); |
21 | 24 |
|
22 | 25 | const { ModuleWrap, kEvaluated } = internalBinding('module_wrap'); |
23 | 26 |
|
@@ -48,8 +51,7 @@ const isCommonJSGlobalLikeNotDefinedError = (errorMessage) => |
48 | 51 | ); |
49 | 52 |
|
50 | 53 | class ModuleJobBase { |
51 | | - constructor(loader, url, importAttributes, moduleWrapMaybePromise, isMain, inspectBrk) { |
52 | | - this.loader = loader; |
| 54 | + constructor(url, importAttributes, moduleWrapMaybePromise, isMain, inspectBrk) { |
53 | 55 | this.importAttributes = importAttributes; |
54 | 56 | this.isMain = isMain; |
55 | 57 | this.inspectBrk = inspectBrk; |
@@ -62,11 +64,13 @@ class ModuleJobBase { |
62 | 64 | /* A ModuleJob tracks the loading of a single Module, and the ModuleJobs of |
63 | 65 | * its dependencies, over time. */ |
64 | 66 | class ModuleJob extends ModuleJobBase { |
| 67 | + #loader = null; |
65 | 68 | // `loader` is the Loader instance used for loading dependencies. |
66 | 69 | constructor(loader, url, importAttributes = { __proto__: null }, |
67 | 70 | moduleProvider, isMain, inspectBrk, sync = false) { |
68 | 71 | const 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; |
70 | 74 | // Expose the promise to the ModuleWrap directly for linking below. |
71 | 75 | // `this.module` is also filled in below. |
72 | 76 | this.modulePromise = modulePromise; |
@@ -89,7 +93,8 @@ class ModuleJob extends ModuleJobBase { |
89 | 93 | // these `link` callbacks depending on each other. |
90 | 94 | const dependencyJobs = []; |
91 | 95 | const 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); |
93 | 98 | ArrayPrototypePush(dependencyJobs, job); |
94 | 99 | return job.modulePromise; |
95 | 100 | }); |
@@ -121,6 +126,8 @@ class ModuleJob extends ModuleJobBase { |
121 | 126 | async _instantiate() { |
122 | 127 | const jobsInGraph = new SafeSet(); |
123 | 128 | const addJobsToDependencyGraph = async (moduleJob) => { |
| 129 | + debug(`async addJobsToDependencyGraph() ${this.url}`, moduleJob); |
| 130 | + |
124 | 131 | if (jobsInGraph.has(moduleJob)) { |
125 | 132 | return; |
126 | 133 | } |
@@ -156,7 +163,7 @@ class ModuleJob extends ModuleJobBase { |
156 | 163 | const { 1: childSpecifier, 2: name } = RegExpPrototypeExec( |
157 | 164 | /module '(.*)' does not provide an export named '(.+)'/, |
158 | 165 | e.message); |
159 | | - const { url: childFileURL } = await this.loader.resolve( |
| 166 | + const { url: childFileURL } = await this.#loader.resolve( |
160 | 167 | childSpecifier, |
161 | 168 | parentFileUrl, |
162 | 169 | kEmptyObject, |
@@ -167,7 +174,7 @@ class ModuleJob extends ModuleJobBase { |
167 | 174 | // in the import attributes and some formats require them; but we only |
168 | 175 | // care about CommonJS for the purposes of this error message. |
169 | 176 | ({ format } = |
170 | | - await this.loader.load(childFileURL)); |
| 177 | + await this.#loader.load(childFileURL)); |
171 | 178 | } catch { |
172 | 179 | // Continue regardless of error. |
173 | 180 | } |
@@ -257,18 +264,27 @@ class ModuleJob extends ModuleJobBase { |
257 | 264 | // All the steps are ensured to be synchronous and it throws on instantiating |
258 | 265 | // an asynchronous graph. |
259 | 266 | class ModuleJobSync extends ModuleJobBase { |
| 267 | + #loader = null; |
260 | 268 | constructor(loader, url, importAttributes, moduleWrap, isMain, inspectBrk) { |
261 | | - super(loader, url, importAttributes, moduleWrap, isMain, inspectBrk, true); |
| 269 | + super(url, importAttributes, moduleWrap, isMain, inspectBrk, true); |
262 | 270 | assert(this.module instanceof ModuleWrap); |
| 271 | + this.#loader = loader; |
263 | 272 | const moduleRequests = this.module.getModuleRequestsSync(); |
| 273 | + const linked = []; |
264 | 274 | for (let i = 0; i < moduleRequests.length; ++i) { |
265 | 275 | const { 0: specifier, 1: attributes } = moduleRequests[i]; |
266 | | - const wrap = this.loader.getModuleWrapForRequire(specifier, url, attributes); |
| 276 | + const job = this.#loader.getModuleWrapForRequire(specifier, url, attributes); |
267 | 277 | const isLast = (i === moduleRequests.length - 1); |
268 | 278 | // TODO(joyeecheung): make the resolution callback deal with both promisified |
269 | 279 | // 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); |
271 | 282 | } |
| 283 | + this.linked = linked; |
| 284 | + } |
| 285 | + |
| 286 | + get modulePromise() { |
| 287 | + return PromiseResolve(this.module); |
272 | 288 | } |
273 | 289 |
|
274 | 290 | async run() { |
|