@@ -7,9 +7,10 @@ import {
77 ModuleKind ,
88 JsxEmit ,
99} from 'typescript' ;
10- import { resolve , sep } from 'path' ;
10+ import { resolve , sep , dirname } from 'path' ;
11+ import { existsSync } from 'fs' ;
1112import formatTsDiagnostics from './format-diagnostics' ;
12- import closestFileData , { IClosestDataResult } from 'closest-file-data' ;
13+ import closestFileData from 'closest-file-data' ;
1314import { memoize } from 'lodash' ;
1415import { logOnce } from './logger' ;
1516import getTSJestConfig from './get-ts-jest-config' ;
@@ -18,7 +19,7 @@ const getTSConfig = memoize(getTSConfig_local, jestConfig => {
1819 // check cache before resolving configuration
1920 // NB: We use JSON.stringify() to create a consistent, unique signature. Although it lacks a uniform
2021 // 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 } ) ;
2223} ) ;
2324export default getTSConfig ;
2425
@@ -33,7 +34,7 @@ function getTSConfig_local(jestConfig: jest.ProjectConfig): CompilerOptions {
3334 const { path : configPath } = configMeta ;
3435 logOnce ( `Reading tsconfig file from path ${ configPath } ` ) ;
3536
36- const config = readCompilerOptions ( configPath , jestConfig . rootDir ) ;
37+ const config = readCompilerOptions ( configPath ) ;
3738 logOnce ( 'Original typescript config before modifications: ' , { ...config } ) ;
3839
3940 // tsc should not emit declaration map when used for tests
@@ -70,11 +71,8 @@ function getTSConfig_local(jestConfig: jest.ProjectConfig): CompilerOptions {
7071 return config ;
7172}
7273
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
7876 const { config, error } = readConfigFile ( configPath , sys . readFile ) ;
7977 if ( error ) {
8078 throw error ;
@@ -83,7 +81,8 @@ function readCompilerOptions(
8381 const { errors, options } = parseJsonConfigFileContent (
8482 config ,
8583 sys ,
86- resolve ( rootDir ) ,
84+ // paths in a tsconfig are relative to that file's path
85+ dirname ( configPath ) ,
8786 ) ;
8887
8988 if ( errors . length > 0 ) {
@@ -117,13 +116,29 @@ function findTSConfigPath(
117116) : { isUserDefined ?: boolean ; path : string } | void {
118117 let tsConfigFile = getTSJestConfig ( jestConfig ) . tsConfigFile ;
119118 if ( tsConfigFile ) {
119+ const givenConfigFile = tsConfigFile ;
120120 tsConfigFile = tsConfigFile . replace (
121121 '<rootDir>' ,
122122 `${ jestConfig . rootDir } ${ sep } ` ,
123123 ) ;
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+ }
125139 return { path : tsConfigFile , isUserDefined : true } ;
126140 }
127141
142+ // try to find the config file starting from the root dir as defined in (or resolved by) jest config
128143 return closestFileData ( jestConfig . rootDir , tsConfigReader ) ;
129144}
0 commit comments