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.