ts-jest
ts-jest copied to clipboard
Support for esbuild or swc
🚀 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!
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.
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. 👍
You might want to give esbuild-jest a try: https://github.com/aelbore/esbuild-jest (caveat: it depends on babel-jest)
@simon04 Will definitely do so! I'd love to contribute as well. 👍
I recently stumbled upon https://github.com/alangpierce/sucrase. Perhaps easier to integrate with since it's written in TypeScript?
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",
},
};
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.
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
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
BUT THERE IS Still one critical problem, I seem to lose type checking when I add
transformfor eitheresbuild-jestor@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 piecemodule.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.
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
My dream setup would be this:
- The tests start running immediately, using
esbuildorswcfor super fast TypeScript -> JS compilation. tscis run in parallel.- 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”.
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.
See https://github.com/kulshekhar/ts-jest/pull/3129
See #3129
exactly that
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

Fixed with

My dream setup would be this:
- The tests start running immediately, using
esbuildorswcfor super fast TypeScript -> JS compilation.tscis run in parallel.- 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 fromtsc, 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/
Any plans when ts-jest could use esbuild?
We plan start adopting it for v28
@ahnpnl v28 was just released. Is esbuild now supported? The changelog doesn't seem to mention it.
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.
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
@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.
Any updates on this? Is it time to start looking at migrating to Vitest?