@@ -9,14 +9,14 @@ import nativeModule = require('module');
9
9
import * as path from 'path' ;
10
10
import { URL , fileURLToPath , pathToFileURL } from 'url' ;
11
11
import {
12
- Script ,
13
12
// @ts -expect-error: experimental, not added to the types
14
13
SourceTextModule ,
15
14
// @ts -expect-error: experimental, not added to the types
16
15
SyntheticModule ,
17
16
type Context as VMContext ,
18
17
// @ts -expect-error: experimental, not added to the types
19
18
type Module as VMModule ,
19
+ compileFunction ,
20
20
} from 'vm' ;
21
21
import { parse as parseCjs } from 'cjs-module-lexer' ;
22
22
import { CoverageInstrumenter , type V8Coverage } from 'collect-v8-coverage' ;
@@ -33,15 +33,12 @@ import type {
33
33
import type { LegacyFakeTimers , ModernFakeTimers } from '@jest/fake-timers' ;
34
34
import type { expect , jest } from '@jest/globals' ;
35
35
import type { SourceMapRegistry } from '@jest/source-map' ;
36
- import type {
37
- RuntimeTransformResult ,
38
- TestContext ,
39
- V8CoverageResult ,
40
- } from '@jest/test-result' ;
36
+ import type { TestContext , V8CoverageResult } from '@jest/test-result' ;
41
37
import {
42
38
type CallerTransformOptions ,
43
39
type ScriptTransformer ,
44
40
type ShouldInstrumentOptions ,
41
+ type TransformResult ,
45
42
type TransformationOptions ,
46
43
handlePotentialSyntaxError ,
47
44
shouldInstrument ,
@@ -145,10 +142,6 @@ const isWasm = (modulePath: string): boolean => modulePath.endsWith('.wasm');
145
142
146
143
const unmockRegExpCache = new WeakMap ( ) ;
147
144
148
- const EVAL_RESULT_VARIABLE = 'Object.<anonymous>' ;
149
-
150
- type RunScriptEvalResult = { [ EVAL_RESULT_VARIABLE ] : ModuleWrapper } ;
151
-
152
145
const runtimeSupportsVmModules = typeof SyntheticModule === 'function' ;
153
146
154
147
const supportsNodeColonModulePrefixInRequire = ( ( ) => {
@@ -203,11 +196,11 @@ export default class Runtime {
203
196
> ;
204
197
private readonly _sourceMapRegistry : SourceMapRegistry ;
205
198
private readonly _scriptTransformer : ScriptTransformer ;
206
- private readonly _fileTransforms : Map < string , RuntimeTransformResult > ;
199
+ private readonly _fileTransforms : Map < string , TransformResult > ;
207
200
private readonly _fileTransformsMutex : Map < string , Promise < void > > ;
208
201
private _v8CoverageInstrumenter : CoverageInstrumenter | undefined ;
209
202
private _v8CoverageResult : V8Coverage | undefined ;
210
- private _v8CoverageSources : Map < string , RuntimeTransformResult > | undefined ;
203
+ private _v8CoverageSources : Map < string , TransformResult > | undefined ;
211
204
private readonly _transitiveShouldMock : Map < string , boolean > ;
212
205
private _unmockList : RegExp | undefined ;
213
206
private readonly _virtualMocks : Map < string , boolean > ;
@@ -1603,21 +1596,10 @@ export default class Runtime {
1603
1596
1604
1597
const transformedCode = this . transformFile ( filename , options ) ;
1605
1598
1606
- let compiledFunction : ModuleWrapper | null = null ;
1607
-
1608
- const script = this . createScriptFromCode ( transformedCode , filename ) ;
1609
-
1610
- let runScript : RunScriptEvalResult | null = null ;
1611
-
1612
- const vmContext = this . _environment . getVmContext ( ) ;
1613
-
1614
- if ( vmContext ) {
1615
- runScript = script . runInContext ( vmContext , { filename} ) ;
1616
- }
1617
-
1618
- if ( runScript !== null ) {
1619
- compiledFunction = runScript [ EVAL_RESULT_VARIABLE ] ;
1620
- }
1599
+ const compiledFunction = this . createScriptFromCode (
1600
+ transformedCode ,
1601
+ filename ,
1602
+ ) ;
1621
1603
1622
1604
if ( compiledFunction === null ) {
1623
1605
this . _logFormattedReferenceError (
@@ -1690,10 +1672,7 @@ export default class Runtime {
1690
1672
source ,
1691
1673
) ;
1692
1674
1693
- this . _fileTransforms . set ( filename , {
1694
- ...transformedFile ,
1695
- wrapperLength : this . constructModuleWrapperStart ( ) . length ,
1696
- } ) ;
1675
+ this . _fileTransforms . set ( filename , transformedFile ) ;
1697
1676
1698
1677
if ( transformedFile . sourceMapPath ) {
1699
1678
this . _sourceMapRegistry . set ( filename , transformedFile . sourceMapPath ) ;
@@ -1718,10 +1697,7 @@ export default class Runtime {
1718
1697
) ;
1719
1698
1720
1699
if ( this . _fileTransforms . get ( filename ) ?. code !== transformedFile . code ) {
1721
- this . _fileTransforms . set ( filename , {
1722
- ...transformedFile ,
1723
- wrapperLength : 0 ,
1724
- } ) ;
1700
+ this . _fileTransforms . set ( filename , transformedFile ) ;
1725
1701
}
1726
1702
1727
1703
if ( transformedFile . sourceMapPath ) {
@@ -1731,34 +1707,39 @@ export default class Runtime {
1731
1707
}
1732
1708
1733
1709
private createScriptFromCode ( scriptSource : string , filename : string ) {
1710
+ const vmContext = this . _environment . getVmContext ( ) ;
1711
+
1712
+ if ( vmContext == null ) {
1713
+ return null ;
1714
+ }
1715
+
1734
1716
try {
1735
1717
const scriptFilename = this . _resolver . isCoreModule ( filename )
1736
1718
? `jest-nodejs-core-${ filename } `
1737
1719
: filename ;
1738
- return new Script ( this . wrapCodeInModuleWrapper ( scriptSource ) , {
1739
- columnOffset : this . _fileTransforms . get ( filename ) ?. wrapperLength ,
1740
- displayErrors : true ,
1741
- filename : scriptFilename ,
1742
- // @ts -expect-error: Experimental ESM API
1743
- importModuleDynamically : async ( specifier : string ) => {
1744
- invariant (
1745
- runtimeSupportsVmModules ,
1746
- 'You need to run with a version of node that supports ES Modules in the VM API. See https://jestjs.io/docs/ecmascript-modules' ,
1747
- ) ;
1748
-
1749
- const context = this . _environment . getVmContext ?.( ) ;
1750
-
1751
- invariant ( context , 'Test environment has been torn down' ) ;
1752
-
1753
- const module = await this . resolveModule (
1754
- specifier ,
1755
- scriptFilename ,
1756
- context ,
1757
- ) ;
1758
-
1759
- return this . linkAndEvaluateModule ( module ) ;
1720
+ return compileFunction (
1721
+ scriptSource ,
1722
+ this . constructInjectedModuleParameters ( ) ,
1723
+ {
1724
+ filename : scriptFilename ,
1725
+ // @ts -expect-error: Experimental ESM API
1726
+ importModuleDynamically : async ( specifier : string ) => {
1727
+ invariant (
1728
+ runtimeSupportsVmModules ,
1729
+ 'You need to run with a version of node that supports ES Modules in the VM API. See https://jestjs.io/docs/ecmascript-modules' ,
1730
+ ) ;
1731
+
1732
+ const module = await this . resolveModule (
1733
+ specifier ,
1734
+ scriptFilename ,
1735
+ vmContext ,
1736
+ ) ;
1737
+
1738
+ return this . linkAndEvaluateModule ( module ) ;
1739
+ } ,
1740
+ parsingContext : vmContext ,
1760
1741
} ,
1761
- } ) ;
1742
+ ) as ModuleWrapper ;
1762
1743
} catch ( error : any ) {
1763
1744
throw handlePotentialSyntaxError ( error ) ;
1764
1745
}
@@ -2484,16 +2465,6 @@ export default class Runtime {
2484
2465
) ;
2485
2466
}
2486
2467
2487
- private wrapCodeInModuleWrapper ( content : string ) {
2488
- return `${ this . constructModuleWrapperStart ( ) + content } \n}});` ;
2489
- }
2490
-
2491
- private constructModuleWrapperStart ( ) {
2492
- const args = this . constructInjectedModuleParameters ( ) ;
2493
-
2494
- return `({"${ EVAL_RESULT_VARIABLE } ":function(${ args . join ( ',' ) } ){` ;
2495
- }
2496
-
2497
2468
private constructInjectedModuleParameters ( ) : Array < string > {
2498
2469
return [
2499
2470
'module' ,
0 commit comments