Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(ts-config): pass moduleTypes to enforce CJS for TS config file #12397

Merged
merged 10 commits into from Feb 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Expand Up @@ -17,8 +17,9 @@

- `[expect]` Move typings of `.not`, `.rejects` and `.resolves` modifiers outside of `Matchers` interface ([#12346](https://github.com/facebook/jest/pull/12346))
- `[expect]` Expose `AsymmetricMatchers` and `RawMatcherFn` interfaces ([#12363](https://github.com/facebook/jest/pull/12363))
- `[jest-environment-jsdom]` Make `jsdom` accessible to extending environments again ([#12232](https://github.com/facebook/jest/pull/12232))
- `[jest-config]` Correctly detect CI environment and update snapshots accordingly ([#12378](https://github.com/facebook/jest/pull/12378))
- `[jest-config]` Pass `moduleTypes` to `ts-node` to enforce CJS when transpiling ([#12397](https://github.com/facebook/jest/pull/12397))
- `[jest-environment-jsdom]` Make `jsdom` accessible to extending environments again ([#12232](https://github.com/facebook/jest/pull/12232))
- `[jest-jasmine2, jest-types]` [**BREAKING**] Move all `jasmine` specific types from `@jest/types` to its own package ([#12125](https://github.com/facebook/jest/pull/12125))

### Chore & Maintenance
Expand Down
33 changes: 33 additions & 0 deletions e2e/__tests__/esmConfigFile.test.ts
Expand Up @@ -5,6 +5,9 @@
* LICENSE file in the root directory of this source tree.
*/

import {resolve} from 'path';
import execa = require('execa');
import {existsSync} from 'graceful-fs';
import {onNodeVersions} from '@jest/test-utils';
import {getConfig} from '../runJest';

Expand Down Expand Up @@ -44,4 +47,34 @@ onNodeVersions('>=12.17.0', () => {
name: 'Config from js file',
});
});

describe('typescript', () => {
beforeAll(async () => {
// the typescript config test needs `@jest/types` to be built
const cwd = resolve(__dirname, '../../');
const typesPackageDirectory = 'packages/jest-types';

const indexDTsFile = resolve(
cwd,
typesPackageDirectory,
'build/index.d.ts',
);

if (!existsSync(indexDTsFile)) {
await execa('tsc', ['-b', typesPackageDirectory], {cwd});
}
}, 60_000);

test('reads config from ts file when package.json#type=module', () => {
const {configs} = getConfig('esm-config/ts', [], {
skipPkgJsonCheck: true,
});

expect(configs).toHaveLength(1);
expect(configs[0].displayName).toEqual({
color: 'white',
name: 'Config from ts file',
});
});
});
});
10 changes: 10 additions & 0 deletions e2e/esm-config/ts/__tests__/test.js
@@ -0,0 +1,10 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
*
* 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(1).toBe(1);
});
15 changes: 15 additions & 0 deletions e2e/esm-config/ts/jest.config.ts
@@ -0,0 +1,15 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import type {Config} from '@jest/types';

const config: Config.InitialOptions = {
displayName: 'Config from ts file',
testEnvironment: 'node',
};

export default () => config;
3 changes: 3 additions & 0 deletions e2e/esm-config/ts/package.json
@@ -0,0 +1,3 @@
{
"type": "module"
}
9 changes: 7 additions & 2 deletions e2e/runJest.ts
Expand Up @@ -266,13 +266,18 @@ export function getConfig(
configs: Array<Config.ProjectConfig>;
version: string;
} {
const {exitCode, stdout} = runJest(
const {exitCode, stdout, stderr} = runJest(
dir,
args.concat('--show-config'),
options,
);

expect(exitCode).toBe(0);
try {
expect(exitCode).toBe(0);
} catch (error) {
console.error('Exit code is not 0', {stderr, stdout});
throw error;
}

return JSON.parse(stdout);
}
43 changes: 28 additions & 15 deletions packages/jest-config/src/readConfigFileAndSetRootDir.ts
Expand Up @@ -84,21 +84,7 @@ const loadTSConfigFile = async (
configPath: Config.Path,
): Promise<Config.InitialOptions> => {
// Register TypeScript compiler instance
try {
registerer ||= require('ts-node').register({
compilerOptions: {
module: 'CommonJS',
},
});
} catch (e: any) {
if (e.code === 'MODULE_NOT_FOUND') {
throw new Error(
`Jest: 'ts-node' is required for the TypeScript configuration files. Make sure it is installed\nError: ${e.message}`,
);
}

throw e;
}
await registerTsNode();

registerer.enabled(true);

Expand All @@ -113,3 +99,30 @@ const loadTSConfigFile = async (

return configObject;
};

async function registerTsNode(): Promise<Service> {
if (registerer) {
return registerer;
}

try {
const tsNode = await import('ts-node');
registerer = tsNode.register({
compilerOptions: {
module: 'CommonJS',
},
moduleTypes: {
'**': 'cjs',
},
});
return registerer;
} catch (e: any) {
if (e.code === 'ERR_MODULE_NOT_FOUND') {
throw new Error(
`Jest: 'ts-node' is required for the TypeScript configuration files. Make sure it is installed\nError: ${e.message}`,
);
}

throw e;
}
}