Skip to content
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
- `[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]` Support loading TS config files using `esbuild-register` via docblock loader ([#15190](https://github.com/jestjs/jest/pull/15190))
- `[@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<string> }` to match [documentation](https://jestjs.io/docs/cli#--filterfile) ([#13319](https://github.com/jestjs/jest/pull/13319))
Expand Down
18 changes: 16 additions & 2 deletions docs/Configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,23 @@ export default async (): Promise<Config> => {

:::tip

To read TypeScript configuration files Jest requires [`ts-node`](https://npmjs.com/package/ts-node). Make sure it is installed in your project.
To read TypeScript configuration files Jest by default requires [`ts-node`](https://npmjs.com/package/ts-node). You can override this behavior by adding a `@jest-config-loader` docblock at the top of the file. Currently, [`ts-node`](https://npmjs.com/package/ts-node) and [`esbuild-register`](https://npmjs.com/package/esbuild-register) is supported. Make sure `ts-node` or the loader you specify is installed.

To read configuration files without typechecking, You can set `JEST_CONFIG_TRANSPILE_ONLY` environment variable to `true` (case insensitive).
```ts title="jest.config.ts"
/** @jest-config-loader ts-node */
// or
/** @jest-config-loader esbuild-register */

import type {Config} from 'jest';

const config: Config = {
verbose: true,
};

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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not for this PR, but maybe in a follow-up - should we drop this new env variable and use docblock config instead (like we support for test environment: https://jestjs.io/blog/2022/04/25/jest-28#inline-testenvironmentoptions)? Then people could also e.g. opt into using swc (https://typestrong.org/ts-node/docs/swc/)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that would be better, will send PR for that
we might also need to add support for swc based loader at some point #12156


:::

Expand Down
12 changes: 12 additions & 0 deletions e2e/__tests__/multipleConfigs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,15 @@ test('multiple configs error can be suppressed by using --config', () => {
);
expect(exitCode).toBe(0);
});
test('should works correctly when using different loaders in different projects', () => {
const {exitCode, stdout, stderr} = runJest(
'multi-project-multiple-configs',
['--projects', 'prj-1', 'prj-2'],
{
skipPkgJsonCheck: true,
},
);
expect(exitCode).toBe(0);
console.log(stdout);
console.log(stderr);
});
84 changes: 29 additions & 55 deletions e2e/__tests__/readInitialOptions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,60 +46,26 @@ describe('readInitialOptions', () => {
expect(config).toEqual({jestConfig: 'jest.config.js', rootDir});
expect(configPath).toEqual(configFile);
});
test('should read a jest.config.js file', async () => {
const configFile = resolveFixture('js-config', 'jest.config.js');
const rootDir = resolveFixture('js-config');
const {config, configPath} = await proxyReadInitialOptions(undefined, {
cwd: rootDir,
});
expect(config).toEqual({jestConfig: 'jest.config.js', rootDir});
expect(configPath).toEqual(configFile);
});
test('should read a package.json file', async () => {
const configFile = resolveFixture('pkg-config', 'package.json');
const rootDir = resolveFixture('pkg-config');
const {config, configPath} = await proxyReadInitialOptions(undefined, {
cwd: rootDir,
});
expect(config).toEqual({jestConfig: 'package.json', rootDir});
expect(configPath).toEqual(configFile);
});
test('should read a jest.config.ts file', async () => {
const configFile = resolveFixture('ts-config', 'jest.config.ts');
const rootDir = resolveFixture('ts-config');
const {config, configPath} = await proxyReadInitialOptions(undefined, {
cwd: rootDir,
});
expect(config).toEqual({jestConfig: 'jest.config.ts', rootDir});
expect(configPath).toEqual(configFile);
});
test('should read a jest.config.mjs file', async () => {
const configFile = resolveFixture('mjs-config', 'jest.config.mjs');
const rootDir = resolveFixture('mjs-config');
const {config, configPath} = await proxyReadInitialOptions(undefined, {
cwd: rootDir,
});
expect(config).toEqual({jestConfig: 'jest.config.mjs', rootDir});
expect(configPath).toEqual(configFile);
});
test('should read a jest.config.json file', async () => {
const configFile = resolveFixture('json-config', 'jest.config.json');
const rootDir = resolveFixture('json-config');
const {config, configPath} = await proxyReadInitialOptions(undefined, {
cwd: rootDir,
});
expect(config).toEqual({jestConfig: 'jest.config.json', rootDir});
expect(configPath).toEqual(configFile);
});
test('should read a jest config exporting an async function', async () => {
const configFile = resolveFixture('async-config', 'jest.config.js');
const rootDir = resolveFixture('async-config');
const {config, configPath} = await proxyReadInitialOptions(undefined, {
cwd: rootDir,
});
expect(config).toEqual({jestConfig: 'async-config', rootDir});
expect(configPath).toEqual(configFile);
});
test.each([
['js-config', 'jest.config.js', 'jest.config.js'],
['pkg-config', 'package.json', 'package.json'],
['ts-node-config', 'jest.config.ts', 'jest.config.ts'],
['ts-esbuild-register-config', 'jest.config.ts', 'jest.config.ts'],
['mjs-config', 'jest.config.mjs', 'jest.config.mjs'],
['json-config', 'jest.config.json', 'jest.config.json'],
['async-config', 'jest.config.js', 'async-config'],
])(
'should read %s/%s file',
async (directory: string, filename: string, configString: string) => {
const configFile = resolveFixture(directory, filename);
const rootDir = resolveFixture(directory);
const {config, configPath} = await proxyReadInitialOptions(undefined, {
cwd: rootDir,
});
expect(config).toEqual({jestConfig: configString, rootDir});
expect(configPath).toEqual(configFile);
},
);

test('should be able to skip config reading, instead read from cwd', async () => {
const expectedConfigFile = resolveFixture(
Expand All @@ -120,7 +86,15 @@ describe('readInitialOptions', () => {
});
expect(configPath).toEqual(expectedConfigFile);
});

test('should give an error when using unsupported loader', async () => {
const cwd = resolveFixture('ts-loader-config');
const error: Error = await proxyReadInitialOptions(undefined, {cwd}).catch(
error => error,
);
expect(error.message).toContain(
"Jest: 'ts-loader' is not a valid TypeScript configuration loader.",
);
});
test('should give an error when there are multiple config files', async () => {
const cwd = resolveFixture('multiple-config-files');
const error: Error = await proxyReadInitialOptions(undefined, {cwd}).catch(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
export default {
jestConfig: 'jest.config.ts',
};

test('dummy test', () => {
expect(1).toBe(1);
});
16 changes: 16 additions & 0 deletions e2e/multi-project-multiple-configs/prj-1/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @jest-config-loader esbuild-register
*/

import type {Config} from 'jest';

const config: Config = {
displayName: 'PROJECT 1',
};

export default config;
10 changes: 10 additions & 0 deletions e2e/multi-project-multiple-configs/prj-2/__tests__/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

test('dummy test', () => {
expect(2).toBe(2);
});
16 changes: 16 additions & 0 deletions e2e/multi-project-multiple-configs/prj-2/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @jest-config-loader ts-node
*/

import type {Config} from 'jest';

const config: Config = {
displayName: 'PROJECT 2',
};

export default config;
16 changes: 16 additions & 0 deletions e2e/read-initial-options/ts-esbuild-register-config/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @jest-config-loader esbuild-register
*/

interface Config {
jestConfig: string;
}

export default {
jestConfig: 'jest.config.ts',
} as Config;
16 changes: 16 additions & 0 deletions e2e/read-initial-options/ts-loader-config/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @jest-config-loader ts-loader
*/

interface Config {
jestConfig: string;
}

export default {
jestConfig: 'jest.config.ts',
} as Config;
16 changes: 16 additions & 0 deletions e2e/read-initial-options/ts-node-config/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @jest-config-loader ts-node
*/

interface Config {
jestConfig: string;
}

export default {
jestConfig: 'jest.config.ts',
} as Config;
2 changes: 2 additions & 0 deletions e2e/typescript-config/modern-module-resolution/jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @jest-config-loader esbuild-register
*/

const config = {
Expand Down
7 changes: 7 additions & 0 deletions packages/jest-config/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,16 @@
},
"peerDependencies": {
"@types/node": "*",
"esbuild-register": ">=3.4.0",
"ts-node": ">=9.0.0"
},
"peerDependenciesMeta": {
"@types/node": {
"optional": true
},
"esbuild-register": {
"optional": true
},
"ts-node": {
"optional": true
}
Expand All @@ -42,6 +46,7 @@
"glob": "^10.3.10",
"graceful-fs": "^4.2.9",
"jest-circus": "workspace:*",
"jest-docblock": "workspace:*",
"jest-environment-node": "workspace:*",
"jest-get-type": "workspace:*",
"jest-regex-util": "workspace:*",
Expand All @@ -59,6 +64,8 @@
"@types/graceful-fs": "^4.1.3",
"@types/micromatch": "^4.0.7",
"@types/parse-json": "^4.0.0",
"esbuild": "^0.23.0",
"esbuild-register": "^3.4.0",
"semver": "^7.5.3",
"ts-node": "^10.5.0",
"typescript": "^5.0.4"
Expand Down
Loading