@@ -3,6 +3,7 @@ import fs from "fs/promises";
33import path from "path" ;
44import vm from "vm" ;
55import {
6+ AdditionalModules ,
67 Context ,
78 ProcessedModuleRule ,
89 STRING_SCRIPT_PATH ,
@@ -19,7 +20,10 @@ export class ModuleLinker {
1920 readonly #moduleCache = new Map < string , vm . Module > ( ) ;
2021 readonly #cjsModuleCache = new Map < string , CommonJSModule > ( ) ;
2122
22- constructor ( private moduleRules : ProcessedModuleRule [ ] ) {
23+ constructor (
24+ private moduleRules : ProcessedModuleRule [ ] ,
25+ private additionalModules : AdditionalModules
26+ ) {
2327 this . linker = this . linker . bind ( this ) ;
2428 }
2529
@@ -45,13 +49,35 @@ export class ModuleLinker {
4549 ) ;
4650 }
4751
48- // Get path to specified module relative to referencing module
49- const identifier = path . resolve ( path . dirname ( referencing . identifier ) , spec ) ;
52+ const additionalModule = this . additionalModules [ spec ] ;
53+ const identifier = additionalModule
54+ ? spec
55+ : // Get path to specified module relative to referencing module
56+ path . resolve ( path . dirname ( referencing . identifier ) , spec ) ;
57+
5058 // If we've already seen a module with the same identifier, return it, to
5159 // handle import cycles
5260 const cached = this . #moduleCache. get ( identifier ) ;
5361 if ( cached ) return cached ;
5462
63+ const moduleOptions = { identifier, context : referencing . context } ;
64+ let module : vm . Module ;
65+
66+ // If this is an additional module, construct and return it immediately
67+ if ( additionalModule ) {
68+ module = new vm . SyntheticModule (
69+ Object . keys ( additionalModule ) ,
70+ function ( ) {
71+ for ( const [ key , value ] of Object . entries ( additionalModule ) ) {
72+ this . setExport ( key , value ) ;
73+ }
74+ } ,
75+ moduleOptions
76+ ) ;
77+ this . #moduleCache. set ( identifier , module ) ;
78+ return module ;
79+ }
80+
5581 // Find first matching module rule ("ignore" requires relative paths)
5682 const relativeIdentifier = path . relative ( "" , identifier ) ;
5783 const rule = this . moduleRules . find ( ( rule ) =>
@@ -67,8 +93,6 @@ export class ModuleLinker {
6793 // Load module based on rule type
6894 const data = await fs . readFile ( identifier ) ;
6995 this . #referencedPathSizes. set ( identifier , data . byteLength ) ;
70- const moduleOptions = { identifier, context : referencing . context } ;
71- let module : vm . Module ;
7296 switch ( rule . type ) {
7397 case "ESModule" :
7498 module = new vm . SourceTextModule ( data . toString ( "utf8" ) , moduleOptions ) ;
0 commit comments