diff --git a/e2e/native-esm-ts/jest.config.js b/e2e/native-esm-ts/jest.config.js index 0b3339a149..4c6efadd53 100644 --- a/e2e/native-esm-ts/jest.config.js +++ b/e2e/native-esm-ts/jest.config.js @@ -1,12 +1,13 @@ -import { pathsToModuleNameMapper } from '../../dist/index.js' +import { pathsToModuleNameMapper, createDefaultEsmPreset } from '../../dist/index.js' import { createRequire } from 'module' const require = createRequire(import.meta.url) const tsConfig = require('./tsconfig.json') +const esmPreset = createDefaultEsmPreset() /** @type {import('../../dist').JestConfigWithTsJest} */ export default { - extensionsToTreatAsEsm: ['.ts'], + ...esmPreset, resolver: '/mjs-resolver.ts', moduleNameMapper: pathsToModuleNameMapper(tsConfig.compilerOptions.paths, { prefix: '', diff --git a/examples/react-app/tsconfig-esm.spec.json b/examples/react-app/tsconfig-esm.spec.json index 2da7333a83..e392e3d6e8 100644 --- a/examples/react-app/tsconfig-esm.spec.json +++ b/examples/react-app/tsconfig-esm.spec.json @@ -1,6 +1,7 @@ { "extends": "./tsconfig.spec.json", "compilerOptions": { + "module": "ESNext", "esModuleInterop": true } } diff --git a/src/legacy/compiler/__snapshots__/ts-compiler.spec.ts.snap b/src/legacy/compiler/__snapshots__/ts-compiler.spec.ts.snap index 33b5ea4249..08d11b3d25 100644 --- a/src/legacy/compiler/__snapshots__/ts-compiler.spec.ts.snap +++ b/src/legacy/compiler/__snapshots__/ts-compiler.spec.ts.snap @@ -20,15 +20,15 @@ exports[`TsCompiler getCompiledOutput isolatedModules false should compile codes { "allowSyntheticDefaultImports": true, "esModuleInterop": true, - "module": 99, + "module": 1, } `; exports[`TsCompiler getCompiledOutput isolatedModules false should compile codes with useESM {"babelConfig": true, "supportsStaticESM": false, "useESM": true} 1`] = ` { - "allowSyntheticDefaultImports": true, + "allowSyntheticDefaultImports": undefined, "esModuleInterop": true, - "module": 99, + "module": 1, } `; @@ -52,14 +52,14 @@ exports[`TsCompiler getCompiledOutput isolatedModules true should transpile code { "allowSyntheticDefaultImports": true, "esModuleInterop": true, - "module": 99, + "module": 1, } `; exports[`TsCompiler getCompiledOutput isolatedModules true should transpile code with config {"babelConfig": true, "supportsStaticESM": false, "useESM": true} 1`] = ` { - "allowSyntheticDefaultImports": true, + "allowSyntheticDefaultImports": undefined, "esModuleInterop": true, - "module": 99, + "module": 1, } `; diff --git a/src/legacy/compiler/ts-compiler.ts b/src/legacy/compiler/ts-compiler.ts index 5ef5f3df8c..3dd57fc89d 100644 --- a/src/legacy/compiler/ts-compiler.ts +++ b/src/legacy/compiler/ts-compiler.ts @@ -146,34 +146,41 @@ export class TsCompiler implements TsCompilerInstance { return importedModulePaths } - getCompiledOutput(fileContent: string, fileName: string, options: TsJestCompileOptions): CompiledOutput { - let moduleKind = this._initialCompilerOptions.module - let esModuleInterop = this._initialCompilerOptions.esModuleInterop - let allowSyntheticDefaultImports = this._initialCompilerOptions.allowSyntheticDefaultImports - const currentModuleKind = this._compilerOptions.module - const isEsmMode = this.configSet.useESM && options.supportsStaticESM - if ( - (this.configSet.babelJestTransformer || (!this.configSet.babelJestTransformer && options.supportsStaticESM)) && - this.configSet.useESM - ) { - moduleKind = - !moduleKind || - (moduleKind && - ![this._ts.ModuleKind.ES2015, this._ts.ModuleKind.ES2020, this._ts.ModuleKind.ESNext].includes(moduleKind)) - ? this._ts.ModuleKind.ESNext - : moduleKind - // Make sure `esModuleInterop` and `allowSyntheticDefaultImports` true to support import CJS into ESM - esModuleInterop = true - allowSyntheticDefaultImports = true - } else { - moduleKind = this._ts.ModuleKind.CommonJS + private fixupCompilerOptionsForModuleKind(compilerOptions: CompilerOptions, isEsm: boolean): CompilerOptions { + if (!isEsm) { + const moduleKind = compilerOptions.module ?? this._ts.ModuleKind.CommonJS + const moduleKindValue = [ + this._ts.ModuleKind.CommonJS, + this._ts.ModuleKind.Node16, + this._ts.ModuleKind.NodeNext, + ].includes(moduleKind) + ? moduleKind + : this._ts.ModuleKind.CommonJS + + return { + ...compilerOptions, + module: moduleKindValue, + } } - this._compilerOptions = { - ...this._compilerOptions, - allowSyntheticDefaultImports, - esModuleInterop, + + const moduleKind = compilerOptions.module ?? this._ts.ModuleKind.ESNext + const esModuleInterop = [this._ts.ModuleKind.Node16, this._ts.ModuleKind.NodeNext].includes(moduleKind) + ? true + : compilerOptions.esModuleInterop + + return { + ...compilerOptions, module: moduleKind, + esModuleInterop: esModuleInterop ?? false, + allowSyntheticDefaultImports: esModuleInterop ?? compilerOptions.allowSyntheticDefaultImports, } + } + + 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) if (this._languageService) { this._logger.debug({ fileName }, 'getCompiledOutput(): compiling using language service')