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

feat: Add support for the jest.config.ts configuration file #10564

Merged
merged 39 commits into from
Oct 12, 2020

Conversation

Gamote
Copy link
Contributor

@Gamote Gamote commented Sep 29, 2020

Summary

Allow developers to define the configuration file using Typescript. This allow a project to be written only in TypeScript and helps with auto-suggestions.

This PR resolves #9636.

Example

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

// Sync object
const config: Config.InitialOptions = {
  verbose: true,
};
export default config;

// Or async function
export default async (): Promise<Config.InitialOptions> => {
  return {
    verbose: true,
  };
};

docs and CHANGELOG.md file were updated to reflect these changes.

Test plan

Tests have been added/updated to check for this behaviour and some messages were updated to indicate to the user about the new supported extension (.ts).

CC: @SimenB

docs/Configuration.md Outdated Show resolved Hide resolved
@dl748
Copy link

dl748 commented Sep 29, 2020

note the "export =" should never be use. It requires the tsconfig.json to use a specific output (commonjs), which may not be what your project intends. "export default" is the correct way, for both async/sync

@Gamote
Copy link
Contributor Author

Gamote commented Sep 29, 2020

note the "export =" should never be use. It requires the tsconfig.json to use a specific output (commonjs), which may not be what your project intends. "export default" is the correct way, for both async/sync

This was my thought as well, but if I'm using export default for objects the config values are added under the default property on compilation. I've tried to stop this behaviour with different configuration but without success. As @G-Rath recommended, I will replace typescript with ts-node and I will try it again. Thanks for the input ✌️

@G-Rath
Copy link
Contributor

G-Rath commented Sep 29, 2020

export = can be fine in some situations, but what you're actually wanting is to use the interop function that'll be around "somewhere" which should make these both worth.

@Gamote
Copy link
Contributor Author

Gamote commented Sep 29, 2020

export = can be fine in some situations, but what you're actually wanting is to use the interop function that'll be around "somewhere" which should make these both worth.

I've tried to add the interlop function but I had the same result. I will see if I have the same problem with the new compilation method.

@G-Rath
Copy link
Contributor

G-Rath commented Sep 29, 2020

Was this the interlop function?

// copied from https://github.com/babel/babel/blob/d8da63c929f2d28c401571e2a43166678c555bc4/packages/babel-helpers/src/helpers.js#L602-L606
/* istanbul ignore next */
const interopRequireDefault = (obj: any): { default: any } =>
  obj && obj.__esModule ? obj : { default: obj };

const importDefault = (moduleName: string) =>
  // eslint-disable-next-line @typescript-eslint/no-require-imports
  interopRequireDefault(require(moduleName)).default;

That's what we've got in eslint-plugin-jest, where we're using export default in place of what technically should be export =.

I think that will break for export = but that's not a very common syntax so I think it's fine to treat export default as the thing to use, since it should always be usable 🙂

@Gamote Gamote marked this pull request as draft September 29, 2020 20:00
@dl748
Copy link

dl748 commented Sep 29, 2020

what i generally do is

const myconfig = require('.....')
if( myconfig.default ) {
  if(typeof(myconfig.default) === 'function') return Promise.resolve(myconfig.default())
  return Promise.resolve(myconfig.default)
}
if(typeof(myconfig) === 'function') return Promise.resolve(myconfig())
return Promise.resolve(myconfig)

that should handle just about every way a module would be exported with a "function".

I'm not partial to empty called functions, so I would generally pass in the object of the code, jest or whatever, so that the configuration file can make decisions based on things like default settings or version specific code.

@G-Rath
Copy link
Contributor

G-Rath commented Sep 29, 2020

@dl748 we shouldn't need to do any of that extra checking unless this PR is also adding the ability to export a function, as that's something jest should already have support for handling.

Effectively what we're wanting to do here is handle just the requireing of the config, which makes things easier - once we've got the config requireed it can just slip into the current flow i.e check if it's a function, validation, apply defaults, use, run tests, 🎉

@dl748
Copy link

dl748 commented Sep 29, 2020

@dl748 we shouldn't need to do any of that extra checking unless this PR is also adding the ability to export a function, as that's something jest should already have support for handling.

Effectively what we're wanting to do here is handle just the requireing of the config, which makes things easier - once we've got the config requireed it can just slip into the current flow i.e check if it's a function, validation, apply defaults, use, run tests, 🎉

Yes I know, i'm just explaining how i've implemented things like interpret, for max compatibility with targeted languages like ES6 and TS

interpret is far more lightweight than importing the entire typescript library.

@Gamote Gamote marked this pull request as ready for review September 29, 2020 23:00
@Gamote Gamote marked this pull request as draft September 29, 2020 23:40
@Gamote Gamote marked this pull request as ready for review September 30, 2020 00:55
@septs
Copy link

septs commented Sep 30, 2020

via globalTeardown and setupFiles also need support load typescript file.

see https://github.com/DimensionDev/Maskbook/blob/9b975f30/jest.config.js#L12-L17

@G-Rath
Copy link
Contributor

G-Rath commented Sep 30, 2020

@septs while we're wanting to support everything, this PR & issue is just for the actual config file itself :)

The global issue we've got open tracking this effort is #8810 - setupFiles are actually already supported, but globalTeardown isn't on that list so I'll update it.

@septs
Copy link

septs commented Sep 30, 2020

@Gamote may be need auto detect esm and auto require esm

see https://npm.im/esm

when the user uses the pure esmodule library or tsconfig.json - module not is commonjs

e.q:

This was referenced Mar 12, 2021
@github-actions
Copy link

This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 11, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support typescript format configuration file
6 participants