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/js-with-babel/tsconfig-esm.json b/examples/js-with-babel/tsconfig-esm.json index a3abe66d31..b6429f521f 100644 --- a/examples/js-with-babel/tsconfig-esm.json +++ b/examples/js-with-babel/tsconfig-esm.json @@ -1,6 +1,8 @@ { "extends": "./tsconfig.json", "compilerOptions": { - "module": "ESNext" + "module": "ESNext", + "moduleResolution": "Bundler", + "esModuleInterop": true } } diff --git a/examples/js-with-babel/tsconfig.json b/examples/js-with-babel/tsconfig.json index 7b56577bc9..b3f36ff7b0 100644 --- a/examples/js-with-babel/tsconfig.json +++ b/examples/js-with-babel/tsconfig.json @@ -1,8 +1,8 @@ { "compilerOptions": { - "module": "CommonJS", - "target": "ES2015", - "allowJs": true + "module": "Node16", + "moduleResolution": "Node16", + "target": "ES2021" }, "files": ["globals.d.ts"] } diff --git a/examples/js-with-ts/tsconfig-esm.json b/examples/js-with-ts/tsconfig-esm.json index d2c2d1eb24..b6429f521f 100644 --- a/examples/js-with-ts/tsconfig-esm.json +++ b/examples/js-with-ts/tsconfig-esm.json @@ -2,6 +2,7 @@ "extends": "./tsconfig.json", "compilerOptions": { "module": "ESNext", + "moduleResolution": "Bundler", "esModuleInterop": true } } diff --git a/examples/js-with-ts/tsconfig.json b/examples/js-with-ts/tsconfig.json index 7b56577bc9..b3f36ff7b0 100644 --- a/examples/js-with-ts/tsconfig.json +++ b/examples/js-with-ts/tsconfig.json @@ -1,8 +1,8 @@ { "compilerOptions": { - "module": "CommonJS", - "target": "ES2015", - "allowJs": true + "module": "Node16", + "moduleResolution": "Node16", + "target": "ES2021" }, "files": ["globals.d.ts"] } diff --git a/examples/monorepo-app/tsconfig-esm.base.json b/examples/monorepo-app/tsconfig-esm.base.json index e963c9857b..9547045648 100644 --- a/examples/monorepo-app/tsconfig-esm.base.json +++ b/examples/monorepo-app/tsconfig-esm.base.json @@ -2,6 +2,7 @@ "extends": "./tsconfig.base.json", "compilerOptions": { "module": "ESNext", + "moduleResolution": "Bundler", "esModuleInterop": true } } diff --git a/examples/monorepo-app/tsconfig.base.json b/examples/monorepo-app/tsconfig.base.json index d763daa80f..b8821ac92a 100644 --- a/examples/monorepo-app/tsconfig.base.json +++ b/examples/monorepo-app/tsconfig.base.json @@ -9,10 +9,10 @@ "declaration": false, "downlevelIteration": true, "experimentalDecorators": true, - "moduleResolution": "node", "importHelpers": true, - "target": "ESNext", - "module": "CommonJS", + "module": "Node16", + "moduleResolution": "Node16", + "target": "ES2021", "lib": ["ESNext", "dom"] } } diff --git a/examples/react-app/tsconfig-esm.spec.json b/examples/react-app/tsconfig-esm.spec.json index 2da7333a83..c8d6370c41 100644 --- a/examples/react-app/tsconfig-esm.spec.json +++ b/examples/react-app/tsconfig-esm.spec.json @@ -1,6 +1,8 @@ { "extends": "./tsconfig.spec.json", "compilerOptions": { + "module": "ESNext", + "moduleResolution": "Bundler", "esModuleInterop": true } } diff --git a/examples/react-app/tsconfig.spec.json b/examples/react-app/tsconfig.spec.json index cc9ea9df8d..1c677a5751 100644 --- a/examples/react-app/tsconfig.spec.json +++ b/examples/react-app/tsconfig.spec.json @@ -1,7 +1,8 @@ { "extends": "./tsconfig.json", "compilerOptions": { - "module": "CommonJS", - "moduleResolution": "Node" + "module": "Node16", + "moduleResolution": "Node16", + "target": "ES2021" } } diff --git a/examples/ts-only/tsconfig-esm.json b/examples/ts-only/tsconfig-esm.json index d2c2d1eb24..b6429f521f 100644 --- a/examples/ts-only/tsconfig-esm.json +++ b/examples/ts-only/tsconfig-esm.json @@ -2,6 +2,7 @@ "extends": "./tsconfig.json", "compilerOptions": { "module": "ESNext", + "moduleResolution": "Bundler", "esModuleInterop": true } } diff --git a/examples/ts-only/tsconfig.json b/examples/ts-only/tsconfig.json index e3a6edbc6a..b3f36ff7b0 100644 --- a/examples/ts-only/tsconfig.json +++ b/examples/ts-only/tsconfig.json @@ -1,6 +1,7 @@ { "compilerOptions": { - "module": "CommonJS", + "module": "Node16", + "moduleResolution": "Node16", "target": "ES2021" }, "files": ["globals.d.ts"] diff --git a/examples/type-module/tsconfig-esm.json b/examples/type-module/tsconfig-esm.json index d2c2d1eb24..b6429f521f 100644 --- a/examples/type-module/tsconfig-esm.json +++ b/examples/type-module/tsconfig-esm.json @@ -2,6 +2,7 @@ "extends": "./tsconfig.json", "compilerOptions": { "module": "ESNext", + "moduleResolution": "Bundler", "esModuleInterop": true } } diff --git a/examples/type-module/tsconfig.json b/examples/type-module/tsconfig.json index e3a6edbc6a..b3f36ff7b0 100644 --- a/examples/type-module/tsconfig.json +++ b/examples/type-module/tsconfig.json @@ -1,6 +1,7 @@ { "compilerOptions": { - "module": "CommonJS", + "module": "Node16", + "moduleResolution": "Node16", "target": "ES2021" }, "files": ["globals.d.ts"] 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..65e8e7e954 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 getCompilerOptionsForModuleKind(compilerOptions: CompilerOptions, isEsm: boolean): CompilerOptions { + if (!isEsm) { + const moduleKind = compilerOptions.module ?? this._ts.ModuleKind.CommonJS + const allowedCjsModuleKinds = [ + this._ts.ModuleKind.CommonJS, + this._ts.ModuleKind.Node16, + this._ts.ModuleKind.NodeNext, + ].includes(moduleKind) + ? moduleKind + : this._ts.ModuleKind.CommonJS + + return { + ...compilerOptions, + module: allowedCjsModuleKinds, + } } - 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.getCompilerOptionsForModuleKind(this._compilerOptions, isEsmMode) if (this._languageService) { this._logger.debug({ fileName }, 'getCompiledOutput(): compiling using language service')