@@ -11,16 +11,18 @@ const {
1111} = primordials ;
1212
1313const {
14- ERR_ESM_LOADER_REGISTRATION_UNAVAILABLE ,
1514 ERR_UNKNOWN_MODULE_FORMAT ,
1615} = require ( 'internal/errors' ) . codes ;
1716const { getOptionValue } = require ( 'internal/options' ) ;
1817const { pathToFileURL } = require ( 'internal/url' ) ;
19- const { emitExperimentalWarning } = require ( 'internal/util' ) ;
18+ const { emitExperimentalWarning, kEmptyObject } = require ( 'internal/util' ) ;
2019const {
2120 getDefaultConditions,
2221} = require ( 'internal/modules/esm/utils' ) ;
2322let defaultResolve , defaultLoad , importMetaInitializer ;
23+ let debug = require ( 'internal/util/debuglog' ) . debuglog ( 'esm' , ( fn ) => {
24+ debug = fn ;
25+ } ) ;
2426
2527function newModuleMap ( ) {
2628 const ModuleMap = require ( 'internal/modules/esm/module_map' ) ;
@@ -106,15 +108,15 @@ class DefaultModuleLoader {
106108 setCallbackForWrap ( module , {
107109 initializeImportMeta : ( meta , wrap ) => this . importMetaInitialize ( meta , { url } ) ,
108110 importModuleDynamically : ( specifier , { url } , importAssertions ) => {
111+ debug ( 'importModuleDynamically: %o' , { specifier, url, Loader : this . constructor . name } ) ;
109112 return this . import ( specifier , url , importAssertions ) ;
110113 } ,
111114 } ) ;
112115
113116 return module ;
114117 } ;
115118 const ModuleJob = require ( 'internal/modules/esm/module_job' ) ;
116- const job = new ModuleJob (
117- this , url , undefined , evalInstance , false , false ) ;
119+ const job = new ModuleJob ( this , url , undefined , evalInstance , false , false ) ;
118120 this . moduleMap . set ( url , undefined , job ) ;
119121 const { module } = await job . run ( ) ;
120122
@@ -285,10 +287,21 @@ class CustomizedModuleLoader extends DefaultModuleLoader {
285287 /**
286288 * Instantiate a module loader that uses user-provided custom loader hooks.
287289 */
288- constructor ( ) {
290+ constructor ( {
291+ cjsCache,
292+ evalIndex,
293+ moduleMap,
294+ } = kEmptyObject ) {
289295 super ( ) ;
290296
291- getHooksProxy ( ) ;
297+ if ( cjsCache != null ) { this . cjsCache = cjsCache ; }
298+ if ( evalIndex != null ) { this . evalIndex = evalIndex ; }
299+ if ( moduleMap != null ) { this . moduleMap = moduleMap ; }
300+
301+ if ( ! hooksProxy ) {
302+ const { HooksProxy } = require ( 'internal/modules/esm/hooks' ) ;
303+ hooksProxy = new HooksProxy ( ) ;
304+ }
292305 }
293306
294307 /**
@@ -357,40 +370,29 @@ let emittedExperimentalWarning = false;
357370 * A loader instance is used as the main entry point for loading ES modules. Currently, this is a singleton; there is
358371 * only one used for loading the main module and everything in its dependency graph, though separate instances of this
359372 * class might be instantiated as part of bootstrap for other purposes.
360- * @param {boolean } useCustomLoadersIfPresent If the user has provided loaders via the --loader flag, use them.
373+ * @param {boolean } forceCustomizedLoaderInMain Ignore whether custom loader(s) have been provided
374+ * via CLI and instantiate a CustomizedModuleLoader instance regardless.
361375 * @returns {DefaultModuleLoader | CustomizedModuleLoader }
362376 */
363- function createModuleLoader ( useCustomLoadersIfPresent = true ) {
364- if ( useCustomLoadersIfPresent &&
365- // Don't spawn a new worker if we're already in a worker thread created by instantiating CustomizedModuleLoader;
366- // doing so would cause an infinite loop.
367- ! require ( 'internal/modules/esm/utils' ) . isLoaderWorker ( ) ) {
368- const userLoaderPaths = getOptionValue ( '--experimental-loader' ) ;
369- if ( userLoaderPaths . length > 0 ) {
377+ function createModuleLoader ( customizationSetup ) {
378+ // Don't spawn a new worker if we're already in a worker thread (doing so would cause an infinite loop).
379+ if ( ! require ( 'internal/modules/esm/utils' ) . isLoaderWorker ( ) ) {
380+ if (
381+ customizationSetup ||
382+ getOptionValue ( '--experimental-loader' ) . length > 0
383+ ) {
370384 if ( ! emittedExperimentalWarning ) {
371385 emitExperimentalWarning ( 'Custom ESM Loaders' ) ;
372386 emittedExperimentalWarning = true ;
373387 }
374- return new CustomizedModuleLoader ( ) ;
388+ debug ( 'instantiating CustomizedModuleLoader' ) ;
389+ return new CustomizedModuleLoader ( customizationSetup ) ;
375390 }
376391 }
377392
378393 return new DefaultModuleLoader ( ) ;
379394}
380395
381- /**
382- * Get the HooksProxy instance. If it is not defined, then create a new one.
383- * @returns {HooksProxy }
384- */
385- function getHooksProxy ( ) {
386- if ( ! hooksProxy ) {
387- const { HooksProxy } = require ( 'internal/modules/esm/hooks' ) ;
388- hooksProxy = new HooksProxy ( ) ;
389- }
390-
391- return hooksProxy ;
392- }
393-
394396/**
395397 * Register a single loader programmatically.
396398 * @param {string } specifier
@@ -405,19 +407,19 @@ function getHooksProxy() {
405407 * ```
406408 */
407409function register ( specifier , parentURL = 'data:' ) {
408- // TODO: Remove this limitation in a follow-up before `register` is released publicly
409- if ( getOptionValue ( '--experimental-loader' ) . length < 1 ) {
410- throw new ERR_ESM_LOADER_REGISTRATION_UNAVAILABLE ( ) ;
411- }
410+ let moduleLoader = require ( 'internal/process/esm_loader' ) . esmLoader ;
412411
413- const moduleLoader = require ( 'internal/process/esm_loader' ) . esmLoader ;
412+ if ( ! ( moduleLoader instanceof CustomizedModuleLoader ) ) {
413+ debug ( 'register called on DefaultModuleLoader; switching to CustomizedModuleLoader' ) ;
414+ moduleLoader = createModuleLoader ( moduleLoader ) ;
415+ require ( 'internal/process/esm_loader' ) . esmLoader = moduleLoader ;
416+ }
414417
415418 moduleLoader . register ( `${ specifier } ` , parentURL ) ;
416419}
417420
418421module . exports = {
419422 DefaultModuleLoader,
420423 createModuleLoader,
421- getHooksProxy,
422424 register,
423425} ;
0 commit comments