22
33const {
44 ArrayIsArray,
5+ ArrayPrototypePushApply,
56} = primordials ;
67
78const { ESMLoader } = require ( 'internal/modules/esm/loader' ) ;
89const {
910 hasUncaughtExceptionCaptureCallback,
1011} = require ( 'internal/process/execution' ) ;
1112const { pathToFileURL } = require ( 'internal/url' ) ;
13+ const { kEmptyObject } = require ( 'internal/util' ) ;
1214
1315const esmLoader = new ESMLoader ( ) ;
1416exports . esmLoader = esmLoader ;
@@ -28,41 +30,61 @@ async function initializeLoader() {
2830 const { getOptionValue } = require ( 'internal/options' ) ;
2931 const customLoaders = getOptionValue ( '--experimental-loader' ) ;
3032 const preloadModules = getOptionValue ( '--import' ) ;
31- const loaders = await loadModulesInIsolation ( customLoaders ) ;
33+
34+ let cwd ;
35+ try {
36+ cwd = process . cwd ( ) + '/' ;
37+ } catch {
38+ cwd = '/' ;
39+ }
40+
41+ const internalEsmLoader = new ESMLoader ( ) ;
42+ const allLoaders = [ ] ;
43+
44+ const parentURL = pathToFileURL ( cwd ) . href ;
45+
46+ for ( let i = 0 ; i < customLoaders . length ; i ++ ) {
47+ const customLoader = customLoaders [ i ] ;
48+
49+ // Importation must be handled by internal loader to avoid polluting user-land
50+ const keyedExportsSublist = await internalEsmLoader . import (
51+ [ customLoader ] ,
52+ parentURL ,
53+ kEmptyObject ,
54+ ) ;
55+
56+ internalEsmLoader . addCustomLoaders ( keyedExportsSublist ) ;
57+ ArrayPrototypePushApply ( allLoaders , keyedExportsSublist ) ;
58+ }
3259
3360 // Hooks must then be added to external/public loader
3461 // (so they're triggered in userland)
35- esmLoader . addCustomLoaders ( loaders ) ;
62+ esmLoader . addCustomLoaders ( allLoaders ) ;
63+ esmLoader . preload ( ) ;
3664
3765 // Preload after loaders are added so they can be used
3866 if ( preloadModules ?. length ) {
39- await loadModulesInIsolation ( preloadModules , loaders ) ;
67+ await loadModulesInIsolation ( parentURL , preloadModules , allLoaders ) ;
4068 }
4169
4270 isESMInitialized = true ;
4371}
4472
45- function loadModulesInIsolation ( specifiers , loaders = [ ] ) {
73+ function loadModulesInIsolation ( parentURL , specifiers , loaders = [ ] ) {
4674 if ( ! ArrayIsArray ( specifiers ) || specifiers . length === 0 ) { return ; }
4775
48- let cwd ;
49- try {
50- cwd = process . cwd ( ) + '/' ;
51- } catch {
52- cwd = 'file:///' ;
53- }
54-
5576 // A separate loader instance is necessary to avoid cross-contamination
5677 // between internal Node.js and userland. For example, a module with internal
5778 // state (such as a counter) should be independent.
5879 const internalEsmLoader = new ESMLoader ( ) ;
5980 internalEsmLoader . addCustomLoaders ( loaders ) ;
81+ internalEsmLoader . preload ( ) ;
6082
6183 // Importation must be handled by internal loader to avoid poluting userland
6284 return internalEsmLoader . import (
6385 specifiers ,
64- pathToFileURL ( cwd ) . href ,
65- { __proto__ : null } ,
86+ parentURL ,
87+ kEmptyObject ,
6688 ) ;
6789}
6890
0 commit comments