Jest fails with "Unexpected token *" on import statement
Some react-native
libraries ship uncompiled ES6 code.
ES6 code needs to be compiled before it can be run by Jest.
The Jest doc about Testing React Native Apps includes a section about compiling dependencies that don't ship pre-compiled code.
You will need to tell Jest to compile react-navigation-tabs
by whitelisting it in the transformIgnorePatterns
option in your Jest config.
Example:
Changing the jest.config.js
file into something like below, fixed the issue mentioned in OP.
But the react-native-reanimated
module (which requires native integration) needs further work, and we should "Mock" modules with such native requirements (as described in another post).
module.exports = {
preset: 'react-native',
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
transformIgnorePatterns: [
"node_modules/(?!(react-native"
+ "|react-navigation-tabs"
+ "|react-native-splash-screen"
+ "|react-native-screens"
+ "|react-native-reanimated"
+ ")/)",
],
}
Note that the transformIgnorePatterns
option (which is an array of Regular-Expressions) is originally meant to exclude files from being compiled, but using (?!(some-dir-name|another-name))
pattern, with the "(?!...)
" negative look-ahead, we do tell Jest to exclude anything in node_modules
directory, except the names that we did specify.
If you're using not only React Native but also Expo, I fixed the same issue but for Expo components by following the official guide, Testing with Jest. Specifically, install via package manager the jest preset jest-expo
, and then update my package.json as they describe:
"jest": {
"preset": "jest-expo",
"transformIgnorePatterns": [
"node_modules/(?!(jest-)?react-native|react-clone-referenced-element|@react-native-community|expo(nent)?|@expo(nent)?/.*|react-navigation|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base|@sentry/.*)"
]
}
I also needed to add to the end of the transformIgnorePatterns
regexp string an exception for |.*font.*
as the Expo Fonts were what were giving me trouble. Probably I could have made it a bit more specific, but I hate regex, and this worked so I left it there!
As it has been said, some modules needs to be transpiled, & some don't. Here is a regex I use that work in a lot of projects
"jest": {
"preset": "react-native",
"transformIgnorePatterns": [
"node_modules/(?!(jest-)?react-native|react-(native|universal|navigation)-(.*)|@react-native-community/(.*)|@react-navigation/(.*)|bs-platform|(@[a-zA-Z]+/)?(bs|reason|rescript)-(.*)+)"
]
}
It's working for most common react native thing, & include also a specific package (here bs-platform
) as an example, when isn't captured by previous patterns.
I had a similar issue on a React + Typescript app.
The first mistake I made was to define the jest.config.js
as jest.config.ts
Running on Node v12.latest
Then the configuration that worked for me were the following:
// jest.config.js
module.exports = {
preset: "ts-jest",
testEnvironment: "node",
roots: ["./src"],
transform: { "\\.ts$": ["ts-jest"] },
testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$",
moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"],
globals: {
"ts-jest": {
tsConfig: {
// allow js in typescript
allowJs: true,
},
},
},
};
// tsconfig.json
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react",
"baseUrl": "."
},
"include": ["src"],
"exclude": ["node_modules", "**/*.spec.ts"]
}
// package.json
"devDependencies": {
"@types/jest": "^26.0.5",
"jest": "^26.1.0",
"ts-jest": "^26.1.3"
}