Using Jest together with TypeScript in multi-module projects
Programming Estimated reading time: ~2 minutes
For one of my current projects (snooop.net) we use Jest for unit and integration testing. This project is a TypeScript multi-module project using project references.
The problem
After incorporating redux-persist
into one of the modules
an integration test stopped to work. Jest complained with the following
error message: Jest encountered an unexpected token
.
Sometimes it happens (especially in React Native or TypeScript projects)
that 3rd party modules are published untranspiled (e.g. redux-persist
).
Since all files inside node_modules
are not transformed by default, Jest
might not understand the code in these modules, resulting in syntax errors.
First try…
If you have a single module TypeScript project you would set allowJs
in the
tsconfig.json
file to true
and configure the transformIgnorePatterns
in the jest.config.js
to include e.g. redux-persist
in the transpilation
process.
File jest.config.js
:
module.exports = {
"roots": [
"<rootDir>/src"
],
"transform": {
"^.+\\.(t|j)sx?$": "ts-jest",
},
"transformIgnorePatterns": [
"node_modules/(?!(redux-persist)/)"
],
"testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$",
"moduleFileExtensions": [
"ts",
"tsx",
"js",
"jsx",
"json",
"node"
],
}
But if you have a TypeScript multi-module project this does not work.
That’s because the TypeScript compiler does not allow to use the
allowJs
together with project references.
See e.g. here.
Actual solution
The solution is to configure a separate transformer for the JavaScript project.
File jest.config.js
:
module.exports = {
"roots": [
"<rootDir>/src"
],
"transform": {
"\\.(ts|tsx)?$": "ts-jest",
"\\.(js|jsx)?$": "./jestTransform.js",
},
"transformIgnorePatterns": [
"node_modules/(?!(redux-persist)/)"
],
"testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$",
"moduleFileExtensions": [
"ts",
"tsx",
"js",
"jsx",
"json",
"node"
],
}
File jestTransform.js
:
const config = {
babelrc: false,
presets: [
"@babel/preset-env",
],
};
module.exports = require("babel-jest").createTransformer(config);
Furthermore you also need to add the following packages to your development dependencies (also see here):
yarn add --dev babel-jest babel-core@^7.0.0-bridge.0 @babel/core
Further notes
ts-jest vs @babel/preset-typescript
While @babel/preset-typescript
actually can be used instead of ts-jest
,
ts-jest
offers some advantages. See e.g.
here.
Related documentation
A note about Netcup (advertisement)
Netcup is a German hosting company. Netcup offers inexpensive, yet powerfull web hosting packages, KVM-based root servers or dedicated servers for example. Using a coupon code from my Netcup coupon code web app you can even save more money (6$ on your first purchase, 30% off any KVM-based root server, ...).