From faefd6d8e73794f28eabcaec6c6468b35d8cdec1 Mon Sep 17 00:00:00 2001 From: Rajat v Date: Fri, 2 Aug 2024 17:11:22 +0000 Subject: [PATCH 1/5] feat: allow passing tsLoader options --- e2e/__tests__/jest.config.ts.test.ts | 7 ++----- .../jest-config/src/readConfigFileAndSetRootDir.ts | 11 +++++++++-- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/e2e/__tests__/jest.config.ts.test.ts b/e2e/__tests__/jest.config.ts.test.ts index 12e5da4b8bfe..5c5948907dec 100644 --- a/e2e/__tests__/jest.config.ts.test.ts +++ b/e2e/__tests__/jest.config.ts.test.ts @@ -84,6 +84,7 @@ const jestTypesExists = fs.existsSync(jestTypesPath); writeFiles(DIR, { '__tests__/a-giraffe.js': "test('giraffe', () => expect(1).toBe(1));", 'jest.config.ts': ` + /**@jest-config-loader-options {"transpileOnly":${!!skipTypeCheck}}*/ import {Config} from 'jest'; const config: Config = { testTimeout: "10000" }; export default config; @@ -95,11 +96,7 @@ const jestTypesExists = fs.existsSync(jestTypesPath); "TS2322: Type 'string' is not assignable to type 'number'."; const runtimeErrorString = 'Option "testTimeout" must be of type:'; - const {stderr, exitCode} = runJest(DIR, ['-w=1', '--ci=false'], { - env: { - JEST_CONFIG_TRANSPILE_ONLY: skipTypeCheck ? 'true' : undefined, - }, - }); + const {stderr, exitCode} = runJest(DIR, ['-w=1', '--ci=false']); if (skipTypeCheck) { expect(stderr).not.toMatch(typeErrorString); diff --git a/packages/jest-config/src/readConfigFileAndSetRootDir.ts b/packages/jest-config/src/readConfigFileAndSetRootDir.ts index d232bcd37db1..6ffe4ff3234e 100644 --- a/packages/jest-config/src/readConfigFileAndSetRootDir.ts +++ b/packages/jest-config/src/readConfigFileAndSetRootDir.ts @@ -10,6 +10,7 @@ import {isNativeError} from 'util/types'; import * as fs from 'graceful-fs'; import parseJson = require('parse-json'); import stripJsonComments = require('strip-json-comments'); +import type {RegisterOptions} from 'ts-node'; import type {Config} from '@jest/types'; import {extract, parse} from 'jest-docblock'; import {interopRequireDefault, requireOrImportModule} from 'jest-util'; @@ -89,13 +90,19 @@ export default async function readConfigFileAndSetRootDir( } // Load the TypeScript configuration +let extraTSLoaderOptions: RegisterOptions; + const loadTSConfigFile = async ( configPath: string, ): Promise => { // Get registered TypeScript compiler instance const docblockPragmas = parse(extract(fs.readFileSync(configPath, 'utf8'))); const tsLoader = docblockPragmas['jest-config-loader'] || 'ts-node'; + const docblockTSLoaderOptions = docblockPragmas['jest-config-loader-options']; + if (typeof docblockTSLoaderOptions === 'string') { + extraTSLoaderOptions = JSON.parse(docblockTSLoaderOptions); + } if (Array.isArray(tsLoader)) { throw new TypeError( `Jest: You can only define a single loader through docblocks, got "${tsLoader.join( @@ -143,8 +150,8 @@ async function registerTsLoader(loader: TsLoaderModule): Promise { moduleTypes: { '**': 'cjs', }, - transpileOnly: - process.env.JEST_CONFIG_TRANSPILE_ONLY?.toLowerCase() === 'true', + swc: extraTSLoaderOptions?.swc, + transpileOnly: extraTSLoaderOptions?.transpileOnly, }); } else if (loader === 'esbuild-register') { const tsLoader = await import( From 50c1bb923999bfe48c7162be7bd63121917f1a23 Mon Sep 17 00:00:00 2001 From: Rajat v Date: Sat, 3 Aug 2024 06:12:52 +0000 Subject: [PATCH 2/5] Update CHAGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e6eebcee0126..08fb81e92512 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ### Features +- `[jest-config]` allow passing TS config loader options via docblock comment ([#15234](https://github.com/jestjs/jest/pull/15234)) - `[babel-jest]` Add option `excludeJestPreset` to allow opting out of `babel-preset-jest` ([#15164](https://github.com/jestjs/jest/pull/15164)) - `[jest-circus, jest-cli, jest-config]` Add `waitNextEventLoopTurnForUnhandledRejectionEvents` flag to minimise performance impact of correct detection of unhandled promise rejections introduced in [#14315](https://github.com/jestjs/jest/pull/14315) ([#14681](https://github.com/jestjs/jest/pull/14681)) - `[jest-circus]` Add a `waitBeforeRetry` option to `jest.retryTimes` ([#14738](https://github.com/jestjs/jest/pull/14738)) From 7d4de1fe6c4e6932713b5eccf6dce69fb167c59e Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Sat, 3 Aug 2024 13:51:26 +0200 Subject: [PATCH 3/5] Update CHANGELOG.md --- CHANGELOG.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 08fb81e92512..6bb8873f6123 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,6 @@ ### Features -- `[jest-config]` allow passing TS config loader options via docblock comment ([#15234](https://github.com/jestjs/jest/pull/15234)) - `[babel-jest]` Add option `excludeJestPreset` to allow opting out of `babel-preset-jest` ([#15164](https://github.com/jestjs/jest/pull/15164)) - `[jest-circus, jest-cli, jest-config]` Add `waitNextEventLoopTurnForUnhandledRejectionEvents` flag to minimise performance impact of correct detection of unhandled promise rejections introduced in [#14315](https://github.com/jestjs/jest/pull/14315) ([#14681](https://github.com/jestjs/jest/pull/14681)) - `[jest-circus]` Add a `waitBeforeRetry` option to `jest.retryTimes` ([#14738](https://github.com/jestjs/jest/pull/14738)) @@ -13,9 +12,9 @@ - `[jest-config]` [**BREAKING**] Update `testMatch` and `testRegex` default option for supporting `mjs`, `cjs`, `mts`, and `cts` ([#14584](https://github.com/jestjs/jest/pull/14584)) - `[jest-config]` Loads config file from provided path in `package.json` ([#14044](https://github.com/facebook/jest/pull/14044)) - `[jest-config]` Allow loading `jest.config.cts` files ([#14070](https://github.com/facebook/jest/pull/14070)) -- `[jest-config]` Added an option to disable `ts-node` typechecking ([#15161](https://github.com/jestjs/jest/pull/15161)) - `[jest-config]` Show `rootDir` in error message when a `preset` fails to load ([#15194](https://github.com/jestjs/jest/pull/15194)) - `[jest-config]` Support loading TS config files using `esbuild-register` via docblock loader ([#15190](https://github.com/jestjs/jest/pull/15190)) +- `[jest-config]` allow passing TS config loader options via docblock comment ([#15234](https://github.com/jestjs/jest/pull/15234)) - `[@jest/core]` Group together open handles with the same stack trace ([#13417](https://github.com/jestjs/jest/pull/13417), & [#14789](https://github.com/jestjs/jest/pull/14789)) - `[@jest/core]` Add `perfStats` to surface test setup overhead ([#14622](https://github.com/jestjs/jest/pull/14622)) - `[@jest/core]` [**BREAKING**] Changed `--filter` to accept an object with shape `{ filtered: Array }` to match [documentation](https://jestjs.io/docs/cli#--filterfile) ([#13319](https://github.com/jestjs/jest/pull/13319)) From 9caaf3c8247bfe70b40e9a0b95bc97cf6e0af6a4 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Sat, 3 Aug 2024 13:53:40 +0200 Subject: [PATCH 4/5] Update Configuration.md --- docs/Configuration.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/docs/Configuration.md b/docs/Configuration.md index c73a1fcaa6f5..1ca9a15e1341 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -73,7 +73,20 @@ const config: Config = { export default config; ``` -If you are using `ts-node`, you can set `JEST_CONFIG_TRANSPILE_ONLY` environment variable to `true` (case insensitive) to read configuration files without typechecking. +You can also pass options to the loader, for instance to enable `transpileOnly`. + +```ts title="jest.config.ts" +/** @jest-config-loader ts-node */ +/** @jest-config-loader-options {"transpileOnly": true} */ + +import type {Config} from 'jest'; + +const config: Config = { + verbose: true, +}; + +export default config; +``` ::: From 422348953d0cde3f0d751002a43fc3871345cd5c Mon Sep 17 00:00:00 2001 From: Rajat v Date: Sun, 4 Aug 2024 05:55:03 +0000 Subject: [PATCH 5/5] expose all options via docblock comment --- packages/jest-config/src/readConfigFileAndSetRootDir.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/jest-config/src/readConfigFileAndSetRootDir.ts b/packages/jest-config/src/readConfigFileAndSetRootDir.ts index 6ffe4ff3234e..01a705f10620 100644 --- a/packages/jest-config/src/readConfigFileAndSetRootDir.ts +++ b/packages/jest-config/src/readConfigFileAndSetRootDir.ts @@ -10,7 +10,6 @@ import {isNativeError} from 'util/types'; import * as fs from 'graceful-fs'; import parseJson = require('parse-json'); import stripJsonComments = require('strip-json-comments'); -import type {RegisterOptions} from 'ts-node'; import type {Config} from '@jest/types'; import {extract, parse} from 'jest-docblock'; import {interopRequireDefault, requireOrImportModule} from 'jest-util'; @@ -90,7 +89,7 @@ export default async function readConfigFileAndSetRootDir( } // Load the TypeScript configuration -let extraTSLoaderOptions: RegisterOptions; +let extraTSLoaderOptions: Record; const loadTSConfigFile = async ( configPath: string, @@ -150,8 +149,7 @@ async function registerTsLoader(loader: TsLoaderModule): Promise { moduleTypes: { '**': 'cjs', }, - swc: extraTSLoaderOptions?.swc, - transpileOnly: extraTSLoaderOptions?.transpileOnly, + ...extraTSLoaderOptions, }); } else if (loader === 'esbuild-register') { const tsLoader = await import( @@ -165,6 +163,7 @@ async function registerTsLoader(loader: TsLoaderModule): Promise { if (bool) { instance = tsLoader.register({ target: `node${process.version.slice(1)}`, + ...extraTSLoaderOptions, }); } else { instance?.unregister();