diff --git a/lib/internal/modules/esm/module_job.js b/lib/internal/modules/esm/module_job.js index c8506b42ff3..7fa2347db12 100644 --- a/lib/internal/modules/esm/module_job.js +++ b/lib/internal/modules/esm/module_job.js @@ -10,6 +10,7 @@ const { ArrayPrototypeSort, FunctionPrototype, ObjectAssign, + ObjectFreeze, ObjectSetPrototypeOf, PromisePrototypeThen, PromiseResolve, @@ -61,6 +62,9 @@ const { } = require('internal/modules/helpers'); const { getOptionValue } = require('internal/options'); const noop = FunctionPrototype; +// Module jobs retain both `linked` and `commonJsDeps`. Share their empty value +// so leaf modules do not each retain two arrays. +const kEmptyModuleDependencies = ObjectFreeze([]); const { ERR_REQUIRE_ASYNC_MODULE, ERR_REQUIRE_ESM_RACE_CONDITION, @@ -296,9 +300,7 @@ class ModuleJobBase { constructor(loader, url, importAttributes, phase, isMain, inspectBrk) { assert(typeof phase === 'number'); this.loader = loader; - this.importAttributes = importAttributes; this.phase = phase; - this.isMain = isMain; this.inspectBrk = inspectBrk; this.url = url; @@ -317,9 +319,12 @@ class ModuleJobBase { this.loader.loadCache.set(this.url, this.type, this); const moduleRequests = this.module.getModuleRequests(); // Modules should be aligned with the moduleRequests array in order. - const modules = Array(moduleRequests.length); - const evaluationDepJobs = []; - this.commonJsDeps = Array(moduleRequests.length); + const modules = moduleRequests.length === 0 ? + kEmptyModuleDependencies : Array(moduleRequests.length); + const evaluationDepJobs = moduleRequests.length === 0 ? + kEmptyModuleDependencies : []; + this.commonJsDeps = moduleRequests.length === 0 ? + kEmptyModuleDependencies : Array(moduleRequests.length); try { for (let idx = 0; idx < moduleRequests.length; idx++) { const request = moduleRequests[idx]; @@ -402,7 +407,7 @@ class ModuleJob extends ModuleJobBase { * first line paused in the debugger (because --inspect-brk is passed). * @param {ModuleRequestType} requestType Type of the module request. */ - constructor(loader, url, importAttributes = { __proto__: null }, moduleOrModulePromise, + constructor(loader, url, importAttributes, moduleOrModulePromise, phase = kEvaluationPhase, isMain, inspectBrk, requestType) { super(loader, url, importAttributes, phase, isMain, inspectBrk); @@ -452,9 +457,12 @@ class ModuleJob extends ModuleJobBase { // Create an ArrayLike to avoid calling into userspace with `.then` // when returned from the async function. // Modules should be aligned with the moduleRequests array in order. - const modulePromises = Array(moduleRequests.length); - const evaluationDepJobs = []; - this.commonJsDeps = Array(moduleRequests.length); + const modulePromises = moduleRequests.length === 0 ? + kEmptyModuleDependencies : Array(moduleRequests.length); + const evaluationDepJobs = moduleRequests.length === 0 ? + kEmptyModuleDependencies : []; + this.commonJsDeps = moduleRequests.length === 0 ? + kEmptyModuleDependencies : Array(moduleRequests.length); for (let idx = 0; idx < moduleRequests.length; idx++) { const request = moduleRequests[idx]; // Explicitly keeping track of dependency jobs is needed in order