2
2
3
3
const {
4
4
ArrayIsArray,
5
+ ArrayPrototypePushApply,
5
6
} = primordials ;
6
7
7
8
const { ESMLoader } = require ( 'internal/modules/esm/loader' ) ;
8
9
const {
9
10
hasUncaughtExceptionCaptureCallback,
10
11
} = require ( 'internal/process/execution' ) ;
11
12
const { pathToFileURL } = require ( 'internal/url' ) ;
13
+ const { kEmptyObject } = require ( 'internal/util' ) ;
12
14
13
15
const esmLoader = new ESMLoader ( ) ;
14
16
exports . esmLoader = esmLoader ;
@@ -28,41 +30,61 @@ async function initializeLoader() {
28
30
const { getOptionValue } = require ( 'internal/options' ) ;
29
31
const customLoaders = getOptionValue ( '--experimental-loader' ) ;
30
32
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
+ }
32
59
33
60
// Hooks must then be added to external/public loader
34
61
// (so they're triggered in userland)
35
- esmLoader . addCustomLoaders ( loaders ) ;
62
+ esmLoader . addCustomLoaders ( allLoaders ) ;
63
+ esmLoader . preload ( ) ;
36
64
37
65
// Preload after loaders are added so they can be used
38
66
if ( preloadModules ?. length ) {
39
- await loadModulesInIsolation ( preloadModules , loaders ) ;
67
+ await loadModulesInIsolation ( parentURL , preloadModules , allLoaders ) ;
40
68
}
41
69
42
70
isESMInitialized = true ;
43
71
}
44
72
45
- function loadModulesInIsolation ( specifiers , loaders = [ ] ) {
73
+ function loadModulesInIsolation ( parentURL , specifiers , loaders = [ ] ) {
46
74
if ( ! ArrayIsArray ( specifiers ) || specifiers . length === 0 ) { return ; }
47
75
48
- let cwd ;
49
- try {
50
- cwd = process . cwd ( ) + '/' ;
51
- } catch {
52
- cwd = 'file:///' ;
53
- }
54
-
55
76
// A separate loader instance is necessary to avoid cross-contamination
56
77
// between internal Node.js and userland. For example, a module with internal
57
78
// state (such as a counter) should be independent.
58
79
const internalEsmLoader = new ESMLoader ( ) ;
59
80
internalEsmLoader . addCustomLoaders ( loaders ) ;
81
+ internalEsmLoader . preload ( ) ;
60
82
61
83
// Importation must be handled by internal loader to avoid poluting userland
62
84
return internalEsmLoader . import (
63
85
specifiers ,
64
- pathToFileURL ( cwd ) . href ,
65
- { __proto__ : null } ,
86
+ parentURL ,
87
+ kEmptyObject ,
66
88
) ;
67
89
}
68
90
0 commit comments