diff --git a/lib/internal/modules/esm/loader.js b/lib/internal/modules/esm/loader.js index de08845a820d77..f9e8a99689cea1 100644 --- a/lib/internal/modules/esm/loader.js +++ b/lib/internal/modules/esm/loader.js @@ -134,6 +134,29 @@ class Loader { return format; } + async getSource(url, format) { + const getSourceResponse = await this._getSource( + url, { format: format }, defaultGetSource); + if (typeof getSourceResponse !== 'object') { + throw new ERR_INVALID_RETURN_VALUE( + 'object', 'loader getSource', getSourceResponse); + } + + const { source } = getSourceResponse; + + // Validate optional format that getSource can return + ({ format } = getSourceResponse); + if (typeof format !== 'string' && typeof format !== 'undefined') { + throw new ERR_INVALID_RETURN_PROPERTY_VALUE( + 'string', 'loader getSource', 'format', format); + } + + return { + source: source, + format: format + }; + } + async eval( source, url = pathToFileURL(`${process.cwd()}/[eval${++this.evalIndex}]`).href @@ -224,7 +247,15 @@ class Loader { async getModuleJob(specifier, parentURL) { const url = await this.resolve(specifier, parentURL); - const format = await this.getFormat(url); + let format = await this.getFormat(url); + let source; + if (format !== 'builtin' && + format !== 'commonjs' && + translators.get(format)) { + const sourceObj = await this.getSource(url, format); + ({ source } = sourceObj); + format = sourceObj.format ? sourceObj.format : format; + } let job = this.moduleMap.get(url); // CommonJS will set functions for lazy job evaluation. if (typeof job === 'function') @@ -239,8 +270,13 @@ class Loader { const inspectBrk = parentURL === undefined && format === 'module' && getOptionValue('--inspect-brk'); - job = new ModuleJob(this, url, loaderInstance, parentURL === undefined, - inspectBrk); + job = new ModuleJob( + this, + url, + loaderInstance, + source, + parentURL === undefined, + inspectBrk); this.moduleMap.set(url, job); return job; } diff --git a/lib/internal/modules/esm/module_job.js b/lib/internal/modules/esm/module_job.js index 4ffa8db9dab903..131b06d092f2e4 100644 --- a/lib/internal/modules/esm/module_job.js +++ b/lib/internal/modules/esm/module_job.js @@ -27,7 +27,7 @@ let hasPausedEntry = false; class ModuleJob { // `loader` is the Loader instance used for loading dependencies. // `moduleProvider` is a function - constructor(loader, url, moduleProvider, isMain, inspectBrk) { + constructor(loader, url, moduleProvider, source, isMain, inspectBrk) { this.loader = loader; this.isMain = isMain; this.inspectBrk = inspectBrk; @@ -35,8 +35,7 @@ class ModuleJob { this.module = undefined; // Expose the promise to the ModuleWrap directly for linking below. // `this.module` is also filled in below. - this.modulePromise = moduleProvider.call(loader, url, isMain); - + this.modulePromise = moduleProvider.call(loader, url, source, isMain); // Wait for the ModuleWrap instance being linked with all dependencies. const link = async () => { this.module = await this.modulePromise; diff --git a/lib/internal/modules/esm/translators.js b/lib/internal/modules/esm/translators.js index bb3528eddde964..2298e56be8a5c4 100644 --- a/lib/internal/modules/esm/translators.js +++ b/lib/internal/modules/esm/translators.js @@ -23,8 +23,6 @@ const { } = require('internal/modules/cjs/helpers'); const CJSModule = require('internal/modules/cjs/loader').Module; const internalURLModule = require('internal/url'); -const { defaultGetSource } = require( - 'internal/modules/esm/get_source'); const { defaultTransformSource } = require( 'internal/modules/esm/transform_source'); const createDynamicModule = require( @@ -110,9 +108,7 @@ function initializeImportMeta(meta, { url }) { } // Strategy for loading a standard JavaScript module -translators.set('module', async function moduleStrategy(url) { - let { source } = await this._getSource( - url, { format: 'module' }, defaultGetSource); +translators.set('module', async function moduleStrategy(url, source) { assertBufferSource(source, true, 'getSource'); ({ source } = await this._transformSource( source, { url, format: 'module' }, defaultTransformSource)); @@ -130,7 +126,7 @@ translators.set('module', async function moduleStrategy(url) { // Strategy for loading a node-style CommonJS module const isWindows = process.platform === 'win32'; const winSepRegEx = /\//g; -translators.set('commonjs', function commonjsStrategy(url, isMain) { +translators.set('commonjs', function commonjsStrategy(url, source, isMain) { debug(`Translating CJSModule ${url}`); const pathname = internalURLModule.fileURLToPath(new URL(url)); const cached = this.cjsCache.get(url); @@ -171,7 +167,7 @@ translators.set('builtin', async function builtinStrategy(url) { }); // Strategy for loading a JSON file -translators.set('json', async function jsonStrategy(url) { +translators.set('json', async function jsonStrategy(url, source) { emitExperimentalWarning('Importing JSON modules'); debug(`Translating JSONModule ${url}`); debug(`Loading JSONModule ${url}`); @@ -189,8 +185,6 @@ translators.set('json', async function jsonStrategy(url) { }); } } - let { source } = await this._getSource( - url, { format: 'json' }, defaultGetSource); assertBufferSource(source, true, 'getSource'); ({ source } = await this._transformSource( source, { url, format: 'json' }, defaultTransformSource)); @@ -231,10 +225,8 @@ translators.set('json', async function jsonStrategy(url) { }); // Strategy for loading a wasm module -translators.set('wasm', async function(url) { +translators.set('wasm', async function(url, source) { emitExperimentalWarning('Importing Web Assembly modules'); - let { source } = await this._getSource( - url, { format: 'wasm' }, defaultGetSource); assertBufferSource(source, false, 'getSource'); ({ source } = await this._transformSource( source, { url, format: 'wasm' }, defaultTransformSource)); diff --git a/test/message/esm_display_syntax_error_module.out b/test/message/esm_display_syntax_error_module.out index 708257fcaf5792..6da4c379ccfa15 100644 --- a/test/message/esm_display_syntax_error_module.out +++ b/test/message/esm_display_syntax_error_module.out @@ -3,4 +3,5 @@ await async () => 0; ^^^^^ SyntaxError: Unexpected reserved word - at Loader.moduleStrategy (internal/modules/esm/translators.js:*:*) \ No newline at end of file + at Loader.moduleStrategy (internal/modules/esm/translators.js:*:*) + at async link (internal/modules/esm/module_job.js:*:*) \ No newline at end of file