77} = primordials ;
88
99const {
10+ ERR_INVALID_ARG_VALUE ,
1011 ERR_INVALID_RETURN_PROPERTY ,
1112 ERR_INVALID_RETURN_PROPERTY_VALUE ,
1213 ERR_INVALID_RETURN_VALUE ,
@@ -47,6 +48,14 @@ class Loader {
4748 // Map of already-loaded CJS modules to use
4849 this . cjsCache = new SafeMap ( ) ;
4950
51+ // This hook is called before the first root module is imported. It's a
52+ // function that returns a piece of code that runs as a sloppy-mode script.
53+ // The script may evaluate to a function that can be called with a
54+ // `getBuiltin` helper that can be used to retrieve builtins.
55+ // If the hook returns `null` instead of a source string, it opts out of
56+ // running any preload code.
57+ // The preload code runs as soon as the hook module has finished evaluating.
58+ this . _getGlobalPreloadCode = null ;
5059 // The resolver has the signature
5160 // (specifier : string, parentURL : string, defaultResolve)
5261 // -> Promise<{ url : string }>
@@ -168,7 +177,16 @@ class Loader {
168177 return module . getNamespace ( ) ;
169178 }
170179
171- hook ( { resolve, dynamicInstantiate, getFormat, getSource, transformSource } ) {
180+ hook ( hooks ) {
181+ const {
182+ resolve,
183+ dynamicInstantiate,
184+ getFormat,
185+ getSource,
186+ transformSource,
187+ getGlobalPreloadCode,
188+ } = hooks ;
189+
172190 // Use .bind() to avoid giving access to the Loader instance when called.
173191 if ( resolve !== undefined )
174192 this . _resolve = FunctionPrototypeBind ( resolve , null ) ;
@@ -185,6 +203,37 @@ class Loader {
185203 if ( transformSource !== undefined ) {
186204 this . _transformSource = FunctionPrototypeBind ( transformSource , null ) ;
187205 }
206+ if ( getGlobalPreloadCode !== undefined ) {
207+ this . _getGlobalPreloadCode =
208+ FunctionPrototypeBind ( getGlobalPreloadCode , null ) ;
209+ }
210+ }
211+
212+ runGlobalPreloadCode ( ) {
213+ if ( ! this . _getGlobalPreloadCode ) {
214+ return ;
215+ }
216+ const preloadCode = this . _getGlobalPreloadCode ( ) ;
217+ if ( preloadCode === null ) {
218+ return ;
219+ }
220+
221+ if ( typeof preloadCode !== 'string' ) {
222+ throw new ERR_INVALID_RETURN_VALUE (
223+ 'string' , 'loader getGlobalPreloadCode' , preloadCode ) ;
224+ }
225+ const { compileFunction } = require ( 'vm' ) ;
226+ const preloadInit = compileFunction ( preloadCode , [ 'getBuiltin' ] , {
227+ filename : '<preload>' ,
228+ } ) ;
229+ const { NativeModule } = require ( 'internal/bootstrap/loaders' ) ;
230+
231+ preloadInit . call ( globalThis , ( builtinName ) => {
232+ if ( NativeModule . canBeRequiredByUsers ( builtinName ) ) {
233+ return require ( builtinName ) ;
234+ }
235+ throw new ERR_INVALID_ARG_VALUE ( 'builtinName' , builtinName ) ;
236+ } ) ;
188237 }
189238
190239 async getModuleJob ( specifier , parentURL ) {
0 commit comments