Skip to content

Commit a9f02bd

Browse files
committedMay 4, 2020
fix(compiler)(**BREAKING**): allow using files provided by tsconfig (#1562)
BREAKING CHANGE: Any custom typing files or files which are needed to be compiled and intended to use with `jest` need to be defined in `files` option of `tsconfig`. For example ``` // tsconfig.json { // ...other configs "files": [ "my-custom-typings.d.ts". "my-global-module.ts" ] } ```
1 parent f7a7c6e commit a9f02bd

File tree

14 files changed

+3780
-20
lines changed

14 files changed

+3780
-20
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
lerna-debug.log*
8+
9+
# Diagnostic reports (https://nodejs.org/api/report.html)
10+
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
11+
12+
# Runtime data
13+
pids
14+
*.pid
15+
*.seed
16+
*.pid.lock
17+
18+
# Directory for instrumented libs generated by jscoverage/JSCover
19+
lib-cov
20+
21+
# Coverage directory used by tools like istanbul
22+
coverage
23+
*.lcov
24+
25+
# nyc test coverage
26+
.nyc_output
27+
28+
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
29+
.grunt
30+
31+
# Bower dependency directory (https://bower.io/)
32+
bower_components
33+
34+
# node-waf configuration
35+
.lock-wscript
36+
37+
# Compiled binary addons (https://nodejs.org/api/addons.html)
38+
build/Release
39+
40+
# Dependency directories
41+
node_modules/
42+
jspm_packages/
43+
44+
# Snowpack dependency directory (https://snowpack.dev/)
45+
web_modules/
46+
47+
# TypeScript cache
48+
*.tsbuildinfo
49+
50+
# Optional npm cache directory
51+
.npm
52+
53+
# Optional eslint cache
54+
.eslintcache
55+
56+
# Microbundle cache
57+
.rpt2_cache/
58+
.rts2_cache_cjs/
59+
.rts2_cache_es/
60+
.rts2_cache_umd/
61+
62+
# Optional REPL history
63+
.node_repl_history
64+
65+
# Output of 'npm pack'
66+
*.tgz
67+
68+
# Yarn Integrity file
69+
.yarn-integrity
70+
71+
# dotenv environment variables file
72+
.env
73+
.env.test
74+
75+
# parcel-bundler cache (https://parceljs.org/)
76+
.cache
77+
.parcel-cache
78+
79+
# Next.js build output
80+
.next
81+
82+
# Nuxt.js build / generate output
83+
.nuxt
84+
dist
85+
86+
# Gatsby files
87+
.cache/
88+
# Comment in the public line in if your project uses Gatsby and not Next.js
89+
# https://nextjs.org/blog/next-9-1#public-directory-support
90+
# public
91+
92+
# vuepress build output
93+
.vuepress/dist
94+
95+
# Serverless directories
96+
.serverless/
97+
98+
# FuseBox cache
99+
.fusebox/
100+
101+
# DynamoDB Local files
102+
.dynamodb/
103+
104+
# TernJS port file
105+
.tern-port
106+
107+
# Stores VSCode versions used for testing VSCode extensions
108+
.vscode-test
109+
110+
# yarn v2
111+
112+
.yarn/cache
113+
.yarn/unplugged
114+
.yarn/build-state.yml
115+
.pnp.*
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import $ from "jquery"
2+
3+
function foo() {
4+
$.ajax<number>("/foo")
5+
}
6+
7+
test("foo", () => {
8+
expect(2).toBe(2)
9+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module.exports = {
2+
preset: 'ts-jest',
3+
testEnvironment: 'node',
4+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
declare global {
2+
interface JQueryStatic {
3+
ajax<T>(url: string, settings?: JQuery.AjaxSettings): JQuery.jqXHR<T>
4+
}
5+
}
6+
7+
export {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"name": "custom-typings",
3+
"private": true,
4+
"scripts": {
5+
"test": "jest"
6+
},
7+
"dependencies": {
8+
"jquery": "^3.5.0"
9+
},
10+
"devDependencies": {
11+
"@types/jest": "^25.2.1",
12+
"@types/jquery": "^3.3.35",
13+
"jest": "^25.4.0",
14+
"typescript": "^3.8.3"
15+
}
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"compilerOptions": {
3+
"target": "es5",
4+
"module": "commonjs",
5+
"esModuleInterop": true
6+
},
7+
"files": [
8+
"jquery.d.ts"
9+
]
10+
}

‎e2e/__external-repos__/custom-typings/yarn.lock

+3,559
Large diffs are not rendered by default.

‎scripts/test-external-project.js

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ const jestArgs = process.argv.slice(3)
1515
let gitUrl = false
1616
const externalRepoPath = 'e2e/__external-repos__'
1717
const PROJECTS_TO_RUN = [
18+
`${externalRepoPath}/custom-typings`,
1819
`${externalRepoPath}/simple/with-dependency`,
1920
`${externalRepoPath}/simple-project-references`,
2021
`${externalRepoPath}/yarn-workspace-composite`,

‎src/__helpers__/fakers.ts

-2
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,6 @@ export function makeCompiler({
7272
...jestConfig,
7373
testMatch: ['^.+\\.tsx?$'],
7474
testRegex: jestConfig?.testRegex ? [...testRegex, ...jestConfig.testRegex] : testRegex,
75-
setupFiles: [],
76-
setupFilesAfterEnv: [],
7775
}
7876
const cs = new ConfigSet(getJestConfig(jestConfig, tsJestConfig), parentConfig)
7977

‎src/compiler/compiler-utils.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ function isUsingProjectReferences(
8181
function getResolvedProjectReferences(
8282
program: _ts.Program,
8383
): ReadonlyArray<_ts.ResolvedProjectReference | undefined> | undefined {
84-
const getProjectReferences = program.getResolvedProjectReferences || program.getProjectReferences
84+
const getProjectReferences = program.getResolvedProjectReferences ?? program.getProjectReferences
8585
if (getProjectReferences) {
8686
return getProjectReferences()
8787
}
@@ -118,7 +118,7 @@ export function getAndCacheProjectReference(
118118
projectReferences: ReadonlyArray<_ts.ProjectReference> | undefined,
119119
) {
120120
const file = files[filePath]
121-
if (file !== undefined && file.projectReference) {
121+
if (file?.projectReference) {
122122
return file.projectReference.project
123123
}
124124

@@ -157,13 +157,13 @@ function getAndCacheOutputJSFileName(
157157
files: TSFiles,
158158
) {
159159
const file = files[inputFileName]
160-
if (file?.projectReference && file.projectReference.outputFileName) {
160+
if (file?.projectReference?.outputFileName) {
161161
return file.projectReference.outputFileName
162162
}
163163

164164
const outputFileName = getOutputJavaScriptFileName(inputFileName, projectReference)
165165
if (file !== undefined) {
166-
file.projectReference = file.projectReference || {
166+
file.projectReference = file.projectReference ?? {
167167
project: projectReference,
168168
}
169169
file.projectReference.outputFileName = outputFileName

‎src/compiler/instance.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,8 @@ export const createCompilerInstance = (configs: ConfigSet): TsCompiler => {
9696
} catch (e) {}
9797
}
9898
/* istanbul ignore next (we leave this for e2e) */
99-
configs.jest.setupFiles.concat(configs.jest.setupFilesAfterEnv).forEach(setupFile => {
100-
memoryCache.files[setupFile] = {
99+
configs.typescript.fileNames.forEach(fileName => {
100+
memoryCache.files[fileName] = {
101101
version: 0,
102102
}
103103
})

‎src/config/config-set.spec.ts

+46-4
Original file line numberDiff line numberDiff line change
@@ -474,9 +474,8 @@ describe('typescript', () => {
474474
createConfigSet({ tsJestConfig: tsJest, parentConfig }).typescript
475475

476476
it('should read file list from default tsconfig', () => {
477-
// since the default is to lookup for tsconfig,
478-
// we should have this file in the list
479-
expect(get().fileNames).toContain(normalizeSlashes(__filename))
477+
// since the default is to lookup for tsconfig, but we set include to [] so we should not have this file in the list
478+
expect(get().fileNames).toEqual([])
480479
})
481480

482481
it.each(['tsConfig', 'tsconfig'])('should include compiler config from `%s` option key', (key: string) => {
@@ -614,6 +613,11 @@ describe('readTsConfig', () => {
614613
const conf = cs.readTsConfig()
615614
expect(conf.input).toBeUndefined()
616615
expect(readConfig).not.toHaveBeenCalled()
616+
expect(parseConfig.mock.calls[0][0]).toEqual(
617+
expect.objectContaining({
618+
include: [],
619+
}),
620+
)
617621
expect(parseConfig.mock.calls[0][2]).toBe('/root')
618622
expect(parseConfig.mock.calls[0][4]).toBeUndefined()
619623
})
@@ -656,16 +660,27 @@ describe('readTsConfig', () => {
656660
expect(conf.input.path).toBe('/root/tsconfig.json')
657661
expect(findConfig.mock.calls[0][0]).toBe('/root')
658662
expect(readConfig.mock.calls[0][0]).toBe('/root/tsconfig.json')
663+
expect(parseConfig.mock.calls[0][0]).toEqual(
664+
expect.objectContaining({
665+
include: [],
666+
}),
667+
)
659668
expect(parseConfig.mock.calls[0][2]).toBe('/root')
660669
expect(parseConfig.mock.calls[0][4]).toBe('/root/tsconfig.json')
661670
expect(conf.resolved.options.allowSyntheticDefaultImports).toEqual(true)
662671
expect(conf.resolved.errors).toMatchSnapshot()
663672
})
673+
664674
it('should use given tsconfig path', () => {
665675
const conf = cs.readTsConfig(undefined, '/foo/tsconfig.bar.json')
666676
expect(conf.input.path).toBe('/foo/tsconfig.bar.json')
667677
expect(findConfig).not.toBeCalled()
668678
expect(readConfig.mock.calls[0][0]).toBe('/foo/tsconfig.bar.json')
679+
expect(parseConfig.mock.calls[0][0]).toEqual(
680+
expect.objectContaining({
681+
include: [],
682+
}),
683+
)
669684
expect(parseConfig.mock.calls[0][2]).toBe('/foo')
670685
expect(parseConfig.mock.calls[0][4]).toBe('/foo/tsconfig.bar.json')
671686
expect(conf.resolved.errors).toMatchSnapshot()
@@ -693,11 +708,17 @@ describe('readTsConfig', () => {
693708
expect(conf.input.path).toBe('/root/tsconfig.json')
694709
expect(findConfig.mock.calls[0][0]).toBe('/root')
695710
expect(readConfig.mock.calls[0][0]).toBe('/root/tsconfig.json')
711+
expect(parseConfig.mock.calls[0][0]).toEqual(
712+
expect.objectContaining({
713+
include: [],
714+
}),
715+
)
696716
expect(parseConfig.mock.calls[0][2]).toBe('/root')
697717
expect(parseConfig.mock.calls[0][4]).toBe('/root/tsconfig.json')
698718
expect(conf.resolved.options.allowSyntheticDefaultImports).toEqual(true)
699719
expect(conf.resolved.errors).toMatchSnapshot()
700720
})
721+
701722
it('should use given tsconfig path', () => {
702723
const conf = cs.readTsConfig(undefined, '/foo/tsconfig.bar.json')
703724
expect(conf.input.path).toBe('/foo/tsconfig.bar.json')
@@ -730,16 +751,27 @@ describe('readTsConfig', () => {
730751
expect(conf.input.path).toBe('/root/tsconfig.json')
731752
expect(findConfig.mock.calls[0][0]).toBe('/root')
732753
expect(readConfig.mock.calls[0][0]).toBe('/root/tsconfig.json')
754+
expect(parseConfig.mock.calls[0][0]).toEqual(
755+
expect.objectContaining({
756+
include: [],
757+
}),
758+
)
733759
expect(parseConfig.mock.calls[0][2]).toBe('/root')
734760
expect(parseConfig.mock.calls[0][4]).toBe('/root/tsconfig.json')
735761
expect(conf.resolved.options.allowSyntheticDefaultImports).toBeUndefined()
736762
expect(conf.resolved.errors).toEqual([])
737763
})
764+
738765
it('should use given tsconfig path', () => {
739766
const conf = cs.readTsConfig(undefined, '/foo/tsconfig.bar.json')
740767
expect(conf.input.path).toBe('/foo/tsconfig.bar.json')
741768
expect(findConfig).not.toBeCalled()
742769
expect(readConfig.mock.calls[0][0]).toBe('/foo/tsconfig.bar.json')
770+
expect(parseConfig.mock.calls[0][0]).toEqual(
771+
expect.objectContaining({
772+
include: [],
773+
}),
774+
)
743775
expect(parseConfig.mock.calls[0][2]).toBe('/foo')
744776
expect(parseConfig.mock.calls[0][4]).toBe('/foo/tsconfig.bar.json')
745777
expect(conf.resolved.errors).toEqual([])
@@ -767,16 +799,27 @@ describe('readTsConfig', () => {
767799
expect(conf.input.path).toBe('/root/tsconfig.json')
768800
expect(findConfig.mock.calls[0][0]).toBe('/root')
769801
expect(readConfig.mock.calls[0][0]).toBe('/root/tsconfig.json')
802+
expect(parseConfig.mock.calls[0][0]).toEqual(
803+
expect.objectContaining({
804+
include: [],
805+
}),
806+
)
770807
expect(parseConfig.mock.calls[0][2]).toBe('/root')
771808
expect(parseConfig.mock.calls[0][4]).toBe('/root/tsconfig.json')
772809
expect(conf.resolved.errors).toEqual([])
773810
expect(conf.resolved.options.allowSyntheticDefaultImports).toEqual(true)
774811
})
812+
775813
it('should use given tsconfig path', () => {
776814
const conf = cs.readTsConfig(undefined, '/foo/tsconfig.bar.json')
777815
expect(conf.input.path).toBe('/foo/tsconfig.bar.json')
778816
expect(findConfig).not.toBeCalled()
779817
expect(readConfig.mock.calls[0][0]).toBe('/foo/tsconfig.bar.json')
818+
expect(parseConfig.mock.calls[0][0]).toEqual(
819+
expect.objectContaining({
820+
include: [],
821+
}),
822+
)
780823
expect(parseConfig.mock.calls[0][2]).toBe('/foo')
781824
expect(parseConfig.mock.calls[0][4]).toBe('/foo/tsconfig.bar.json')
782825
expect(conf.resolved.errors).toEqual([])
@@ -878,7 +921,6 @@ describe('tsCompiler', () => {
878921
it('should be a compiler object', () => {
879922
const cs = createConfigSet({
880923
tsJestConfig: { tsConfig: false } as any,
881-
jestConfig: { setupFiles: [], setupFilesAfterEnv: [] } as any,
882924
})
883925
const compiler = cs.tsCompiler
884926
expect(compiler.cwd).toBe(cs.cwd)

‎src/config/config-set.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -717,7 +717,7 @@ export class ConfigSet {
717717
resolvedConfigFile?: string | null,
718718
noProject?: boolean | null,
719719
): ReadTsConfigResult {
720-
let config = { compilerOptions: {} }
720+
let config = { compilerOptions: {}, include: [] }
721721
let basePath = normalizeSlashes(this.rootDir)
722722
let configFileName: string | undefined
723723
const ts = this.compilerModule
@@ -759,6 +759,11 @@ export class ConfigSet {
759759
...config.compilerOptions,
760760
...compilerOptions,
761761
}
762+
/**
763+
* Always set include to empty array so fileNames after parseJsonConfigFileContent only contains the least minimum initial
764+
* files to utilize LanguageService incremental feature
765+
*/
766+
config.include = []
762767

763768
// parse json, merge config extending others, ...
764769
const result = ts.parseJsonConfigFileContent(config, ts.sys, basePath, undefined, configFileName)

‎tsconfig.json

+1-7
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,7 @@
3131
"react"
3232
]
3333
},
34-
"include": [
35-
"e2e/__helpers__",
36-
"e2e/__serializer__",
37-
"e2e/__tests__",
38-
"scripts/",
39-
"src"
40-
],
34+
"include": [],
4135
"exclude": [
4236
"e2e/__cases__",
4337
"e2e/__templates__",

0 commit comments

Comments
 (0)
Please sign in to comment.