From 543b4ad729d20fbd46a2de5cd4660dc50b94ebe7 Mon Sep 17 00:00:00 2001 From: Ahn <27772165+ahnpnl@users.noreply.github.com> Date: Wed, 27 Apr 2022 13:43:34 +0200 Subject: [PATCH] feat(presets): add presets for legacy mode (#3465) --- e2e/presets/__tests__/presets.spec.ts | 35 ++++++++++++++++ presets/default-esm-legacy/jest-preset.js | 1 + presets/default-legacy/jest-preset.js | 1 + presets/index.d.ts | 6 +++ presets/index.js | 41 ++++++++++++++++--- .../js-with-babel-esm-legacy/jest-preset.js | 1 + presets/js-with-babel-legacy/jest-preset.js | 1 + presets/js-with-ts-esm-legacy/jest-preset.js | 1 + presets/js-with-ts-legacy/jest-preset.js | 1 + src/index.ts | 9 ++-- src/legacy/index.ts | 2 - .../create-jest-preset.spec.ts.snap | 8 ++-- src/presets/create-jest-preset.spec.ts | 9 +++- src/presets/create-jest-preset.ts | 10 ++++- website/docs/getting-started/presets.md | 28 +++++++++---- website/docs/guides/esm-support.md | 6 +++ 16 files changed, 134 insertions(+), 26 deletions(-) create mode 100644 presets/default-esm-legacy/jest-preset.js create mode 100644 presets/default-legacy/jest-preset.js create mode 100644 presets/js-with-babel-esm-legacy/jest-preset.js create mode 100644 presets/js-with-babel-legacy/jest-preset.js create mode 100644 presets/js-with-ts-esm-legacy/jest-preset.js create mode 100644 presets/js-with-ts-legacy/jest-preset.js diff --git a/e2e/presets/__tests__/presets.spec.ts b/e2e/presets/__tests__/presets.spec.ts index a97429dee9..6339be19ab 100644 --- a/e2e/presets/__tests__/presets.spec.ts +++ b/e2e/presets/__tests__/presets.spec.ts @@ -9,29 +9,57 @@ test('presets', () => { '^.+\\.tsx?$': 'ts-jest', }, }) + expect(presets.defaultsLegacy).toEqual({ + transform: { + '^.+\\.tsx?$': 'ts-jest/legacy', + }, + }) expect(presets.defaultsESM).toEqual({ extensionsToTreatAsEsm: [...TS_EXT_TO_TREAT_AS_ESM], transform: { '^.+\\.tsx?$': 'ts-jest', }, }) + expect(presets.defaultsESMLegacy).toEqual({ + extensionsToTreatAsEsm: [...TS_EXT_TO_TREAT_AS_ESM], + transform: { + '^.+\\.tsx?$': 'ts-jest/legacy', + }, + }) expect(presets.jsWithTs).toEqual({ transform: { '^.+\\.[tj]sx?$': 'ts-jest', }, }) + expect(presets.jsWithTsLegacy).toEqual({ + transform: { + '^.+\\.[tj]sx?$': 'ts-jest/legacy', + }, + }) expect(presets.jsWithTsESM).toEqual({ extensionsToTreatAsEsm: [...JS_EXT_TO_TREAT_AS_ESM, ...TS_EXT_TO_TREAT_AS_ESM], transform: { '^.+\\.m?[tj]sx?$': 'ts-jest', }, }) + expect(presets.jsWithTsESMLegacy).toEqual({ + extensionsToTreatAsEsm: [...JS_EXT_TO_TREAT_AS_ESM, ...TS_EXT_TO_TREAT_AS_ESM], + transform: { + '^.+\\.m?[tj]sx?$': 'ts-jest/legacy', + }, + }) expect(presets.jsWithBabel).toEqual({ transform: { '^.+\\.tsx?$': 'ts-jest', '^.+\\.jsx?$': 'babel-jest', }, }) + expect(presets.jsWithBabelLegacy).toEqual({ + transform: { + '^.+\\.tsx?$': 'ts-jest/legacy', + '^.+\\.jsx?$': 'babel-jest', + }, + }) expect(presets.jsWithBabelESM).toEqual({ extensionsToTreatAsEsm: [...JS_EXT_TO_TREAT_AS_ESM, ...TS_EXT_TO_TREAT_AS_ESM], transform: { @@ -39,4 +67,11 @@ test('presets', () => { '^.+\\.m?[j]sx?$': 'babel-jest', }, }) + expect(presets.jsWithBabelESMLegacy).toEqual({ + extensionsToTreatAsEsm: [...JS_EXT_TO_TREAT_AS_ESM, ...TS_EXT_TO_TREAT_AS_ESM], + transform: { + '^.+\\.tsx?$': 'ts-jest/legacy', + '^.+\\.m?[j]sx?$': 'babel-jest', + }, + }) }) diff --git a/presets/default-esm-legacy/jest-preset.js b/presets/default-esm-legacy/jest-preset.js new file mode 100644 index 0000000000..e69ddb95c7 --- /dev/null +++ b/presets/default-esm-legacy/jest-preset.js @@ -0,0 +1 @@ +module.exports = require('..').defaultsESMLegacy diff --git a/presets/default-legacy/jest-preset.js b/presets/default-legacy/jest-preset.js new file mode 100644 index 0000000000..7b1cede23b --- /dev/null +++ b/presets/default-legacy/jest-preset.js @@ -0,0 +1 @@ +module.exports = require('..').defaultsLegacy diff --git a/presets/index.d.ts b/presets/index.d.ts index c61abe9dd8..84383d9716 100644 --- a/presets/index.d.ts +++ b/presets/index.d.ts @@ -2,10 +2,16 @@ import type { TsJestPresets } from '../dist' declare const _default: { defaults: TsJestPresets; + defaultsLegacy: TsJestPresets; defaultsESM: TsJestPresets; + defaultsESMLegacy: TsJestPresets; jsWithTs: TsJestPresets; + jsWithTsLegacy: TsJestPresets; jsWithTsESM: TsJestPresets; + jsWithTsESMLegacy: TsJestPresets; jsWithBabel: TsJestPresets; + jsWithBabelLegacy: TsJestPresets; jsWithBabelESM: TsJestPresets; + jsWithBabelESMLegacy: TsJestPresets; }; export = _default; diff --git a/presets/index.js b/presets/index.js index 07eedbbca6..b000651d2b 100644 --- a/presets/index.js +++ b/presets/index.js @@ -5,24 +5,55 @@ module.exports = { get defaults() { return createJestPreset() }, + get defaultsLegacy() { + return createJestPreset(true, false) + }, get defaultsESM() { - return createJestPreset(false, { extensionsToTreatAsEsm: TS_EXT_TO_TREAT_AS_ESM }) + return createJestPreset(false, false, { extensionsToTreatAsEsm: TS_EXT_TO_TREAT_AS_ESM }) + }, + get defaultsESMLegacy() { + return createJestPreset(true, false, { extensionsToTreatAsEsm: TS_EXT_TO_TREAT_AS_ESM }) }, get jsWithTs() { - return createJestPreset(true) + return createJestPreset(false, true) + }, + get jsWithTsLegacy() { + return createJestPreset(true, true) }, get jsWithTsESM() { - return createJestPreset(true, { extensionsToTreatAsEsm: [...JS_EXT_TO_TREAT_AS_ESM, ...TS_EXT_TO_TREAT_AS_ESM] }) + return createJestPreset(false, true, { + extensionsToTreatAsEsm: [...JS_EXT_TO_TREAT_AS_ESM, ...TS_EXT_TO_TREAT_AS_ESM], + }) + }, + get jsWithTsESMLegacy() { + return createJestPreset(true, true, { + extensionsToTreatAsEsm: [...JS_EXT_TO_TREAT_AS_ESM, ...TS_EXT_TO_TREAT_AS_ESM], + }) }, get jsWithBabel() { - return createJestPreset(false, { + return createJestPreset(false, false, { + transform: { + '^.+\\.jsx?$': 'babel-jest', + }, + }) + }, + get jsWithBabelLegacy() { + return createJestPreset(true, false, { transform: { '^.+\\.jsx?$': 'babel-jest', }, }) }, get jsWithBabelESM() { - return createJestPreset(false, { + return createJestPreset(false, false, { + extensionsToTreatAsEsm: [...JS_EXT_TO_TREAT_AS_ESM, ...TS_EXT_TO_TREAT_AS_ESM], + transform: { + '^.+\\.m?[j]sx?$': 'babel-jest', + }, + }) + }, + get jsWithBabelESMLegacy() { + return createJestPreset(true, false, { extensionsToTreatAsEsm: [...JS_EXT_TO_TREAT_AS_ESM, ...TS_EXT_TO_TREAT_AS_ESM], transform: { '^.+\\.m?[j]sx?$': 'babel-jest', diff --git a/presets/js-with-babel-esm-legacy/jest-preset.js b/presets/js-with-babel-esm-legacy/jest-preset.js new file mode 100644 index 0000000000..33062408fc --- /dev/null +++ b/presets/js-with-babel-esm-legacy/jest-preset.js @@ -0,0 +1 @@ +module.exports = require('..').jsWithBabelESMLegacy diff --git a/presets/js-with-babel-legacy/jest-preset.js b/presets/js-with-babel-legacy/jest-preset.js new file mode 100644 index 0000000000..a2d5ff8b3f --- /dev/null +++ b/presets/js-with-babel-legacy/jest-preset.js @@ -0,0 +1 @@ +module.exports = require('..').jsWithBabelLegacy diff --git a/presets/js-with-ts-esm-legacy/jest-preset.js b/presets/js-with-ts-esm-legacy/jest-preset.js new file mode 100644 index 0000000000..592e02c962 --- /dev/null +++ b/presets/js-with-ts-esm-legacy/jest-preset.js @@ -0,0 +1 @@ +module.exports = require('..').jsWithTsESMLegacy diff --git a/presets/js-with-ts-legacy/jest-preset.js b/presets/js-with-ts-legacy/jest-preset.js new file mode 100644 index 0000000000..76cb70f0b9 --- /dev/null +++ b/presets/js-with-ts-legacy/jest-preset.js @@ -0,0 +1 @@ +module.exports = require('..').jsWithTsLegacy diff --git a/src/index.ts b/src/index.ts index 01267d7450..6e5eb70972 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,12 +1,13 @@ -import { TsJestTransformer } from './legacy' +import { TsJestTransformer } from './legacy/ts-jest-transformer' -export * from './legacy' +export * from './config' export * from './constants' export * from './legacy/compiler' -export * from './config' +export * from './legacy/ts-jest-transformer' +export * from './legacy/config/config-set' export * from './presets/create-jest-preset' -export * from './utils' export * from './raw-compiler-options' +export * from './utils' export * from './types' export default { diff --git a/src/legacy/index.ts b/src/legacy/index.ts index cd4424988c..9cfb6e5d73 100644 --- a/src/legacy/index.ts +++ b/src/legacy/index.ts @@ -1,7 +1,5 @@ import { TsJestTransformer } from './ts-jest-transformer' -export * from './ts-jest-transformer' - export default { createTransformer: (): TsJestTransformer => new TsJestTransformer(), } diff --git a/src/presets/__snapshots__/create-jest-preset.spec.ts.snap b/src/presets/__snapshots__/create-jest-preset.spec.ts.snap index 2f8d12dbd7..7d28dbdb8b 100644 --- a/src/presets/__snapshots__/create-jest-preset.spec.ts.snap +++ b/src/presets/__snapshots__/create-jest-preset.spec.ts.snap @@ -3,7 +3,7 @@ exports[`create-jest-preset should return correct preset 1`] = ` Object { "transform": Object { - "^.+\\\\.tsx?$": "ts-jest", + "^.+\\\\.tsx?$": "ts-jest/legacy", }, } `; @@ -19,7 +19,7 @@ Object { exports[`create-jest-preset should return correct preset 3`] = ` Object { "transform": Object { - "^.+\\\\.[tj]sx?$": "ts-jest", + "^.+\\\\.[tj]sx?$": "ts-jest/legacy", }, } `; @@ -35,7 +35,7 @@ Object { exports[`create-jest-preset should return correct preset 5`] = ` Object { "transform": Object { - "^.+\\\\.tsx?$": "ts-jest", + "^.+\\\\.tsx?$": "ts-jest/legacy", }, } `; @@ -69,7 +69,7 @@ Object { "foo", ], "transform": Object { - "^.+\\\\.m?[tj]sx?$": "ts-jest", + "^.+\\\\.m?[tj]sx?$": "ts-jest/legacy", "foo": "bar", }, } diff --git a/src/presets/create-jest-preset.spec.ts b/src/presets/create-jest-preset.spec.ts index e8267b8fda..a4b7d424da 100644 --- a/src/presets/create-jest-preset.spec.ts +++ b/src/presets/create-jest-preset.spec.ts @@ -11,30 +11,37 @@ describe('create-jest-preset', () => { test.each([ { + legacy: true, allowJs: undefined, extraOptions: undefined, }, { + legacy: false, allowJs: false, extraOptions: undefined, }, { + legacy: true, allowJs: true, extraOptions: undefined, }, { + legacy: false, allowJs: true, extraOptions: {}, }, { + legacy: true, allowJs: false, extraOptions: {}, }, { + legacy: false, allowJs: false, extraOptions: baseExtraOptions, }, { + legacy: true, allowJs: true, extraOptions: { ...baseExtraOptions, @@ -42,6 +49,6 @@ describe('create-jest-preset', () => { }, }, ])('should return correct preset', (data) => { - expect(createJestPreset(data.allowJs, data.extraOptions)).toMatchSnapshot() + expect(createJestPreset(data.legacy, data.allowJs, data.extraOptions)).toMatchSnapshot() }) }) diff --git a/src/presets/create-jest-preset.ts b/src/presets/create-jest-preset.ts index 0cf13af314..aff2cf649b 100644 --- a/src/presets/create-jest-preset.ts +++ b/src/presets/create-jest-preset.ts @@ -5,7 +5,11 @@ import { rootLogger } from '../utils' const logger = rootLogger.child({ namespace: 'jest-preset' }) -export function createJestPreset(allowJs = false, extraOptions: Config.InitialOptions = {}): TsJestPresets { +export function createJestPreset( + legacy = false, + allowJs = false, + extraOptions: Config.InitialOptions = {}, +): TsJestPresets { logger.debug({ allowJs }, 'creating jest presets', allowJs ? 'handling' : 'not handling', 'JavaScript files') const { extensionsToTreatAsEsm, moduleFileExtensions, testMatch } = extraOptions @@ -17,7 +21,9 @@ export function createJestPreset(allowJs = false, extraOptions: Config.InitialOp ...(testMatch ? { testMatch } : undefined), transform: { ...extraOptions.transform, - [allowJs ? (supportESM ? '^.+\\.m?[tj]sx?$' : '^.+\\.[tj]sx?$') : '^.+\\.tsx?$']: 'ts-jest', + [allowJs ? (supportESM ? '^.+\\.m?[tj]sx?$' : '^.+\\.[tj]sx?$') : '^.+\\.tsx?$']: legacy + ? 'ts-jest/legacy' + : 'ts-jest', }, } } diff --git a/website/docs/getting-started/presets.md b/website/docs/getting-started/presets.md index be43edb499..6a70d9d03d 100644 --- a/website/docs/getting-started/presets.md +++ b/website/docs/getting-started/presets.md @@ -5,16 +5,28 @@ title: Presets ### The presets +:::important + +Starting from **v28.0.0**, `ts-jest` will gradually switch to `esbuild`/`swc` to transform `ts` to `js`. To make the transition smoothly, we introduce `legacy` presets as a fallback when the new codes don't work yet. + +::: + `ts-jest` comes with several presets, covering most of the project's base configuration: -| Preset name | Description | -| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `ts-jest/presets/default`
or `ts-jest` | TypeScript files (`.ts`, `.tsx`) will be transformed by `ts-jest` to **CommonJS** syntax, leaving JavaScript files (`.js`, `jsx`) as-is. | -| `ts-jest/presets/default-esm`
| TypeScript files (`.ts`, `.tsx`) will be transformed by `ts-jest` to **ESM** syntax, leaving JavaScript files (`.js`, `jsx`) as-is. | -| `ts-jest/presets/js-with-ts` | TypeScript and JavaScript files (`.ts`, `.tsx`, `.js`, `.jsx`) will be transformed by `ts-jest` to **CommonJS** syntax.
You'll need to set `allowJs` to `true` in your `tsconfig.json` file. | -| `ts-jest/presets/js-with-ts-esm` | TypeScript and JavaScript files (`.ts`, `.tsx`, `.js`, `.jsx`, `.mjs`) will be transformed by `ts-jest` to **ESM** syntax.
You'll need to set `allowJs` to `true` in your `tsconfig.json` file. | -| `ts-jest/presets/js-with-babel` | TypeScript files (`.ts`, `.tsx`) will be transformed by `ts-jest` to **CommonJS** syntax, and JavaScript files (`.js`, `jsx`) will be transformed by `babel-jest`. | -| `ts-jest/presets/js-with-babel-esm` | TypeScript files (`.ts`, `.tsx`) will be transformed by `ts-jest` to **ESM** syntax, and JavaScript files (`.js`, `jsx`, `.mjs`) will be transformed by `babel-jest`. | +| Preset name | Description | +| --------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `ts-jest/presets/default`
or `ts-jest` | TypeScript files (`.ts`, `.tsx`) will be transformed by `ts-jest` to **CommonJS** syntax, leaving JavaScript files (`.js`, `jsx`) as-is. | +| `ts-jest/presets/default-legacy`
or `ts-jest/legacy` (**LEGACY**) | TypeScript files (`.ts`, `.tsx`) will be transformed by `ts-jest` to **CommonJS** syntax, leaving JavaScript files (`.js`, `jsx`) as-is. | +| `ts-jest/presets/default-esm`
| TypeScript files (`.ts`, `.tsx`) will be transformed by `ts-jest` to **ESM** syntax, leaving JavaScript files (`.js`, `jsx`) as-is. | +| `ts-jest/presets/default-esm-legacy`
(**LEGACY**) | TypeScript files (`.ts`, `.tsx`) will be transformed by `ts-jest` to **ESM** syntax, leaving JavaScript files (`.js`, `jsx`) as-is. | +| `ts-jest/presets/js-with-ts` | TypeScript and JavaScript files (`.ts`, `.tsx`, `.js`, `.jsx`) will be transformed by `ts-jest` to **CommonJS** syntax.
You'll need to set `allowJs` to `true` in your `tsconfig.json` file. | +| `ts-jest/presets/js-with-ts-legacy` (**LEGACY**) | TypeScript and JavaScript files (`.ts`, `.tsx`, `.js`, `.jsx`) will be transformed by `ts-jest` to **CommonJS** syntax.
You'll need to set `allowJs` to `true` in your `tsconfig.json` file. | +| `ts-jest/presets/js-with-ts-esm` | TypeScript and JavaScript files (`.ts`, `.tsx`, `.js`, `.jsx`, `.mjs`) will be transformed by `ts-jest` to **ESM** syntax.
You'll need to set `allowJs` to `true` in your `tsconfig.json` file. | +| `ts-jest/presets/js-with-ts-esm-legacy` (**LEGACY**) | TypeScript and JavaScript files (`.ts`, `.tsx`, `.js`, `.jsx`, `.mjs`) will be transformed by `ts-jest` to **ESM** syntax.
You'll need to set `allowJs` to `true` in your `tsconfig.json` file. | +| `ts-jest/presets/js-with-babel` | TypeScript files (`.ts`, `.tsx`) will be transformed by `ts-jest` to **CommonJS** syntax, and JavaScript files (`.js`, `jsx`) will be transformed by `babel-jest`. | +| `ts-jest/presets/js-with-babel-legacy` (**LEGACY**) | TypeScript files (`.ts`, `.tsx`) will be transformed by `ts-jest` to **CommonJS** syntax, and JavaScript files (`.js`, `jsx`) will be transformed by `babel-jest`. | +| `ts-jest/presets/js-with-babel-esm` | TypeScript files (`.ts`, `.tsx`) will be transformed by `ts-jest` to **ESM** syntax, and JavaScript files (`.js`, `jsx`, `.mjs`) will be transformed by `babel-jest`. | +| `ts-jest/presets/js-with-babel-esm-legacy` (**LEGACY**) | TypeScript files (`.ts`, `.tsx`) will be transformed by `ts-jest` to **ESM** syntax, and JavaScript files (`.js`, `jsx`, `.mjs`) will be transformed by `babel-jest`. | ### Basic usage diff --git a/website/docs/guides/esm-support.md b/website/docs/guides/esm-support.md index e7a3ce2fbd..b9d0a36392 100644 --- a/website/docs/guides/esm-support.md +++ b/website/docs/guides/esm-support.md @@ -54,6 +54,12 @@ module.exports = { #### Use ESM presets +:::important + +Starting from **v28.0.0**, `ts-jest` will gradually switch to `esbuild`/`swc` to transform `ts` to `js`. To make the transition smoothly, we introduce `legacy` presets as a fallback when the new codes don't work yet. + +::: + ```js // jest.config.js module.exports = {