jestjs / jest

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

[Feature]: Allow usage of tsm instead of ts-node? #11989

Open karlhorky opened 2 years ago

karlhorky commented 2 years ago

πŸš€ Feature Proposal

Jest allows for configuration in TypeScript via ts-node:

https://github.com/facebook/jest/blob/7f39f0a589703191a0cd3c6db558920281f7195f/docs/Configuration.md?plain=1#L37

It would be great to also enable support for tsm

Motivation

Example

No response

Pitch

Not entirely sure I understand this field, but maybe:

It fits Jest's ideology of being fast and enabling modern techniques

SimenB commented 2 years ago

PR very much welcome!

jensmeindertsma commented 2 years ago

The disadvantage to using tsm is that there is no programmatic way to invoke it. This is a problem because then we need to spawn a child process in which we run node --loader tsm jest.config.ts to import the config file. Then we must pass back the imported config to Jest. This can't be done across process boundaries without sacrificing support for function config files.

What I propose instead:

  1. Use @swc/cli in a child process like this: npx swc jest.config.,ts -o /node_modules/jest-config/_jest.config.js where /node_modules/jest-config/_jest.config.js is a temporary file.
  2. require("/node_modules/jest-config/_jest.config.js") which gives us the config object.
  3. Delete the temporary file. -> Now we have the config object available.

I chose swc because of the stability. I know there is also esbuild which tsm uses, and they are similar in size.

@SimenB would you accept a PR implementing this approach?

SimenB commented 2 years ago

would that work if said file imported another ts file? or will swc bundle?

jensmeindertsma commented 2 years ago

If said file imported another TS file, it wouldn't work. I know esbuild can do bundling, that might be an option. I don't know many cases in which you might import from other files though, but yeah, I'd be happy to use esbuild instead and do bundling. Let me know what you prefer ☺️

SimenB commented 2 years ago

@swc/core has a bundle export: https://www.runpkg.com/?@swc/core@1.2.106/index.js#229

(I don't care if swc or esbuild is chosen, I've never used either and haven't cared to check any of them out)

jensmeindertsma commented 2 years ago

Ah, okay. I'll look into it. Just to confirm, you are open to a PR removing ts-node and implementing support for jest.config.ts files with swc or esbuild?

SimenB commented 2 years ago

I don't think we should remove ts-node (but as it would be a breaking change, but also since I don't think any of the alternatives does any type checking?), but making it configurable in some way (--config-loader=blah or some such?) sounds reasonable

jensmeindertsma commented 2 years ago

What would be breaking about removing ts-node? Depending on it's type-checking features would be one? I can do a CLI option

SimenB commented 2 years ago

For people currently using ts-node it would stop working - it's a peer dependency, not a dependency

jensmeindertsma commented 2 years ago

Ah okay. I will implement esbuild under a flag

jensmeindertsma commented 2 years ago

What about a fallback mechanism where Jest will try to parse the config file with esbuild if ts-node is not installed?

milesj commented 2 years ago

If config loading happens within a CJS context, something like this would work just fine: https://boostlib.dev/docs/module#commonjs-requires

github-actions[bot] commented 1 year ago

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

karlhorky commented 1 year ago

Not stale? There is also now another alternative called tsx

SimenB commented 1 year ago

Current thinking: https://github.com/facebook/jest/issues/13143#issuecomment-1249081951

I.e. allowing a user to specify which loader to use.

LinusU commented 1 year ago

Both tsm and tsx support would be provided by https://github.com/facebook/jest/pull/13521 πŸŽ‰

github-actions[bot] commented 7 months ago

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

karlhorky commented 7 months ago

Not stale