From ec15732c29c6cc2767ef10029f417b50990a6b26 Mon Sep 17 00:00:00 2001 From: Ahn Date: Wed, 8 Jul 2020 11:18:26 +0200 Subject: [PATCH] perf(compiler): use moduleResolutionCache for resolveModuleNames --- src/__helpers__/fakers.ts | 14 ++++----- src/compiler/language-service.spec.ts | 20 ++++++++++++- src/compiler/language-service.ts | 9 +++++- .../__snapshots__/config-set.spec.ts.snap | 30 +------------------ src/config/config-set.spec.ts | 9 +++++- src/config/config-set.ts | 1 - 6 files changed, 43 insertions(+), 40 deletions(-) diff --git a/src/__helpers__/fakers.ts b/src/__helpers__/fakers.ts index f417dddbf1..9f49caaa99 100644 --- a/src/__helpers__/fakers.ts +++ b/src/__helpers__/fakers.ts @@ -68,13 +68,6 @@ export function createConfigSet({ resolve?: ((path: string) => string) | null [key: string]: any } = {}): ConfigSet { - const defaultTestRegex = ['(/__tests__/.*|(\\\\.|/)(test|spec))\\\\.[jt]sx?$'] - const defaultTestMatch = ['**/__tests__/**/*.[jt]s?(x)', '**/?(*.)+(spec|test).[jt]s?(x)'] - jestConfig = { - ...jestConfig, - testMatch: jestConfig?.testMatch ? [...jestConfig.testMatch, ...defaultTestMatch] : defaultTestMatch, - testRegex: jestConfig?.testRegex ? [...defaultTestRegex, ...jestConfig.testRegex] : defaultTestRegex, - } const cs = new ConfigSet(getJestConfig(jestConfig, tsJestConfig), parentConfig) if (resolve) { cs.resolvePath = resolve @@ -101,6 +94,13 @@ export function makeCompiler({ ...(tsJestConfig.diagnostics as any), pretty: false, } + const defaultTestRegex = ['(/__tests__/.*|(\\\\.|/)(test|spec))\\\\.[jt]sx?$'] + const defaultTestMatch = ['**/__tests__/**/*.[jt]s?(x)', '**/?(*.)+(spec|test).[jt]s?(x)'] + jestConfig = { + ...jestConfig, + testMatch: jestConfig?.testMatch ? [...jestConfig.testMatch, ...defaultTestMatch] : defaultTestMatch, + testRegex: jestConfig?.testRegex ? [...defaultTestRegex, ...jestConfig.testRegex] : defaultTestRegex, + } const cs = createConfigSet({ jestConfig, tsJestConfig, parentConfig, resolve: null }) return createCompilerInstance(cs) diff --git a/src/compiler/language-service.spec.ts b/src/compiler/language-service.spec.ts index 513ed4581e..73a6b031b3 100644 --- a/src/compiler/language-service.spec.ts +++ b/src/compiler/language-service.spec.ts @@ -10,6 +10,8 @@ import ProcessedSource from '../__helpers__/processed-source' const logTarget = logTargetMock() describe('Language service', () => { + const baseTsJestConfig = { tsConfig: require.resolve('../../tsconfig.spec.json') } + beforeEach(() => { logTarget.clear() }) @@ -107,10 +109,26 @@ describe('Language service', () => { }) }) + describe('module resolution', () => { + it(`should use moduleResolutionCache`, () => { + jest.unmock('typescript') + const ts = require('typescript') + const moduleResolutionCacheMock = (ts.createModuleResolutionCache = jest.fn().mockImplementation(() => {})) + + makeCompiler({ + tsJestConfig: baseTsJestConfig, + }) + + expect(moduleResolutionCacheMock).toHaveBeenCalled() + expect(moduleResolutionCacheMock.mock.calls[0].length).toBe(3) + + moduleResolutionCacheMock.mockRestore() + }) + }) + describe('diagnostics', () => { const importedFileName = require.resolve('../__mocks__/thing.ts') const importedFileContent = readFileSync(importedFileName, 'utf-8') - const baseTsJestConfig = { tsConfig: require.resolve('../../tsconfig.spec.json') } it(`should report diagnostics for imported modules as well as test files which use imported modules with cache`, async () => { const testFileName = require.resolve('../__mocks__/thing1.spec.ts') diff --git a/src/compiler/language-service.ts b/src/compiler/language-service.ts index 5c671a7c23..e5f934d79e 100644 --- a/src/compiler/language-service.ts +++ b/src/compiler/language-service.ts @@ -80,12 +80,19 @@ export const initializeLanguageServiceInstance = (configs: ConfigSet, logger: Lo realpath: ts.sys.realpath && memoize(ts.sys.realpath), getDirectories: memoize(ts.sys.getDirectories), } + const moduleResolutionCache = ts.createModuleResolutionCache(cwd, (x) => x, options) function resolveModuleNames(moduleNames: string[], containingFile: string): (_ts.ResolvedModuleFull | undefined)[] { const normalizedContainingFile = normalize(containingFile) const currentResolvedModules = memoryCache.resolvedModules.get(normalizedContainingFile) ?? [] return moduleNames.map((moduleName) => { - const resolveModuleName = ts.resolveModuleName(moduleName, containingFile, options, moduleResolutionHost) + const resolveModuleName = ts.resolveModuleName( + moduleName, + containingFile, + options, + moduleResolutionHost, + moduleResolutionCache, + ) const resolvedModule = resolveModuleName.resolvedModule if (configs.isTestFile(normalizedContainingFile) && resolvedModule) { const normalizedResolvedFileName = normalize(resolvedModule.resolvedFileName) diff --git a/src/config/__snapshots__/config-set.spec.ts.snap b/src/config/__snapshots__/config-set.spec.ts.snap index e4a7fd62a6..ac0693e1d5 100644 --- a/src/config/__snapshots__/config-set.spec.ts.snap +++ b/src/config/__snapshots__/config-set.spec.ts.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -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}}"`; +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}}"`; exports[`isTestFile should return a boolean value whether the file matches test pattern 1`] = `true`; @@ -18,13 +18,6 @@ Object { "__parent": true, }, }, - "testMatch": Array [ - "**/__tests__/**/*.[jt]s?(x)", - "**/?(*.)+(spec|test).[jt]s?(x)", - ], - "testRegex": Array [ - "(/__tests__/.*|(\\\\\\\\.|/)(test|spec))\\\\\\\\.[jt]sx?$", - ], } `; @@ -32,13 +25,6 @@ exports[`jest should merge parent config if any with globals is undefined 1`] = Object { "__backported": true, "globals": undefined, - "testMatch": Array [ - "**/__tests__/**/*.[jt]s?(x)", - "**/?(*.)+(spec|test).[jt]s?(x)", - ], - "testRegex": Array [ - "(/__tests__/.*|(\\\\\\\\.|/)(test|spec))\\\\\\\\.[jt]sx?$", - ], } `; @@ -46,13 +32,6 @@ exports[`jest should return correct config and go thru backports 1`] = ` Object { "__backported": true, "globals": Object {}, - "testMatch": Array [ - "**/__tests__/**/*.[jt]s?(x)", - "**/?(*.)+(spec|test).[jt]s?(x)", - ], - "testRegex": Array [ - "(/__tests__/.*|(\\\\\\\\.|/)(test|spec))\\\\\\\\.[jt]sx?$", - ], } `; @@ -63,13 +42,6 @@ Object { "jest": Object { "__backported": true, "globals": Object {}, - "testMatch": Array [ - "**/__tests__/**/*.[jt]s?(x)", - "**/?(*.)+(spec|test).[jt]s?(x)", - ], - "testRegex": Array [ - "(/__tests__/.*|(\\\\\\\\.|/)(test|spec))\\\\\\\\.[jt]sx?$", - ], }, "projectDepVersions": Object { "some-module": "1.2.3", diff --git a/src/config/config-set.spec.ts b/src/config/config-set.spec.ts index 47dfb1742a..9e5a981dcf 100644 --- a/src/config/config-set.spec.ts +++ b/src/config/config-set.spec.ts @@ -15,7 +15,9 @@ import { getPackageVersion } from '../util/get-package-version' import { normalizeSlashes } from '../util/normalize-slashes' import { mocked } from '../util/testing' -import { ConfigSet, IGNORE_DIAGNOSTIC_CODES, MATCH_NOTHING, TS_JEST_OUT_DIR } from './config-set' +import { IGNORE_DIAGNOSTIC_CODES, MATCH_NOTHING, TS_JEST_OUT_DIR } from './config-set' +// eslint-disable-next-line no-duplicate-imports +import type { ConfigSet } from './config-set' jest.mock('../util/backports') jest.mock('../index') @@ -795,6 +797,7 @@ describe('readTsConfig', () => { { jestConfig: { rootDir: '/root', cwd: '/cwd' } as any }, ])('toggle warning message for users who are using ts-jest with babel or without babel', (config) => { const shouldAction = config.tsJestConfig?.babelConfig ? `shouldn't` : 'should' + beforeEach(() => { logTarget.clear() cs = createConfigSet(config) @@ -974,6 +977,10 @@ describe('shouldReportDiagnostic', () => { describe('tsCompiler', () => { it('should be a compiler object', () => { const cs = createConfigSet({ + jestConfig: { + testRegex: [], + testMatch: [], + }, tsJestConfig: { tsConfig: false } as any, }) const compiler = cs.tsCompiler diff --git a/src/config/config-set.ts b/src/config/config-set.ts index 23564a75ab..7ba4a754bc 100644 --- a/src/config/config-set.ts +++ b/src/config/config-set.ts @@ -210,7 +210,6 @@ export class ConfigSet { */ pattern instanceof RegExp || typeof pattern === 'string', ) - /* istanbul ignore next */ if (!matchablePatterns.length) { matchablePatterns.push(...DEFAULT_JEST_TEST_MATCH) }