@@ -7,9 +7,10 @@ import {
7
7
ModuleKind ,
8
8
JsxEmit ,
9
9
} from 'typescript' ;
10
- import { resolve , sep } from 'path' ;
10
+ import { resolve , sep , dirname } from 'path' ;
11
+ import { existsSync } from 'fs' ;
11
12
import formatTsDiagnostics from './format-diagnostics' ;
12
- import closestFileData , { IClosestDataResult } from 'closest-file-data' ;
13
+ import closestFileData from 'closest-file-data' ;
13
14
import { memoize } from 'lodash' ;
14
15
import { logOnce } from './logger' ;
15
16
import getTSJestConfig from './get-ts-jest-config' ;
@@ -18,7 +19,7 @@ const getTSConfig = memoize(getTSConfig_local, jestConfig => {
18
19
// check cache before resolving configuration
19
20
// NB: We use JSON.stringify() to create a consistent, unique signature. Although it lacks a uniform
20
21
// shape, this is simpler and faster than using the crypto package to generate a hash signature.
21
- return JSON . stringify ( jestConfig ) ;
22
+ return JSON . stringify ( { ... jestConfig , name : null , cacheDirectory : null } ) ;
22
23
} ) ;
23
24
export default getTSConfig ;
24
25
@@ -33,7 +34,7 @@ function getTSConfig_local(jestConfig: jest.ProjectConfig): CompilerOptions {
33
34
const { path : configPath } = configMeta ;
34
35
logOnce ( `Reading tsconfig file from path ${ configPath } ` ) ;
35
36
36
- const config = readCompilerOptions ( configPath , jestConfig . rootDir ) ;
37
+ const config = readCompilerOptions ( configPath ) ;
37
38
logOnce ( 'Original typescript config before modifications: ' , { ...config } ) ;
38
39
39
40
// tsc should not emit declaration map when used for tests
@@ -70,11 +71,8 @@ function getTSConfig_local(jestConfig: jest.ProjectConfig): CompilerOptions {
70
71
return config ;
71
72
}
72
73
73
- function readCompilerOptions (
74
- configPath : string ,
75
- rootDir : string ,
76
- ) : CompilerOptions {
77
- configPath = resolve ( rootDir , configPath ) ;
74
+ function readCompilerOptions ( configPath : string ) : CompilerOptions {
75
+ // at this point the configPath is resolved
78
76
const { config, error } = readConfigFile ( configPath , sys . readFile ) ;
79
77
if ( error ) {
80
78
throw error ;
@@ -83,7 +81,8 @@ function readCompilerOptions(
83
81
const { errors, options } = parseJsonConfigFileContent (
84
82
config ,
85
83
sys ,
86
- resolve ( rootDir ) ,
84
+ // paths in a tsconfig are relative to that file's path
85
+ dirname ( configPath ) ,
87
86
) ;
88
87
89
88
if ( errors . length > 0 ) {
@@ -117,13 +116,29 @@ function findTSConfigPath(
117
116
) : { isUserDefined ?: boolean ; path : string } | void {
118
117
let tsConfigFile = getTSJestConfig ( jestConfig ) . tsConfigFile ;
119
118
if ( tsConfigFile ) {
119
+ const givenConfigFile = tsConfigFile ;
120
120
tsConfigFile = tsConfigFile . replace (
121
121
'<rootDir>' ,
122
122
`${ jestConfig . rootDir } ${ sep } ` ,
123
123
) ;
124
- tsConfigFile = resolve ( jestConfig . rootDir , tsConfigFile ) ;
124
+ // ensure the path is resolved
125
+ if ( ! tsConfigFile . startsWith ( '/' ) ) {
126
+ tsConfigFile = resolve ( jestConfig . rootDir , tsConfigFile ) ;
127
+ } else {
128
+ tsConfigFile = resolve ( tsConfigFile ) ;
129
+ }
130
+ if ( ! existsSync ( tsConfigFile ) ) {
131
+ throw new Error (
132
+ [
133
+ `Unable to find tsconfig file given "${ givenConfigFile } ". If you gave a relative path,` ,
134
+ `it'll be relative to the resolved "rootDir".\nTo avoid issues, use <rootDir> followed` ,
135
+ `by a relative path to it in "tsConfigFile" config key.` ,
136
+ ] . join ( ' ' ) ,
137
+ ) ;
138
+ }
125
139
return { path : tsConfigFile , isUserDefined : true } ;
126
140
}
127
141
142
+ // try to find the config file starting from the root dir as defined in (or resolved by) jest config
128
143
return closestFileData ( jestConfig . rootDir , tsConfigReader ) ;
129
144
}
0 commit comments