Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf(compiler): use moduleResolutionCache for Language Service's resolveModuleNames #1786

Merged
merged 2 commits into from Jul 8, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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