Skip to content

Commit 798d6c0

Browse files
authored
feat(jest-config):Support loading TS config files via docblock loader (#15190)
1 parent 3b0c061 commit 798d6c0

File tree

15 files changed

+491
-78
lines changed

15 files changed

+491
-78
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
- `[jest-config]` Allow loading `jest.config.cts` files ([#14070](https://github.com/facebook/jest/pull/14070))
1515
- `[jest-config]` Added an option to disable `ts-node` typechecking ([#15161](https://github.com/jestjs/jest/pull/15161))
1616
- `[jest-config]` Show `rootDir` in error message when a `preset` fails to load ([#15194](https://github.com/jestjs/jest/pull/15194))
17+
- `[jest-config]` Support loading TS config files using `esbuild-register` via docblock loader ([#15190](https://github.com/jestjs/jest/pull/15190))
1718
- `[@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))
1819
- `[@jest/core]` Add `perfStats` to surface test setup overhead ([#14622](https://github.com/jestjs/jest/pull/14622))
1920
- `[@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))

docs/Configuration.md

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,23 @@ export default async (): Promise<Config> => {
5757

5858
:::tip
5959

60-
To read TypeScript configuration files Jest requires [`ts-node`](https://npmjs.com/package/ts-node). Make sure it is installed in your project.
60+
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.
6161

62-
To read configuration files without typechecking, You can set `JEST_CONFIG_TRANSPILE_ONLY` environment variable to `true` (case insensitive).
62+
```ts title="jest.config.ts"
63+
/** @jest-config-loader ts-node */
64+
// or
65+
/** @jest-config-loader esbuild-register */
66+
67+
import type {Config} from 'jest';
68+
69+
const config: Config = {
70+
verbose: true,
71+
};
72+
73+
export default config;
74+
```
75+
76+
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.
6377

6478
:::
6579

e2e/__tests__/multipleConfigs.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,16 @@ test('multiple configs error can be suppressed by using --config', () => {
3434
);
3535
expect(exitCode).toBe(0);
3636
});
37+
38+
test('should works correctly when using different loaders in different projects', () => {
39+
const {exitCode, stdout, stderr} = runJest(
40+
'multi-project-multiple-configs',
41+
['--projects', 'prj-1', 'prj-2'],
42+
{
43+
skipPkgJsonCheck: true,
44+
},
45+
);
46+
expect(exitCode).toBe(0);
47+
console.log(stdout);
48+
console.log(stderr);
49+
});

e2e/__tests__/readInitialOptions.test.ts

Lines changed: 31 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -46,60 +46,27 @@ describe('readInitialOptions', () => {
4646
expect(config).toEqual({jestConfig: 'jest.config.js', rootDir});
4747
expect(configPath).toEqual(configFile);
4848
});
49-
test('should read a jest.config.js file', async () => {
50-
const configFile = resolveFixture('js-config', 'jest.config.js');
51-
const rootDir = resolveFixture('js-config');
52-
const {config, configPath} = await proxyReadInitialOptions(undefined, {
53-
cwd: rootDir,
54-
});
55-
expect(config).toEqual({jestConfig: 'jest.config.js', rootDir});
56-
expect(configPath).toEqual(configFile);
57-
});
58-
test('should read a package.json file', async () => {
59-
const configFile = resolveFixture('pkg-config', 'package.json');
60-
const rootDir = resolveFixture('pkg-config');
61-
const {config, configPath} = await proxyReadInitialOptions(undefined, {
62-
cwd: rootDir,
63-
});
64-
expect(config).toEqual({jestConfig: 'package.json', rootDir});
65-
expect(configPath).toEqual(configFile);
66-
});
67-
test('should read a jest.config.ts file', async () => {
68-
const configFile = resolveFixture('ts-config', 'jest.config.ts');
69-
const rootDir = resolveFixture('ts-config');
70-
const {config, configPath} = await proxyReadInitialOptions(undefined, {
71-
cwd: rootDir,
72-
});
73-
expect(config).toEqual({jestConfig: 'jest.config.ts', rootDir});
74-
expect(configPath).toEqual(configFile);
75-
});
76-
test('should read a jest.config.mjs file', async () => {
77-
const configFile = resolveFixture('mjs-config', 'jest.config.mjs');
78-
const rootDir = resolveFixture('mjs-config');
79-
const {config, configPath} = await proxyReadInitialOptions(undefined, {
80-
cwd: rootDir,
81-
});
82-
expect(config).toEqual({jestConfig: 'jest.config.mjs', rootDir});
83-
expect(configPath).toEqual(configFile);
84-
});
85-
test('should read a jest.config.json file', async () => {
86-
const configFile = resolveFixture('json-config', 'jest.config.json');
87-
const rootDir = resolveFixture('json-config');
88-
const {config, configPath} = await proxyReadInitialOptions(undefined, {
89-
cwd: rootDir,
90-
});
91-
expect(config).toEqual({jestConfig: 'jest.config.json', rootDir});
92-
expect(configPath).toEqual(configFile);
93-
});
94-
test('should read a jest config exporting an async function', async () => {
95-
const configFile = resolveFixture('async-config', 'jest.config.js');
96-
const rootDir = resolveFixture('async-config');
97-
const {config, configPath} = await proxyReadInitialOptions(undefined, {
98-
cwd: rootDir,
99-
});
100-
expect(config).toEqual({jestConfig: 'async-config', rootDir});
101-
expect(configPath).toEqual(configFile);
102-
});
49+
50+
test.each([
51+
['js-config', 'jest.config.js', 'jest.config.js'],
52+
['pkg-config', 'package.json', 'package.json'],
53+
['ts-node-config', 'jest.config.ts', 'jest.config.ts'],
54+
['ts-esbuild-register-config', 'jest.config.ts', 'jest.config.ts'],
55+
['mjs-config', 'jest.config.mjs', 'jest.config.mjs'],
56+
['json-config', 'jest.config.json', 'jest.config.json'],
57+
['async-config', 'jest.config.js', 'async-config'],
58+
])(
59+
'should read %s/%s file',
60+
async (directory: string, filename: string, configString: string) => {
61+
const configFile = resolveFixture(directory, filename);
62+
const rootDir = resolveFixture(directory);
63+
const {config, configPath} = await proxyReadInitialOptions(undefined, {
64+
cwd: rootDir,
65+
});
66+
expect(config).toEqual({jestConfig: configString, rootDir});
67+
expect(configPath).toEqual(configFile);
68+
},
69+
);
10370

10471
test('should be able to skip config reading, instead read from cwd', async () => {
10572
const expectedConfigFile = resolveFixture(
@@ -121,6 +88,16 @@ describe('readInitialOptions', () => {
12188
expect(configPath).toEqual(expectedConfigFile);
12289
});
12390

91+
test('should give an error when using unsupported loader', async () => {
92+
const cwd = resolveFixture('ts-loader-config');
93+
const error: Error = await proxyReadInitialOptions(undefined, {cwd}).catch(
94+
error => error,
95+
);
96+
expect(error.message).toContain(
97+
"Jest: 'ts-loader' is not a valid TypeScript configuration loader.",
98+
);
99+
});
100+
124101
test('should give an error when there are multiple config files', async () => {
125102
const cwd = resolveFixture('multiple-config-files');
126103
const error: Error = await proxyReadInitialOptions(undefined, {cwd}).catch(

e2e/read-initial-options/ts-config/jest.config.ts renamed to e2e/multi-project-multiple-configs/prj-1/__tests__/test.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*/
7-
export default {
8-
jestConfig: 'jest.config.ts',
9-
};
7+
8+
test('dummy test', () => {
9+
expect(1).toBe(1);
10+
});
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @jest-config-loader esbuild-register
8+
*/
9+
10+
import type {Config} from 'jest';
11+
12+
const config: Config = {
13+
displayName: 'PROJECT 1',
14+
};
15+
16+
export default config;
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
test('dummy test', () => {
9+
expect(2).toBe(2);
10+
});
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @jest-config-loader ts-node
8+
*/
9+
10+
import type {Config} from 'jest';
11+
12+
const config: Config = {
13+
displayName: 'PROJECT 2',
14+
};
15+
16+
export default config;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @jest-config-loader esbuild-register
8+
*/
9+
10+
interface Config {
11+
jestConfig: string;
12+
}
13+
14+
export default {
15+
jestConfig: 'jest.config.ts',
16+
} as Config;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @jest-config-loader ts-loader
8+
*/
9+
10+
interface Config {
11+
jestConfig: string;
12+
}
13+
14+
export default {
15+
jestConfig: 'jest.config.ts',
16+
} as Config;

0 commit comments

Comments
 (0)