@@ -13,12 +13,18 @@ const {
1313 } ,
1414} = internalBinding ( 'util' ) ;
1515const {
16+ source_text_module_default_hdo,
1617 vm_dynamic_import_default_internal,
1718 vm_dynamic_import_main_context_default,
1819 vm_dynamic_import_missing_flag,
1920 vm_dynamic_import_no_callback,
2021} = internalBinding ( 'symbols' ) ;
2122
23+ const { ModuleWrap } = internalBinding ( 'module_wrap' ) ;
24+ const {
25+ maybeCacheSourceMap,
26+ } = require ( 'internal/source_map/source_map_cache' ) ;
27+
2228const {
2329 ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING_FLAG ,
2430 ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING ,
@@ -167,28 +173,55 @@ function registerModule(referrer, registry) {
167173 moduleRegistries . set ( idSymbol , registry ) ;
168174}
169175
176+ /**
177+ * Proxy the import meta handling to the default loader for source text modules.
178+ * @param {Record<string, string | Function> } meta - The import.meta object to initialize.
179+ * @param {ModuleWrap } wrap - The ModuleWrap of the SourceTextModule where `import.meta` is referenced.
180+ */
181+ function defaultInitializeImportMetaForModule ( meta , wrap ) {
182+ const cascadedLoader = require ( 'internal/modules/esm/loader' ) . getOrInitializeCascadedLoader ( ) ;
183+ return cascadedLoader . importMetaInitialize ( meta , { url : wrap . url } ) ;
184+ }
185+
170186/**
171187 * Defines the `import.meta` object for a given module.
172188 * @param {symbol } symbol - Reference to the module.
173189 * @param {Record<string, string | Function> } meta - The import.meta object to initialize.
190+ * @param {ModuleWrap } wrap - The ModuleWrap of the SourceTextModule where `import.meta` is referenced.
174191 */
175- function initializeImportMetaObject ( symbol , meta ) {
176- if ( moduleRegistries . has ( symbol ) ) {
177- const { initializeImportMeta, callbackReferrer } = moduleRegistries . get ( symbol ) ;
178- if ( initializeImportMeta !== undefined ) {
179- meta = initializeImportMeta ( meta , callbackReferrer ) ;
180- }
192+ function initializeImportMetaObject ( symbol , meta , wrap ) {
193+ if ( symbol === source_text_module_default_hdo ) {
194+ defaultInitializeImportMetaForModule ( meta , wrap ) ;
195+ return ;
196+ }
197+ const data = moduleRegistries . get ( symbol ) ;
198+ assert ( data , `import.meta registry not found for ${ wrap . url } ` ) ;
199+ const { initializeImportMeta, callbackReferrer } = data ;
200+ if ( initializeImportMeta !== undefined ) {
201+ meta = initializeImportMeta ( meta , callbackReferrer ) ;
181202 }
182203}
183204
184205/**
185- * Proxy the dynamic import to the default loader.
206+ * Proxy the dynamic import handling to the default loader for source text modules.
207+ * @param {string } specifier - The module specifier string.
208+ * @param {Record<string, string> } attributes - The import attributes object.
209+ * @param {string|null|undefined } referrerName - name of the referrer.
210+ * @returns {Promise<import('internal/modules/esm/loader.js').ModuleExports> } - The imported module object.
211+ */
212+ function defaultImportModuleDynamicallyForModule ( specifier , attributes , referrerName ) {
213+ const cascadedLoader = require ( 'internal/modules/esm/loader' ) . getOrInitializeCascadedLoader ( ) ;
214+ return cascadedLoader . import ( specifier , referrerName , attributes ) ;
215+ }
216+
217+ /**
218+ * Proxy the dynamic import to the default loader for classic scripts.
186219 * @param {string } specifier - The module specifier string.
187220 * @param {Record<string, string> } attributes - The import attributes object.
188221 * @param {string|null|undefined } referrerName - name of the referrer.
189222 * @returns {Promise<import('internal/modules/esm/loader.js').ModuleExports> } - The imported module object.
190223 */
191- function defaultImportModuleDynamically ( specifier , attributes , referrerName ) {
224+ function defaultImportModuleDynamicallyForScript ( specifier , attributes , referrerName ) {
192225 const parentURL = normalizeReferrerURL ( referrerName ) ;
193226 const cascadedLoader = require ( 'internal/modules/esm/loader' ) . getOrInitializeCascadedLoader ( ) ;
194227 return cascadedLoader . import ( specifier , parentURL , attributes ) ;
@@ -208,12 +241,16 @@ async function importModuleDynamicallyCallback(referrerSymbol, specifier, attrib
208241 // and fall back to the default loader.
209242 if ( referrerSymbol === vm_dynamic_import_main_context_default ) {
210243 emitExperimentalWarning ( 'vm.USE_MAIN_CONTEXT_DEFAULT_LOADER' ) ;
211- return defaultImportModuleDynamically ( specifier , attributes , referrerName ) ;
244+ return defaultImportModuleDynamicallyForScript ( specifier , attributes , referrerName ) ;
212245 }
213246 // For script compiled internally that should use the default loader to handle dynamic
214247 // import, proxy the request to the default loader without the warning.
215248 if ( referrerSymbol === vm_dynamic_import_default_internal ) {
216- return defaultImportModuleDynamically ( specifier , attributes , referrerName ) ;
249+ return defaultImportModuleDynamicallyForScript ( specifier , attributes , referrerName ) ;
250+ }
251+ // For SourceTextModules compiled internally, proxy the request to the default loader.
252+ if ( referrerSymbol === source_text_module_default_hdo ) {
253+ return defaultImportModuleDynamicallyForModule ( specifier , attributes , referrerName ) ;
217254 }
218255
219256 if ( moduleRegistries . has ( referrerSymbol ) ) {
@@ -286,6 +323,29 @@ async function initializeHooks() {
286323 return hooks ;
287324}
288325
326+ /**
327+ * Compile a SourceTextModule for the built-in ESM loader. Register it for default
328+ * source map and import.meta and dynamic import() handling if cascadedLoader is provided.
329+ * @param {string } url URL of the module.
330+ * @param {string } source Source code of the module.
331+ * @param {typeof import('./loader.js').ModuleLoader|undefined } cascadedLoader If provided,
332+ * register the module for default handling.
333+ * @returns {ModuleWrap }
334+ */
335+ function compileSourceTextModule ( url , source , cascadedLoader ) {
336+ const hostDefinedOption = cascadedLoader ? source_text_module_default_hdo : undefined ;
337+ const wrap = new ModuleWrap ( url , undefined , source , 0 , 0 , hostDefinedOption ) ;
338+
339+ if ( ! cascadedLoader ) {
340+ return wrap ;
341+ }
342+ // Cache the source map for the module if present.
343+ if ( wrap . sourceMapURL ) {
344+ maybeCacheSourceMap ( url , source , null , false , undefined , wrap . sourceMapURL ) ;
345+ }
346+ return wrap ;
347+ }
348+
289349module . exports = {
290350 registerModule,
291351 initializeESM,
@@ -294,4 +354,5 @@ module.exports = {
294354 getConditionsSet,
295355 loaderWorkerId : 'internal/modules/esm/worker' ,
296356 forceDefaultLoader,
357+ compileSourceTextModule,
297358} ;
0 commit comments