@@ -122,6 +122,7 @@ class Runtime {
122122 private _transitiveShouldMock : BooleanObject ;
123123 private _unmockList : RegExp | undefined ;
124124 private _virtualMocks : BooleanObject ;
125+ private _moduleImplementation ?: typeof nativeModule . Module ;
125126
126127 constructor (
127128 config : Config . ProjectConfig ,
@@ -898,64 +899,75 @@ class Runtime {
898899 }
899900
900901 if ( moduleName === 'module' ) {
901- const createRequire = ( modulePath : string | URL ) => {
902- const filename =
903- typeof modulePath === 'string'
904- ? modulePath . startsWith ( 'file:///' )
905- ? fileURLToPath ( new URL ( modulePath ) )
906- : modulePath
907- : fileURLToPath ( modulePath ) ;
908-
909- if ( ! path . isAbsolute ( filename ) ) {
902+ return this . _getMockedNativeModule ( ) ;
903+ }
904+
905+ return require ( moduleName ) ;
906+ }
907+
908+ private _getMockedNativeModule ( ) : typeof nativeModule . Module {
909+ if ( this . _moduleImplementation ) {
910+ return this . _moduleImplementation ;
911+ }
912+
913+ const createRequire = ( modulePath : string | URL ) => {
914+ const filename =
915+ typeof modulePath === 'string'
916+ ? modulePath . startsWith ( 'file:///' )
917+ ? fileURLToPath ( new URL ( modulePath ) )
918+ : modulePath
919+ : fileURLToPath ( modulePath ) ;
920+
921+ if ( ! path . isAbsolute ( filename ) ) {
922+ const error = new TypeError (
923+ `The argument 'filename' must be a file URL object, file URL string, or absolute path string. Received '${ filename } '` ,
924+ ) ;
925+ // @ts -ignore
926+ error . code = 'ERR_INVALID_ARG_TYPE' ;
927+ throw error ;
928+ }
929+
930+ return this . _createRequireImplementation ( {
931+ children : [ ] ,
932+ exports : { } ,
933+ filename,
934+ id : filename ,
935+ loaded : false ,
936+ } ) ;
937+ } ;
938+
939+ // should we implement the class ourselves?
940+ class Module extends nativeModule . Module { }
941+
942+ Module . Module = Module ;
943+
944+ if ( 'createRequire' in nativeModule ) {
945+ Module . createRequire = createRequire ;
946+ }
947+ if ( 'createRequireFromPath' in nativeModule ) {
948+ Module . createRequireFromPath = ( filename : string | URL ) => {
949+ if ( typeof filename !== 'string' ) {
910950 const error = new TypeError (
911- `The argument 'filename' must be a file URL object, file URL string, or absolute path string. Received '${ filename } '` ,
951+ `The argument 'filename' must be string. Received '${ filename } '.${
952+ filename instanceof URL
953+ ? ' Use createRequire for URL filename.'
954+ : ''
955+ } `,
912956 ) ;
913957 // @ts -ignore
914958 error . code = 'ERR_INVALID_ARG_TYPE' ;
915959 throw error ;
916960 }
917-
918- return this . _createRequireImplementation ( {
919- children : [ ] ,
920- exports : { } ,
921- filename,
922- id : filename ,
923- loaded : false ,
924- } ) ;
961+ return createRequire ( filename ) ;
925962 } ;
926-
927- const overriddenModules : Partial < typeof nativeModule > = { } ;
928-
929- if ( 'createRequire' in nativeModule ) {
930- overriddenModules . createRequire = createRequire ;
931- }
932- if ( 'createRequireFromPath' in nativeModule ) {
933- overriddenModules . createRequireFromPath = ( filename : string | URL ) => {
934- if ( typeof filename !== 'string' ) {
935- const error = new TypeError (
936- `The argument 'filename' must be string. Received '${ filename } '.${
937- filename instanceof URL
938- ? ' Use createRequire for URL filename.'
939- : ''
940- } `,
941- ) ;
942- // @ts -ignore
943- error . code = 'ERR_INVALID_ARG_TYPE' ;
944- throw error ;
945- }
946- return createRequire ( filename ) ;
947- } ;
948- }
949- if ( 'syncBuiltinESMExports' in nativeModule ) {
950- overriddenModules . syncBuiltinESMExports = ( ) => { } ;
951- }
952-
953- return Object . keys ( overriddenModules ) . length > 0
954- ? { ...nativeModule , ...overriddenModules }
955- : nativeModule ;
963+ }
964+ if ( 'syncBuiltinESMExports' in nativeModule ) {
965+ Module . syncBuiltinESMExports = ( ) => { } ;
956966 }
957967
958- return require ( moduleName ) ;
968+ this . _moduleImplementation = Module ;
969+
970+ return Module ;
959971 }
960972
961973 private _generateMock ( from : Config . Path , moduleName : string ) {
0 commit comments