Skip to content

Commit 7f731ed

Browse files
authored
perf(compiler): cache module resolution for isolatedModules: false (#1786)
1 parent 5d20cd5 commit 7f731ed

6 files changed

Lines changed: 43 additions & 40 deletions

File tree

src/__helpers__/fakers.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,6 @@ export function createConfigSet({
6868
resolve?: ((path: string) => string) | null
6969
[key: string]: any
7070
} = {}): ConfigSet {
71-
const defaultTestRegex = ['(/__tests__/.*|(\\\\.|/)(test|spec))\\\\.[jt]sx?$']
72-
const defaultTestMatch = ['**/__tests__/**/*.[jt]s?(x)', '**/?(*.)+(spec|test).[jt]s?(x)']
73-
jestConfig = {
74-
...jestConfig,
75-
testMatch: jestConfig?.testMatch ? [...jestConfig.testMatch, ...defaultTestMatch] : defaultTestMatch,
76-
testRegex: jestConfig?.testRegex ? [...defaultTestRegex, ...jestConfig.testRegex] : defaultTestRegex,
77-
}
7871
const cs = new ConfigSet(getJestConfig(jestConfig, tsJestConfig), parentConfig)
7972
if (resolve) {
8073
cs.resolvePath = resolve
@@ -101,6 +94,13 @@ export function makeCompiler({
10194
...(tsJestConfig.diagnostics as any),
10295
pretty: false,
10396
}
97+
const defaultTestRegex = ['(/__tests__/.*|(\\\\.|/)(test|spec))\\\\.[jt]sx?$']
98+
const defaultTestMatch = ['**/__tests__/**/*.[jt]s?(x)', '**/?(*.)+(spec|test).[jt]s?(x)']
99+
jestConfig = {
100+
...jestConfig,
101+
testMatch: jestConfig?.testMatch ? [...jestConfig.testMatch, ...defaultTestMatch] : defaultTestMatch,
102+
testRegex: jestConfig?.testRegex ? [...defaultTestRegex, ...jestConfig.testRegex] : defaultTestRegex,
103+
}
104104
const cs = createConfigSet({ jestConfig, tsJestConfig, parentConfig, resolve: null })
105105

106106
return createCompilerInstance(cs)

src/compiler/language-service.spec.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import ProcessedSource from '../__helpers__/processed-source'
1010
const logTarget = logTargetMock()
1111

1212
describe('Language service', () => {
13+
const baseTsJestConfig = { tsConfig: require.resolve('../../tsconfig.spec.json') }
14+
1315
beforeEach(() => {
1416
logTarget.clear()
1517
})
@@ -107,10 +109,26 @@ describe('Language service', () => {
107109
})
108110
})
109111

112+
describe('module resolution', () => {
113+
it(`should use moduleResolutionCache`, () => {
114+
jest.unmock('typescript')
115+
const ts = require('typescript')
116+
const moduleResolutionCacheMock = (ts.createModuleResolutionCache = jest.fn().mockImplementation(() => {}))
117+
118+
makeCompiler({
119+
tsJestConfig: baseTsJestConfig,
120+
})
121+
122+
expect(moduleResolutionCacheMock).toHaveBeenCalled()
123+
expect(moduleResolutionCacheMock.mock.calls[0].length).toBe(3)
124+
125+
moduleResolutionCacheMock.mockRestore()
126+
})
127+
})
128+
110129
describe('diagnostics', () => {
111130
const importedFileName = require.resolve('../__mocks__/thing.ts')
112131
const importedFileContent = readFileSync(importedFileName, 'utf-8')
113-
const baseTsJestConfig = { tsConfig: require.resolve('../../tsconfig.spec.json') }
114132

115133
it(`should report diagnostics for imported modules as well as test files which use imported modules with cache`, async () => {
116134
const testFileName = require.resolve('../__mocks__/thing1.spec.ts')

src/compiler/language-service.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,19 @@ export const initializeLanguageServiceInstance = (configs: ConfigSet, logger: Lo
8080
realpath: ts.sys.realpath && memoize(ts.sys.realpath),
8181
getDirectories: memoize(ts.sys.getDirectories),
8282
}
83+
const moduleResolutionCache = ts.createModuleResolutionCache(cwd, (x) => x, options)
8384
function resolveModuleNames(moduleNames: string[], containingFile: string): (_ts.ResolvedModuleFull | undefined)[] {
8485
const normalizedContainingFile = normalize(containingFile)
8586
const currentResolvedModules = memoryCache.resolvedModules.get(normalizedContainingFile) ?? []
8687

8788
return moduleNames.map((moduleName) => {
88-
const resolveModuleName = ts.resolveModuleName(moduleName, containingFile, options, moduleResolutionHost)
89+
const resolveModuleName = ts.resolveModuleName(
90+
moduleName,
91+
containingFile,
92+
options,
93+
moduleResolutionHost,
94+
moduleResolutionCache,
95+
)
8996
const resolvedModule = resolveModuleName.resolvedModule
9097
if (configs.isTestFile(normalizedContainingFile) && resolvedModule) {
9198
const normalizedResolvedFileName = normalize(resolvedModule.resolvedFileName)

src/config/__snapshots__/config-set.spec.ts.snap

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3-
exports[`cacheKey should be a string 1`] = `"{\\"digest\\":\\"a0d51ca854194df8191d0e65c0ca4730f510f332\\",\\"jest\\":{\\"__backported\\":true,\\"globals\\":{},\\"testMatch\\":[\\"**/__tests__/**/*.[jt]s?(x)\\",\\"**/?(*.)+(spec|test).[jt]s?(x)\\"],\\"testRegex\\":[\\"(/__tests__/.*|(\\\\\\\\\\\\\\\\.|/)(test|spec))\\\\\\\\\\\\\\\\.[jt]sx?$\\"]},\\"projectDepVersions\\":{\\"dev\\":\\"1.2.5\\",\\"opt\\":\\"1.2.3\\",\\"peer\\":\\"1.2.4\\",\\"std\\":\\"1.2.6\\"},\\"transformers\\":[\\"hoisting-jest-mock@1\\"],\\"tsJest\\":{\\"compiler\\":\\"typescript\\",\\"diagnostics\\":{\\"ignoreCodes\\":[6059,18002,18003],\\"pretty\\":true,\\"throws\\":true},\\"isolatedModules\\":false,\\"packageJson\\":{\\"kind\\":\\"file\\"},\\"transformers\\":[]},\\"tsconfig\\":{\\"declaration\\":false,\\"inlineSourceMap\\":false,\\"inlineSources\\":true,\\"module\\":1,\\"noEmit\\":false,\\"removeComments\\":false,\\"sourceMap\\":true,\\"target\\":1}}"`;
3+
exports[`cacheKey should be a string 1`] = `"{\\"digest\\":\\"a0d51ca854194df8191d0e65c0ca4730f510f332\\",\\"jest\\":{\\"__backported\\":true,\\"globals\\":{}},\\"projectDepVersions\\":{\\"dev\\":\\"1.2.5\\",\\"opt\\":\\"1.2.3\\",\\"peer\\":\\"1.2.4\\",\\"std\\":\\"1.2.6\\"},\\"transformers\\":[\\"hoisting-jest-mock@1\\"],\\"tsJest\\":{\\"compiler\\":\\"typescript\\",\\"diagnostics\\":{\\"ignoreCodes\\":[6059,18002,18003],\\"pretty\\":true,\\"throws\\":true},\\"isolatedModules\\":false,\\"packageJson\\":{\\"kind\\":\\"file\\"},\\"transformers\\":[]},\\"tsconfig\\":{\\"declaration\\":false,\\"inlineSourceMap\\":false,\\"inlineSources\\":true,\\"module\\":1,\\"noEmit\\":false,\\"removeComments\\":false,\\"sourceMap\\":true,\\"target\\":1}}"`;
44

55
exports[`isTestFile should return a boolean value whether the file matches test pattern 1`] = `true`;
66

@@ -18,41 +18,20 @@ Object {
1818
"__parent": true,
1919
},
2020
},
21-
"testMatch": Array [
22-
"**/__tests__/**/*.[jt]s?(x)",
23-
"**/?(*.)+(spec|test).[jt]s?(x)",
24-
],
25-
"testRegex": Array [
26-
"(/__tests__/.*|(\\\\\\\\.|/)(test|spec))\\\\\\\\.[jt]sx?$",
27-
],
2821
}
2922
`;
3023

3124
exports[`jest should merge parent config if any with globals is undefined 1`] = `
3225
Object {
3326
"__backported": true,
3427
"globals": undefined,
35-
"testMatch": Array [
36-
"**/__tests__/**/*.[jt]s?(x)",
37-
"**/?(*.)+(spec|test).[jt]s?(x)",
38-
],
39-
"testRegex": Array [
40-
"(/__tests__/.*|(\\\\\\\\.|/)(test|spec))\\\\\\\\.[jt]sx?$",
41-
],
4228
}
4329
`;
4430

4531
exports[`jest should return correct config and go thru backports 1`] = `
4632
Object {
4733
"__backported": true,
4834
"globals": Object {},
49-
"testMatch": Array [
50-
"**/__tests__/**/*.[jt]s?(x)",
51-
"**/?(*.)+(spec|test).[jt]s?(x)",
52-
],
53-
"testRegex": Array [
54-
"(/__tests__/.*|(\\\\\\\\.|/)(test|spec))\\\\\\\\.[jt]sx?$",
55-
],
5635
}
5736
`;
5837

@@ -63,13 +42,6 @@ Object {
6342
"jest": Object {
6443
"__backported": true,
6544
"globals": Object {},
66-
"testMatch": Array [
67-
"**/__tests__/**/*.[jt]s?(x)",
68-
"**/?(*.)+(spec|test).[jt]s?(x)",
69-
],
70-
"testRegex": Array [
71-
"(/__tests__/.*|(\\\\\\\\.|/)(test|spec))\\\\\\\\.[jt]sx?$",
72-
],
7345
},
7446
"projectDepVersions": Object {
7547
"some-module": "1.2.3",

src/config/config-set.spec.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ import { getPackageVersion } from '../util/get-package-version'
1515
import { normalizeSlashes } from '../util/normalize-slashes'
1616
import { mocked } from '../util/testing'
1717

18-
import { ConfigSet, IGNORE_DIAGNOSTIC_CODES, MATCH_NOTHING, TS_JEST_OUT_DIR } from './config-set'
18+
import { IGNORE_DIAGNOSTIC_CODES, MATCH_NOTHING, TS_JEST_OUT_DIR } from './config-set'
19+
// eslint-disable-next-line no-duplicate-imports
20+
import type { ConfigSet } from './config-set'
1921

2022
jest.mock('../util/backports')
2123
jest.mock('../index')
@@ -795,6 +797,7 @@ describe('readTsConfig', () => {
795797
{ jestConfig: { rootDir: '/root', cwd: '/cwd' } as any },
796798
])('toggle warning message for users who are using ts-jest with babel or without babel', (config) => {
797799
const shouldAction = config.tsJestConfig?.babelConfig ? `shouldn't` : 'should'
800+
798801
beforeEach(() => {
799802
logTarget.clear()
800803
cs = createConfigSet(config)
@@ -974,6 +977,10 @@ describe('shouldReportDiagnostic', () => {
974977
describe('tsCompiler', () => {
975978
it('should be a compiler object', () => {
976979
const cs = createConfigSet({
980+
jestConfig: {
981+
testRegex: [],
982+
testMatch: [],
983+
},
977984
tsJestConfig: { tsConfig: false } as any,
978985
})
979986
const compiler = cs.tsCompiler

src/config/config-set.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,6 @@ export class ConfigSet {
210210
*/
211211
pattern instanceof RegExp || typeof pattern === 'string',
212212
)
213-
/* istanbul ignore next */
214213
if (!matchablePatterns.length) {
215214
matchablePatterns.push(...DEFAULT_JEST_TEST_MATCH)
216215
}

0 commit comments

Comments
 (0)