From 94db43f4d1c8d7b010d3ba78e6aa31af4aa25163 Mon Sep 17 00:00:00 2001 From: ahnpnl Date: Wed, 10 Jul 2024 18:54:29 +0200 Subject: [PATCH] fix(compiler): update memory cache after changing `module` value Fixes #4439 --- .../__snapshots__/ts-compiler.spec.ts.snap | 32 ------ src/legacy/compiler/ts-compiler.spec.ts | 99 +++++++++++-------- src/legacy/compiler/ts-compiler.ts | 4 +- 3 files changed, 60 insertions(+), 75 deletions(-) diff --git a/src/legacy/compiler/__snapshots__/ts-compiler.spec.ts.snap b/src/legacy/compiler/__snapshots__/ts-compiler.spec.ts.snap index 44eb97c2ed..1fc4cd40e5 100644 --- a/src/legacy/compiler/__snapshots__/ts-compiler.spec.ts.snap +++ b/src/legacy/compiler/__snapshots__/ts-compiler.spec.ts.snap @@ -1,37 +1,5 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`TsCompiler getCompiledOutput isolatedModules false should compile codes with useESM {"babelConfig": false, "supportsStaticESM": false, "useESM": true} 1`] = ` -{ - "allowSyntheticDefaultImports": undefined, - "esModuleInterop": true, - "module": 1, -} -`; - -exports[`TsCompiler getCompiledOutput isolatedModules false should compile codes with useESM {"babelConfig": false, "supportsStaticESM": true, "useESM": false} 1`] = ` -{ - "allowSyntheticDefaultImports": undefined, - "esModuleInterop": true, - "module": 1, -} -`; - -exports[`TsCompiler getCompiledOutput isolatedModules false should compile codes with useESM {"babelConfig": false, "supportsStaticESM": true, "useESM": true} 1`] = ` -{ - "allowSyntheticDefaultImports": undefined, - "esModuleInterop": true, - "module": 1, -} -`; - -exports[`TsCompiler getCompiledOutput isolatedModules false should compile codes with useESM {"babelConfig": true, "supportsStaticESM": false, "useESM": true} 1`] = ` -{ - "allowSyntheticDefaultImports": undefined, - "esModuleInterop": true, - "module": 1, -} -`; - exports[`TsCompiler getCompiledOutput isolatedModules true should transpile code with config {"babelConfig": false, "supportsStaticESM": false, "useESM": true} 1`] = ` { "allowSyntheticDefaultImports": undefined, diff --git a/src/legacy/compiler/ts-compiler.spec.ts b/src/legacy/compiler/ts-compiler.spec.ts index d45bcbd780..ee12043408 100644 --- a/src/legacy/compiler/ts-compiler.spec.ts +++ b/src/legacy/compiler/ts-compiler.spec.ts @@ -5,6 +5,7 @@ import type { CompilerOptions, EmitOutput, transpileModule, TranspileOutput } fr import * as ts from 'typescript' import { createConfigSet, makeCompiler } from '../../__helpers__/fakers' +import type { RawCompilerOptions } from '../../raw-compiler-options' import type { DepGraphInfo } from '../../types' import { Errors, interpolate } from '../../utils/messages' @@ -190,64 +191,80 @@ describe('TsCompiler', () => { test.each([ { useESM: true, - babelConfig: true, - supportsStaticESM: false, + supportsStaticESM: true, + moduleValue: 'ESNext', + expectedModule: ts.ModuleKind.ESNext, + expectedEsModuleInterop: false, }, { useESM: true, - babelConfig: false, supportsStaticESM: true, + moduleValue: 'NodeNext', + expectedModule: ts.ModuleKind.NodeNext, + expectedEsModuleInterop: true, }, { useESM: true, - babelConfig: false, supportsStaticESM: false, + moduleValue: 'ESNext', + expectedModule: ts.ModuleKind.CommonJS, + expectedEsModuleInterop: false, }, { useESM: false, - babelConfig: false, supportsStaticESM: true, + moduleValue: 'ESNext', + expectedModule: ts.ModuleKind.CommonJS, + expectedEsModuleInterop: false, }, - ])('should compile codes with useESM %p', ({ useESM, babelConfig, supportsStaticESM }) => { - const configSet = createConfigSet({ - tsJestConfig: { ...baseTsJestConfig, useESM, babelConfig }, - }) - const emptyFile = join(mockFolder, 'empty.ts') - configSet.parsedTsConfig.fileNames.push(emptyFile) - const compiler = new TsCompiler(configSet, new Map()) - // @ts-expect-error testing purpose - compiler._languageService.getEmitOutput = jest.fn().mockReturnValueOnce({ - outputFiles: [{ text: sourceMap }, { text: jsOutput }], - emitSkipped: false, - } as EmitOutput) - // @ts-expect-error testing purpose - compiler.getDiagnostics = jest.fn().mockReturnValue([]) + ])( + 'should compile codes with useESM %p', + ({ useESM, supportsStaticESM, moduleValue, expectedModule, expectedEsModuleInterop }) => { + const configSet = createConfigSet({ + tsJestConfig: { + ...baseTsJestConfig, + useESM, + tsconfig: { + module: moduleValue as unknown as RawCompilerOptions['module'], + esModuleInterop: false, + }, + }, + }) + const emptyFile = join(mockFolder, 'empty.ts') + configSet.parsedTsConfig.fileNames.push(emptyFile) + const compiler = new TsCompiler(configSet, new Map()) + // @ts-expect-error testing purpose + compiler._languageService.getEmitOutput = jest.fn().mockReturnValueOnce({ + outputFiles: [{ text: sourceMap }, { text: jsOutput }], + emitSkipped: false, + } as EmitOutput) + // @ts-expect-error testing purpose + compiler.getDiagnostics = jest.fn().mockReturnValue([]) - const output = compiler.getCompiledOutput(fileContent, fileName, { - depGraphs: new Map(), - supportsStaticESM, - watchMode: false, - }) + const output = compiler.getCompiledOutput(fileContent, fileName, { + depGraphs: new Map(), + supportsStaticESM, + watchMode: false, + }) - // @ts-expect-error testing purpose - const usedCompilerOptions = compiler._compilerOptions - expect({ - module: usedCompilerOptions.module, - esModuleInterop: usedCompilerOptions.esModuleInterop, - allowSyntheticDefaultImports: usedCompilerOptions.allowSyntheticDefaultImports, - }).toMatchSnapshot() - expect(output).toEqual({ - code: updateOutput(jsOutput, fileName, sourceMap), - diagnostics: [], - }) + // @ts-expect-error testing purpose + const usedCompilerOptions = compiler._compilerOptions - // @ts-expect-error testing purpose - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - compiler._languageService!.getSemanticDiagnostics(fileName) + expect(usedCompilerOptions.module).toBe(expectedModule) + expect(usedCompilerOptions.esModuleInterop).toBe(expectedEsModuleInterop) + expect(output).toEqual({ + code: updateOutput(jsOutput, fileName, sourceMap), + diagnostics: [], + }) - // @ts-expect-error testing purpose - expect(compiler._fileContentCache.has(emptyFile)).toBe(true) - }) + // @ts-expect-error testing purpose + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + compiler._languageService!.getSemanticDiagnostics(fileName) + + // @ts-expect-error testing purpose + expect(compiler._fileContentCache.has(emptyFile)).toBe(true) + }, + ) test('should show a warning message and return original file content for non ts/tsx files if emitSkipped is true', () => { const compiler = makeCompiler({ diff --git a/src/legacy/compiler/ts-compiler.ts b/src/legacy/compiler/ts-compiler.ts index 43a8fa0202..d4e4a5c2db 100644 --- a/src/legacy/compiler/ts-compiler.ts +++ b/src/legacy/compiler/ts-compiler.ts @@ -176,10 +176,10 @@ export class TsCompiler implements TsCompilerInstance { } getCompiledOutput(fileContent: string, fileName: string, options: TsJestCompileOptions): CompiledOutput { - const moduleKind = this._initialCompilerOptions.module - const currentModuleKind = this._compilerOptions.module const isEsmMode = this.configSet.useESM && options.supportsStaticESM this._compilerOptions = this.fixupCompilerOptionsForModuleKind(this._initialCompilerOptions, isEsmMode) + const moduleKind = this._initialCompilerOptions.module + const currentModuleKind = this._compilerOptions.module if (this._languageService) { this._logger.debug({ fileName }, 'getCompiledOutput(): compiling using language service')