ts-jest icon indicating copy to clipboard operation
ts-jest copied to clipboard

Support for esbuild or swc

Open isaacl opened this issue 5 years ago • 24 comments
trafficstars

🚀 Feature Proposal

Hi, I started with ts-jest on my project, but found startup performance to be unacceptable. I think this is because ts-jest compiles my entire project in order to run tests. There are compilers with significantly better performance, namely esbuild and swc.

swc-node/jest is decent but doesn't cache dependency tree, which means large repos have TONS of duplication compilation.

So maybe an opportunity here? I'm not saying it will be easy!

isaacl avatar Nov 14 '20 15:11 isaacl

Definitely those 2 have lots of possibilities to solve the performance problem. They are currently the new trend as well.

We have thought about that. Probably something like an experimental mode to turn on/off which allows using those 2.

ahnpnl avatar Nov 14 '20 16:11 ahnpnl

Any updates 6 months later? Our product team recently switched to esbuild and vite, and we have significantly improved DX here.

I would love to see the same improvement for ts-jest so we don't need to wait a full minute testing each component in a pre-commit hook. ts-jest really is the last commonly-used but slow component in our frontend tech stack. 👍

dlqqq avatar May 12 '21 18:05 dlqqq

You might want to give esbuild-jest a try: https://github.com/aelbore/esbuild-jest (caveat: it depends on babel-jest)

simon04 avatar May 19 '21 09:05 simon04

@simon04 Will definitely do so! I'd love to contribute as well. 👍

dlqqq avatar May 19 '21 13:05 dlqqq

I recently stumbled upon https://github.com/alangpierce/sucrase. Perhaps easier to integrate with since it's written in TypeScript?

jgonera avatar Jul 23 '21 18:07 jgonera

BUT THERE IS Still one critical problem, I seem to lose type checking when I add transform for either esbuild-jest or @swc/jest. If anyone knows how to fix this issue please let me know! Below is my configuration. What happens is that this will throw a type error in my test but if I uncomment any one of the transforms I lose that valuable piece

module.exports = {
  preset: "ts-jest",
  verbose: true,
  setupFilesAfterEnv: ["@testing-library/jest-dom/extend-expect"],
  // transform: { "\\.[jt]sx?$": "esbuild-jest" },
  // transform: { "^.+\\.(t|j)sx?$": "@swc/jest" },
  moduleNameMapper: {
    "\\.(css|less|scss|sss|styl)$": "<rootDir>/node_modules/identity-obj-proxy",
  },
};

floydjones1 avatar Aug 03 '21 03:08 floydjones1

Okay if I change the regex to only look for js and jsx then it catches type errors. But I'm not sure if there is any performance benefit if any.

floydjones1 avatar Aug 03 '21 03:08 floydjones1

Okay if I change the regex to only look for js and jsx then it catches type errors. But I'm not sure if there is any performance benefit if any.

You could check, if you run your tests before and after the change with time

sebastianrothe avatar Aug 03 '21 08:08 sebastianrothe

Okay if I change the regex to only look for js and jsx then it catches type errors. But I'm not sure if there is any performance benefit if any.

You could check, if you run your tests before and after the change with time

Unfortunately I don't have enough test that I could use to verify with. I think at this point I rather let tsc typecheck only test files and then let esbuild/swc run the transpiling

floydjones1 avatar Aug 03 '21 22:08 floydjones1

BUT THERE IS Still one critical problem, I seem to lose type checking when I add transform for either esbuild-jest or @swc/jest. If anyone knows how to fix this issue please let me know! Below is my configuration. What happens is that this will throw a type error in my test but if I uncomment any one of the transforms I lose that valuable piece

module.exports = {
  preset: "ts-jest",
  verbose: true,
  setupFilesAfterEnv: ["@testing-library/jest-dom/extend-expect"],
  // transform: { "\\.[jt]sx?$": "esbuild-jest" },
  // transform: { "^.+\\.(t|j)sx?$": "@swc/jest" },
  moduleNameMapper: {
    "\\.(css|less|scss|sss|styl)$": "<rootDir>/node_modules/identity-obj-proxy",
  },
};

