Skip to content

Commit

Permalink
perf(compiler): cache module resolution for isolatedModules: false (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
ahnpnl committed Jul 8, 2020
1 parent 5d20cd5 commit 7f731ed
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 40 deletions.
14 changes: 7 additions & 7 deletions src/__helpers__/fakers.ts
Expand Up @@ -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
Expand All @@ -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)
Expand Down
20 changes: 19 additions & 1 deletion src/compiler/language-service.spec.ts
Expand Up @@ -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()
})
Expand Down Expand Up @@ -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')
Expand Down
9 changes: 8 additions & 1 deletion src/compiler/language-service.ts
Expand Up @@ -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)
Expand Down
30 changes: 1 addition & 29 deletions 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`;

Expand All @@ -18,41 +18,20 @@ Object {
"__parent": true,
},
},
"testMatch": Array [
"**/__tests__/**/*.[jt]s?(x)",
"**/?(*.)+(spec|test).[jt]s?(x)",
],
"testRegex": Array [
"(/__tests__/.*|(\\\\\\\\.|/)(test|spec))\\\\\\\\.[jt]sx?$",
],
}
`;

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?$",
],
}
`;

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?$",
],
}
`;

Expand All @@ -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",
Expand Down
9 changes: 8 additions & 1 deletion src/config/config-set.spec.ts
Expand Up @@ -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')
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down
1 change: 0 additions & 1 deletion src/config/config-set.ts
Expand Up @@ -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)
}
Expand Down

0 comments on commit 7f731ed

Please sign in to comment.