Skip to content

Commit 6c6edd8

Browse files
authored
more thorough fallback to ts loaders if node TypeScript support doesn't work out (#15720)
1 parent 37b1686 commit 6c6edd8

File tree

2 files changed

+37
-16
lines changed

2 files changed

+37
-16
lines changed

e2e/__tests__/__snapshots__/jest.config.ts.test.ts.snap

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,20 @@ Ran all test suites."
1515
1616
exports[`on node >=24 invalid JS in jest.config.ts (node with native TS support) 1`] = `
1717
"Error: Jest: Failed to parse the TypeScript config file <<REPLACED>>
18-
SyntaxError [ERR_INVALID_TYPESCRIPT_SYNTAX]: Expected ';', got 'string literal (ll break this file yo, 'll break this file yo)'"
18+
both with the native node TypeScript support and configured TypeScript loaders.
19+
Errors were:
20+
- SyntaxError [ERR_INVALID_TYPESCRIPT_SYNTAX]: Expected ';', got 'string literal (ll break this file yo, 'll break this file yo)'
21+
- TSError: ⨯ Unable to compile TypeScript:
22+
jest.config.ts(1,16): error TS2304: Cannot find name 'i'.
23+
jest.config.ts(1,17): error TS1005: ';' expected.
24+
jest.config.ts(1,39): error TS1002: Unterminated string literal."
1925
`;
2026
2127
exports[`on node ^23.6 invalid JS in jest.config.ts (node with native TS support) 1`] = `
2228
"Error: Jest: Failed to parse the TypeScript config file <<REPLACED>>
23-
SyntaxError [ERR_INVALID_TYPESCRIPT_SYNTAX]: x Expected ';', got 'string literal (ll break this file yo, 'll break this file yo)'
29+
both with the native node TypeScript support and configured TypeScript loaders.
30+
Errors were:
31+
- SyntaxError [ERR_INVALID_TYPESCRIPT_SYNTAX]: x Expected ';', got 'string literal (ll break this file yo, 'll break this file yo)'
2432
,----
2533
1 | export default i'll break this file yo
2634
: ^^^^^^^^^^^^^^^^^^^^^^
@@ -29,7 +37,12 @@ exports[`on node ^23.6 invalid JS in jest.config.ts (node with native TS support
2937
,----
3038
1 | export default i'll break this file yo
3139
: ^^^^^^^^^^^^^^^^^^^^^^
32-
\`----"
40+
\`----
41+
42+
- TSError: ⨯ Unable to compile TypeScript:
43+
jest.config.ts(1,16): error TS2304: Cannot find name 'i'.
44+
jest.config.ts(1,17): error TS1005: ';' expected.
45+
jest.config.ts(1,39): error TS1002: Unterminated string literal."
3346
`;
3447
3548
exports[`traverses directory tree up until it finds jest.config 1`] = `

packages/jest-config/src/readConfigFileAndSetRootDir.ts

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -45,21 +45,29 @@ export default async function readConfigFileAndSetRootDir(
4545
try {
4646
// Try native node TypeScript support first.
4747
configObject = await requireOrImportModule<any>(configPath);
48-
} catch (error) {
49-
if (
50-
!(
51-
error instanceof SyntaxError &&
52-
// Likely ESM in a file interpreted as CJS, which means it needs to be
53-
// compiled. We ignore the error and try to load it with a loader.
54-
/Unexpected token '(export|import)'/.test(error.message)
55-
)
56-
) {
57-
throw error;
48+
} catch (requireOrImportModuleError) {
49+
if (!(requireOrImportModuleError instanceof SyntaxError)) {
50+
throw requireOrImportModuleError;
51+
}
52+
try {
53+
// Likely ESM in a file interpreted as CJS, which means it needs to be
54+
// compiled. We ignore the error and try to load it with a loader.
55+
configObject = await loadTSConfigFile(configPath);
56+
} catch (loadTSConfigFileError) {
57+
// If we still encounter an error, we throw both messages combined.
58+
// This string is caught further down and merged into a new error message.
59+
// eslint-disable-next-line no-throw-literal
60+
throw (
61+
// Preamble text is added further down:
62+
// Jest: Failed to parse the TypeScript config file ${configPath}\n
63+
' both with the native node TypeScript support and configured TypeScript loaders.\n' +
64+
' Errors were:\n' +
65+
` - ${requireOrImportModuleError}\n` +
66+
` - ${loadTSConfigFileError}`
67+
);
5868
}
5969
}
60-
}
61-
// Fall back to `ts-node` etc. if this cannot be natively parsed/executed.
62-
if (!configObject) {
70+
} else {
6371
configObject = await loadTSConfigFile(configPath);
6472
}
6573
} else if (isJSON) {

0 commit comments

Comments
 (0)