That is correct. Esbuild will just throw away your types.

sebastianrothe avatar Aug 04 '21 08:08 sebastianrothe

I think the best solution would be to use tsc to type-check only test files and then lets esbuild/swc transpile and run test. Seems like there is no way to let the ts-jest type-check when a transform is specified

floydjones1 avatar Aug 04 '21 15:08 floydjones1

My dream setup would be this:

  1. The tests start running immediately, using esbuild or swc for super fast TypeScript -> JS compilation.
  2. tsc is run in parallel.
  3. The results of both of those are shown in a clever way.

When I run the tests, I usually have no type errors, because I see them and fix them in my editor. Then I don’t want to wait for tsc. But sometimes I have missed something in my editor. Then I would rather see the type errors from tsc, rather than cryptic test failures like “Expected 5, got undefined”.

lydell avatar Aug 16 '21 11:08 lydell

I don't know what happened between 27.0.7 and 27.1.0, but now the build on our jenkins server is failing: ➤ YN0056: │ esbuild-linux-64@npm:0.14.2: Cache entry required but missing for esbuild-linux-64@npm:0.14.2

We check in the yarn dependencies and adding this esbuild is now causing issues.

JorisAerts avatar Dec 07 '21 17:12 JorisAerts

See https://github.com/kulshekhar/ts-jest/pull/3129

ahnpnl avatar Dec 07 '21 17:12 ahnpnl

See #3129

exactly that

JorisAerts avatar Dec 07 '21 19:12 JorisAerts

Thanks, #3129 solved the peerDependency problem.

Just a note about the types:

https://github.com/kulshekhar/ts-jest/blob/0e8f8298285ab7090f6efe42186c11c113f4792f/src/types.ts#L4

That will make typescript fail if skipLibCheck !== true in consuming projects that does not have installed esbuild.

No real solution as esbuild does not exports its types.

Example

In P/R: https://github.com/soluble-io/cache-interop/pull/241

image

Fixed with

image

belgattitude avatar Dec 10 '21 00:12 belgattitude

My dream setup would be this:

  1. The tests start running immediately, using esbuild or swc for super fast TypeScript -> JS compilation.
  2. tsc is run in parallel.
  3. The results of both of those are shown in a clever way.

When I run the tests, I usually have no type errors, because I see them and fix them in my editor. Then I don’t want to wait for tsc. But sometimes I have missed something in my editor. Then I would rather see the type errors from tsc, rather than cryptic test failures like “Expected 5, got undefined”.

@lydell This approach might give you what you're looking for (see 4. What about types?): https://tsh.io/blog/how-to-speed-up-your-typescript-project/

mattsears18 avatar Dec 30 '21 21:12 mattsears18

Any plans when ts-jest could use esbuild?

vertic4l avatar Mar 15 '22 09:03 vertic4l

We plan start adopting it for v28

ahnpnl avatar Mar 15 '22 10:03 ahnpnl

@ahnpnl v28 was just released. Is esbuild now supported? The changelog doesn't seem to mention it.

isaachinman avatar May 03 '22 14:05 isaachinman

Not there yet, it will be opted in as experimental feature. esbuild doesn't support some TypeScript specific features which we need to be careful with adoption.

ahnpnl avatar May 03 '22 14:05 ahnpnl

Esbuild drop all the comments so you cannot make the use of /* istanbul ignore next */ in your code. And it does not seems to be something wanted to be implemented in esbuild see

Hideman85 avatar Jul 13 '22 11:07 Hideman85

@ahnpnl Do you know if esbuild experimental support is available yet? I see a few instances of it in the codebase (https://github.com/kulshekhar/ts-jest/search?q=esbuild) but not sure if it's able to be used yet or still in progress.

epicfaace avatar Aug 23 '22 16:08 epicfaace

Any updates on this? Is it time to start looking at migrating to Vitest?

algoflows avatar Apr 16 '23 16:04 algoflows