@@ -38,7 +38,7 @@ const {
3838 forceDefaultLoader,
3939} = require ( 'internal/modules/esm/utils' ) ;
4040const { kImplicitTypeAttribute } = require ( 'internal/modules/esm/assert' ) ;
41- const { ModuleWrap, kEvaluating, kEvaluated } = internalBinding ( 'module_wrap' ) ;
41+ const { ModuleWrap, kEvaluating, kEvaluated, kEvaluationPhase , kSourcePhase } = internalBinding ( 'module_wrap' ) ;
4242const {
4343 urlToFilename,
4444} = require ( 'internal/modules/helpers' ) ;
@@ -236,8 +236,7 @@ class ModuleLoader {
236236 async executeModuleJob ( url , wrap , isEntryPoint = false ) {
237237 const { ModuleJob } = require ( 'internal/modules/esm/module_job' ) ;
238238 const module = await onImport . tracePromise ( async ( ) => {
239- const job = new ModuleJob (
240- this , url , undefined , wrap , false , false ) ;
239+ const job = new ModuleJob ( this , url , undefined , wrap , kEvaluationPhase , false , false ) ;
241240 this . loadCache . set ( url , undefined , job ) ;
242241 const { module } = await job . run ( isEntryPoint ) ;
243242 return module ;
@@ -273,11 +272,12 @@ class ModuleLoader {
273272 * @param {string } [parentURL] The URL of the module where the module request is initiated.
274273 * It's undefined if it's from the root module.
275274 * @param {ImportAttributes } importAttributes Attributes from the import statement or expression.
275+ * @param {number } phase Import phase.
276276 * @returns {Promise<ModuleJobBase> }
277277 */
278- async getModuleJobForImport ( specifier , parentURL , importAttributes ) {
278+ async getModuleJobForImport ( specifier , parentURL , importAttributes , phase ) {
279279 const resolveResult = await this . resolve ( specifier , parentURL , importAttributes ) ;
280- return this . #getJobFromResolveResult( resolveResult , parentURL , importAttributes , false ) ;
280+ return this . #getJobFromResolveResult( resolveResult , parentURL , importAttributes , phase , false ) ;
281281 }
282282
283283 /**
@@ -287,11 +287,12 @@ class ModuleLoader {
287287 * @param {string } specifier See {@link getModuleJobForImport}
288288 * @param {string } [parentURL] See {@link getModuleJobForImport}
289289 * @param {ImportAttributes } importAttributes See {@link getModuleJobForImport}
290+ * @param {number } phase Import phase.
290291 * @returns {Promise<ModuleJobBase> }
291292 */
292- getModuleJobForRequireInImportedCJS ( specifier , parentURL , importAttributes ) {
293+ getModuleJobForRequireInImportedCJS ( specifier , parentURL , importAttributes , phase ) {
293294 const resolveResult = this . resolveSync ( specifier , parentURL , importAttributes ) ;
294- return this . #getJobFromResolveResult( resolveResult , parentURL , importAttributes , true ) ;
295+ return this . #getJobFromResolveResult( resolveResult , parentURL , importAttributes , phase , true ) ;
295296 }
296297
297298 /**
@@ -300,16 +301,21 @@ class ModuleLoader {
300301 * @param {{ format: string, url: string } } resolveResult Resolved module request.
301302 * @param {string } [parentURL] See {@link getModuleJobForImport}
302303 * @param {ImportAttributes } importAttributes See {@link getModuleJobForImport}
304+ * @param {number } phase Import phase.
303305 * @param {boolean } isForRequireInImportedCJS Whether this is done for require() in imported CJS.
304306 * @returns {ModuleJobBase }
305307 */
306- #getJobFromResolveResult( resolveResult , parentURL , importAttributes , isForRequireInImportedCJS = false ) {
308+ #getJobFromResolveResult( resolveResult , parentURL , importAttributes , phase ,
309+ isForRequireInImportedCJS = false ) {
307310 const { url, format } = resolveResult ;
308311 const resolvedImportAttributes = resolveResult . importAttributes ?? importAttributes ;
309312 let job = this . loadCache . get ( url , resolvedImportAttributes . type ) ;
310313
311314 if ( job === undefined ) {
312- job = this . #createModuleJob( url , resolvedImportAttributes , parentURL , format , isForRequireInImportedCJS ) ;
315+ job = this . #createModuleJob( url , resolvedImportAttributes , phase , parentURL , format ,
316+ isForRequireInImportedCJS ) ;
317+ } else {
318+ job . ensurePhase ( phase ) ;
313319 }
314320
315321 return job ;
@@ -377,7 +383,7 @@ class ModuleLoader {
377383 const inspectBrk = ( isMain && getOptionValue ( '--inspect-brk' ) ) ;
378384
379385 const { ModuleJobSync } = require ( 'internal/modules/esm/module_job' ) ;
380- job = new ModuleJobSync ( this , url , kEmptyObject , wrap , isMain , inspectBrk ) ;
386+ job = new ModuleJobSync ( this , url , kEmptyObject , wrap , kEvaluationPhase , isMain , inspectBrk ) ;
381387 this . loadCache . set ( url , kImplicitTypeAttribute , job ) ;
382388 mod [ kRequiredModuleSymbol ] = job . module ;
383389 return { wrap : job . module , namespace : job . runSync ( parent ) . namespace } ;
@@ -389,9 +395,10 @@ class ModuleLoader {
389395 * @param {string } specifier Specifier of the the imported module.
390396 * @param {string } parentURL Where the import comes from.
391397 * @param {object } importAttributes import attributes from the import statement.
398+ * @param {number } phase The import phase.
392399 * @returns {ModuleJobBase }
393400 */
394- getModuleJobForRequire ( specifier , parentURL , importAttributes ) {
401+ getModuleJobForRequire ( specifier , parentURL , importAttributes , phase ) {
395402 const parsed = URLParse ( specifier ) ;
396403 if ( parsed != null ) {
397404 const protocol = parsed . protocol ;
@@ -422,6 +429,7 @@ class ModuleLoader {
422429 }
423430 throw new ERR_REQUIRE_CYCLE_MODULE ( message ) ;
424431 }
432+ job . ensurePhase ( phase ) ;
425433 // Otherwise the module could be imported before but the evaluation may be already
426434 // completed (e.g. the require call is lazy) so it's okay. We will return the
427435 // module now and check asynchronicity of the entire graph later, after the
@@ -463,7 +471,7 @@ class ModuleLoader {
463471
464472 const inspectBrk = ( isMain && getOptionValue ( '--inspect-brk' ) ) ;
465473 const { ModuleJobSync } = require ( 'internal/modules/esm/module_job' ) ;
466- job = new ModuleJobSync ( this , url , importAttributes , wrap , isMain , inspectBrk ) ;
474+ job = new ModuleJobSync ( this , url , importAttributes , wrap , phase , isMain , inspectBrk ) ;
467475
468476 this . loadCache . set ( url , importAttributes . type , job ) ;
469477 return job ;
@@ -543,13 +551,14 @@ class ModuleLoader {
543551 * by the time this returns. Otherwise it may still have pending module requests.
544552 * @param {string } url The URL that was resolved for this module.
545553 * @param {ImportAttributes } importAttributes See {@link getModuleJobForImport}
554+ * @param {number } phase Import phase.
546555 * @param {string } [parentURL] See {@link getModuleJobForImport}
547556 * @param {string } [format] The format hint possibly returned by the `resolve` hook
548557 * @param {boolean } isForRequireInImportedCJS Whether this module job is created for require()
549558 * in imported CJS.
550559 * @returns {ModuleJobBase } The (possibly pending) module job
551560 */
552- #createModuleJob( url , importAttributes , parentURL , format , isForRequireInImportedCJS ) {
561+ #createModuleJob( url , importAttributes , phase , parentURL , format , isForRequireInImportedCJS ) {
553562 const context = { format, importAttributes } ;
554563
555564 const isMain = parentURL === undefined ;
@@ -575,6 +584,7 @@ class ModuleLoader {
575584 url ,
576585 importAttributes ,
577586 moduleOrModulePromise ,
587+ phase ,
578588 isMain ,
579589 inspectBrk ,
580590 isForRequireInImportedCJS ,
@@ -592,11 +602,18 @@ class ModuleLoader {
592602 * @param {string } parentURL Path of the parent importing the module.
593603 * @param {Record<string, string> } importAttributes Validations for the
594604 * module import.
605+ * @param {number } [phase] The phase of the import.
606+ * @param {boolean } [isEntryPoint] Whether this is the realm-level entry point.
595607 * @returns {Promise<ModuleExports> }
596608 */
597- async import ( specifier , parentURL , importAttributes , isEntryPoint = false ) {
609+ async import ( specifier , parentURL , importAttributes , phase = kEvaluationPhase , isEntryPoint = false ) {
598610 return onImport . tracePromise ( async ( ) => {
599- const moduleJob = await this . getModuleJobForImport ( specifier , parentURL , importAttributes ) ;
611+ const moduleJob = await this . getModuleJobForImport ( specifier , parentURL , importAttributes ,
612+ phase ) ;
613+ if ( phase === kSourcePhase ) {
614+ const module = await moduleJob . modulePromise ;
615+ return module . getModuleSourceObject ( ) ;
616+ }
600617 const { module } = await moduleJob . run ( isEntryPoint ) ;
601618 return module . getNamespace ( ) ;
602619 } , {
0 commit comments