@@ -11,7 +11,7 @@ import * as fs from 'graceful-fs';
11
11
import parseJson from 'parse-json' ;
12
12
import stripJsonComments from 'strip-json-comments' ;
13
13
import type { Config } from '@jest/types' ;
14
- import { extract , parse } from 'jest-docblock' ;
14
+ import { type Pragmas , extract , parse } from 'jest-docblock' ;
15
15
import { interopRequireDefault , requireOrImportModule } from 'jest-util' ;
16
16
import {
17
17
JEST_CONFIG_EXT_CTS ,
@@ -47,10 +47,15 @@ export default async function readConfigFileAndSetRootDir(
47
47
configObject = await requireOrImportModule < any > ( configPath ) ;
48
48
} catch ( requireOrImportModuleError ) {
49
49
if ( ! ( requireOrImportModuleError instanceof SyntaxError ) ) {
50
- throw requireOrImportModuleError ;
50
+ if ( ! hasTsLoaderExplicitlyConfigured ( configPath ) ) {
51
+ throw requireOrImportModuleError ;
52
+ }
51
53
}
52
54
try {
53
- // Likely ESM in a file interpreted as CJS, which means it needs to be
55
+ // There are various reasons of failed loadout of Jest config in Typescript:
56
+ // 1. User has specified a TypeScript loader in the docblock and
57
+ // desire non-native compilation (https://github.com/jestjs/jest/issues/15837)
58
+ // 2. Likely ESM in a file interpreted as CJS, which means it needs to be
54
59
// compiled. We ignore the error and try to load it with a loader.
55
60
configObject = await loadTSConfigFile ( configPath ) ;
56
61
} catch ( loadTSConfigFileError ) {
@@ -120,11 +125,22 @@ export default async function readConfigFileAndSetRootDir(
120
125
// Load the TypeScript configuration
121
126
let extraTSLoaderOptions : Record < string , unknown > ;
122
127
128
+ const hasTsLoaderExplicitlyConfigured = ( configPath : string ) : boolean => {
129
+ const docblockPragmas = loadDocblockPragmasInConfig ( configPath ) ;
130
+ const tsLoader = docblockPragmas [ 'jest-config-loader' ] ;
131
+ return ! Array . isArray ( tsLoader ) && ( tsLoader ?? '' ) . trim ( ) !== '' ;
132
+ } ;
133
+
134
+ const loadDocblockPragmasInConfig = ( configPath : string ) : Pragmas => {
135
+ const docblockPragmas = parse ( extract ( fs . readFileSync ( configPath , 'utf8' ) ) ) ;
136
+ return docblockPragmas ;
137
+ } ;
138
+
123
139
const loadTSConfigFile = async (
124
140
configPath : string ,
125
141
) : Promise < Config . InitialOptions > => {
126
142
// Get registered TypeScript compiler instance
127
- const docblockPragmas = parse ( extract ( fs . readFileSync ( configPath , 'utf8' ) ) ) ;
143
+ const docblockPragmas = loadDocblockPragmasInConfig ( configPath ) ;
128
144
const tsLoader = docblockPragmas [ 'jest-config-loader' ] || 'ts-node' ;
129
145
const docblockTSLoaderOptions = docblockPragmas [ 'jest-config-loader-options' ] ;
130
146
0 commit comments