Skip to content

Commit f1d1b6e

Browse files
authored
chore(compiler): improve performance for isolatedModules: false (#1558)
1 parent ec62440 commit f1d1b6e

12 files changed

+146
-251
lines changed

appveyor.yml

-48
This file was deleted.

e2e/__tests__/__snapshots__/logger.test.ts.snap

+6-6
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,14 @@ Array [
2222
"[level:20] file caching disabled",
2323
"[level:20] initializeLanguageServiceInstance(): create typescript compiler",
2424
"[level:20] compileUsingLanguageService(): creating language service",
25-
"[level:20] readThrough(): no cache",
25+
"[level:20] compileAndCacheResult(): no cache",
2626
"[level:20] compileFn(): compiling using language service",
2727
"[level:20] updateMemoryCache(): update memory cache for language service",
2828
"[level:20] visitSourceFileNode(): hoisting",
2929
"[level:20] compileFn(): computing diagnostics for <cwd>/Hello.spec.ts using language service",
3030
"[level:20] computing cache key for <cwd>/Hello.ts",
3131
"[level:20] processing <cwd>/Hello.ts",
32-
"[level:20] readThrough(): no cache",
32+
"[level:20] compileAndCacheResult(): no cache",
3333
"[level:20] compileFn(): compiling using language service",
3434
"[level:20] updateMemoryCache(): update memory cache for language service",
3535
"[level:20] visitSourceFileNode(): hoisting",
@@ -63,15 +63,15 @@ Array [
6363
"[level:20] file caching disabled",
6464
"[level:20] initializeLanguageServiceInstance(): create typescript compiler",
6565
"[level:20] compileUsingLanguageService(): creating language service",
66-
"[level:20] readThrough(): no cache",
66+
"[level:20] compileAndCacheResult(): no cache",
6767
"[level:20] compileFn(): compiling using language service",
6868
"[level:20] updateMemoryCache(): update memory cache for language service",
6969
"[level:20] visitSourceFileNode(): hoisting",
7070
"[level:20] compileFn(): computing diagnostics for <cwd>/Hello.spec.ts using language service",
7171
"[level:20] calling babel-jest processor",
7272
"[level:20] computing cache key for <cwd>/Hello.ts",
7373
"[level:20] processing <cwd>/Hello.ts",
74-
"[level:20] readThrough(): no cache",
74+
"[level:20] compileAndCacheResult(): no cache",
7575
"[level:20] compileFn(): compiling using language service",
7676
"[level:20] updateMemoryCache(): update memory cache for language service",
7777
"[level:20] visitSourceFileNode(): hoisting",
@@ -107,15 +107,15 @@ Array [
107107
"[level:20] file caching disabled",
108108
"[level:20] initializeLanguageServiceInstance(): create typescript compiler",
109109
"[level:20] compileUsingLanguageService(): creating language service",
110-
"[level:20] readThrough(): no cache",
110+
"[level:20] compileAndCacheResult(): no cache",
111111
"[level:20] compileFn(): compiling using language service",
112112
"[level:20] updateMemoryCache(): update memory cache for language service",
113113
"[level:20] visitSourceFileNode(): hoisting",
114114
"[level:20] compileFn(): computing diagnostics for <cwd>/Hello.spec.ts using language service",
115115
"[level:20] calling babel-jest processor",
116116
"[level:20] computing cache key for <cwd>/Hello.ts",
117117
"[level:20] processing <cwd>/Hello.ts",
118-
"[level:20] readThrough(): no cache",
118+
"[level:20] compileAndCacheResult(): no cache",
119119
"[level:20] compileFn(): compiling using language service",
120120
"[level:20] updateMemoryCache(): update memory cache for language service",
121121
"[level:20] visitSourceFileNode(): hoisting",

src/__helpers__/fakers.ts

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

src/compiler/compiler-utils.spec.ts

-67
This file was deleted.

src/compiler/compiler-utils.ts

+3-6
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,15 @@ import { sha1 } from '../util/sha1'
1212
/**
1313
* @internal
1414
*/
15-
export const hasOwn = Object.prototype.hasOwnProperty
16-
/**
17-
* @internal
18-
*/
19-
export function getResolvedModulesCache(cachedir: string): string {
20-
return join(cachedir, sha1('ts-jest-resolved-modules', '\x00'))
15+
export function getResolvedModulesCache(cacheDir: string): string {
16+
return join(cacheDir, sha1('ts-jest-resolved-modules', '\x00'))
2117
}
2218

2319
/**
2420
* @internal
2521
* Get resolved modules of a test file and put into memory cache
2622
*/
23+
/* istanbul ignore next (we leave this for e2e) */
2724
export function cacheResolvedModules(
2825
fileName: string,
2926
fileContent: string,

src/compiler/instance.ts

+49-51
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
import { Logger } from 'bs-logger'
3333
import { readFileSync, writeFileSync } from 'fs'
3434
import mkdirp = require('mkdirp')
35-
import { basename, extname, join, normalize } from 'path'
35+
import { basename, extname, join } from 'path'
3636

3737
import { ConfigSet } from '../config/config-set'
3838
import { CompileFn, CompilerInstance, MemoryCache, TSFile, TsCompiler } from '../types'
@@ -92,60 +92,54 @@ const isValidCacheContent = (contents: string): boolean => {
9292
* cache mode
9393
*/
9494
const compileAndCacheResult = (
95-
cachedir: string | undefined,
95+
cacheDir: string | undefined,
9696
memoryCache: MemoryCache,
9797
compileFn: CompileFn,
9898
getExtension: (fileName: string) => string,
9999
logger: Logger,
100100
) => {
101-
if (!cachedir) {
102-
return (code: string, fileName: string, lineOffset?: number) => {
103-
const normalizedFileName = normalize(fileName)
104-
105-
logger.debug({ normalizedFileName }, 'readThrough(): no cache')
106-
107-
const [value, sourceMap] = compileFn(code, normalizedFileName, lineOffset)
101+
return (code: string, fileName: string, lineOffset?: number) => {
102+
function getCompileOutput(): string {
103+
const [value, sourceMap] = compileFn(code, fileName, lineOffset)
108104
const output = updateOutput(value, fileName, sourceMap, getExtension)
109-
memoryCache.outputs[normalizedFileName] = output
105+
memoryCache.files.set(fileName, {
106+
...memoryCache.files.get(fileName)!,
107+
output,
108+
})
110109

111110
return output
112111
}
113-
}
114-
115-
// Make sure the cache directory exists before continuing.
116-
mkdirp.sync(cachedir)
117-
try {
118-
const resolvedModulesCache = readFileSync(getResolvedModulesCache(cachedir), 'utf-8')
119-
/* istanbul ignore next (covered by e2e) */
120-
memoryCache.resolvedModules = JSON.parse(resolvedModulesCache)
121-
} catch (e) {}
112+
if (!cacheDir) {
113+
logger.debug({ fileName }, 'compileAndCacheResult(): no cache')
122114

123-
return (code: string, fileName: string, lineOffset?: number) => {
124-
const normalizedFileName = normalize(fileName)
125-
const cachePath = join(cachedir, getCacheName(code, normalizedFileName))
126-
const extension = getExtension(normalizedFileName)
127-
const outputPath = `${cachePath}${extension}`
128-
try {
129-
const output = readFileSync(outputPath, 'utf8')
130-
if (isValidCacheContent(output)) {
131-
logger.debug({ normalizedFileName }, 'readThrough(): cache hit')
132-
memoryCache.outputs[normalizedFileName] = output
115+
return getCompileOutput()
116+
} else {
117+
const cachePath = join(cacheDir, getCacheName(code, fileName))
118+
const extension = getExtension(fileName)
119+
const outputPath = `${cachePath}${extension}`
120+
try {
121+
const output = readFileSync(outputPath, 'utf8')
122+
if (isValidCacheContent(output)) {
123+
logger.debug({ fileName }, 'compileAndCacheResult(): cache hit')
124+
memoryCache.files.set(fileName, {
125+
...memoryCache.files.get(fileName)!,
126+
output,
127+
})
133128

134-
return output
135-
}
136-
} catch (err) {}
129+
return output
130+
}
131+
} catch (err) {}
137132

138-
logger.debug({ fileName }, 'readThrough(): cache miss')
133+
logger.debug({ fileName }, 'compileAndCacheResult(): cache miss')
139134

140-
const [value, sourceMap] = compileFn(code, normalizedFileName, lineOffset)
141-
const output = updateOutput(value, normalizedFileName, sourceMap, getExtension)
135+
const output = getCompileOutput()
142136

143-
logger.debug({ normalizedFileName, outputPath }, 'readThrough(): writing caches')
137+
logger.debug({ fileName, outputPath }, 'compileAndCacheResult(): writing caches')
144138

145-
memoryCache.outputs[normalizedFileName] = output
146-
writeFileSync(outputPath, output)
139+
writeFileSync(outputPath, output)
147140

148-
return output
141+
return output
142+
}
149143
}
150144
}
151145

@@ -156,16 +150,13 @@ const compileAndCacheResult = (
156150
export const createCompilerInstance = (configs: ConfigSet): TsCompiler => {
157151
const logger = configs.logger.child({ namespace: 'ts-compiler' })
158152
const {
159-
typescript: { options: compilerOptions, fileNames },
153+
typescript: { options: compilerOptions },
160154
tsJest,
161155
} = configs
162-
const cachedir = configs.tsCacheDir
156+
const cacheDir = configs.tsCacheDir
163157
const ts = configs.compilerModule // Require the TypeScript compiler and configuration.
164158
const extensions = ['.ts', '.tsx']
165159
const memoryCache: MemoryCache = {
166-
contents: Object.create(null),
167-
versions: Object.create(null),
168-
outputs: Object.create(null),
169160
resolvedModules: Object.create(null),
170161
files: new Map<string, TSFile>(),
171162
}
@@ -174,14 +165,21 @@ export const createCompilerInstance = (configs: ConfigSet): TsCompiler => {
174165
extensions.push('.js')
175166
extensions.push('.jsx')
176167
}
177-
// Initialize files from TypeScript into project.
178-
for (const path of fileNames) {
179-
const normalizedFilePath = normalize(path)
180-
memoryCache.versions[normalizedFilePath] = 1
181-
memoryCache.files.set(normalizedFilePath, {
168+
if (cacheDir) {
169+
// Make sure the cache directory exists before continuing.
170+
mkdirp.sync(cacheDir)
171+
try {
172+
const resolvedModulesCache = readFileSync(getResolvedModulesCache(cacheDir), 'utf-8')
173+
/* istanbul ignore next (covered by e2e) */
174+
memoryCache.resolvedModules = JSON.parse(resolvedModulesCache)
175+
} catch (e) {}
176+
}
177+
/* istanbul ignore next (we leave this for e2e) */
178+
configs.jest.setupFiles.concat(configs.jest.setupFilesAfterEnv).forEach(setupFile => {
179+
memoryCache.files.set(setupFile, {
182180
version: 0,
183181
})
184-
}
182+
})
185183
/**
186184
* Get the extension for a transpiled file.
187185
*/
@@ -196,7 +194,7 @@ export const createCompilerInstance = (configs: ConfigSet): TsCompiler => {
196194
} else {
197195
compilerInstance = initializeTranspilerInstance(configs, memoryCache, logger)
198196
}
199-
const compile = compileAndCacheResult(cachedir, memoryCache, compilerInstance.compileFn, getExtension, logger)
197+
const compile = compileAndCacheResult(cacheDir, memoryCache, compilerInstance.compileFn, getExtension, logger)
200198

201199
return { cwd: configs.cwd, compile, program: compilerInstance.program }
202200
}

0 commit comments

Comments
 (0)