jestjs / jest

Delightful JavaScript Testing.
https://jestjs.io
MIT License
44.21k stars 6.46k forks source link

[Feature]: Allow presets to export function returning config object #15306

Open Filipoliko opened 1 month ago

Filipoliko commented 1 month ago

πŸš€ Feature Proposal

Similar to current option for jest config file to export function returning an object (as described in docs)

/** @returns {Promise<import('jest').Config>} */
module.exports = async () => {
  return {
    verbose: true,
  };
};

Add same option to jest presets. Currently, if you export function in your jest-preset.js file, it is sort of ignored without showing any error. Due to lack of (or my inability to find) documentation about how to write your own jest presets, I assumed, that I can write preset file the same way as I would write my jest.config.js file, but I ran into this inconsistency.

Motivation

This feature will show a clear way, how to create async presets as you can simply export an async function and do all your async stuff inside. ESM supports top-level await, but it does not work in CJS and it has its own caveats. Exporting async function, which is awaited by jest, is a much cleaner solution.

This feature will also allow users to create jest-preset file by simply moving it to separate file / package and creating reference from jest.conf file. This is possible in most cases right now, but the scenario, where jest.conf is exporting function is not covered by jest-preset. This will make the preset feature more complete as it will reflect the jest.conf file behaviour.

Currently, you can do something like this as a workaround, but it is undocumented behaviour, which I'm worried, might break in future releases.

module.exports = (async () => {
  return {
    verbose: true,
  };
})();

Example

Let's have an npm package @my/package with a jest-preset.js file.

// @my/package/jest-preset.js

/** @returns {Promise<import('jest').Config>} */
module.exports = async () => {
  return {
    verbose: true,
  };
};

In my project jest.conf.js file, I should be able to do this.

// jest.conf.js

/** @type {import('jest').Config} */
const config = {
  preset: '@my/package',
};

module.exports = config;

This should set verbose: true in my jest test run.

Pitch

This feature would unify the behaviour of jest config and jest presets. It will also make it more straightforward to implement async jest presets.

If this feature request is approved, I would love to work on the PR.

Filipoliko commented 1 month ago

I just noticed, that this has been proposed by @unional but it did not get any hype at that point of time. Maybe it will work out this time? There is at least 2 of us πŸ˜†

https://github.com/jestjs/jest/issues/14177

github-actions[bot] commented 1 week ago

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 30 days.

Filipoliko commented 1 week ago

Bump, let's keep this alive. Since this is affecting only preset developers, it might not be getting enough of traction, but it really feels like forgotten feature, that just should be there.