Jest Unexpected Token Error in React Native Tests
Problem Statement
When running component tests in a React Native project using Jest (@testing-library/react-native
), you may encounter a syntax error like:
Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax
Details:
/HelloWorld.spec.tsx:12
(0, react_native_1.render)(<HelloWorld_1.HelloWorld />);
^
SyntaxError: Unexpected token '<'
This error typically occurs when:
- React Native component tests contain JSX syntax
- Jest is not properly configured to handle JSX or React Native code
- Dependencies in
node_modules
require transformation - Configuration conflicts exist between Jest presets
The core issue is that Jest encounters JSX syntax (<HelloWorld />
) but lacks the proper configuration to transform it into valid JavaScript.
Recommended Solution
Update Jest Configuration Structure (Best Approach)
Modify your jest.config.js
to use jest-expo
preset only:
module.exports = {
preset: "jest-expo",
transformIgnorePatterns: [
"node_modules/(?!((jest-)?react-native|@react-native(-community)?)|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|@react-navigation/.*|@sentry/react-native|native-base|react-native-svg)"
],
testPathIgnorePatterns: [
"<rootDir>/node_modules/",
"<rootDir>/.maestro/",
"@react-native"
],
testEnvironment: "jsdom",
setupFiles: ["<rootDir>/test/setup.ts"],
setupFilesAfterEnv: ["<rootDir>/jest-setup-after-env.js"]
};
Key Changes
Remove conflicting presets
Eliminate thets-jest/presets
import and usage to avoid configuration conflicts.Update transformIgnorePatterns
Use the pattern recommended in the Expo documentation:js"node_modules/(?!((jest-)?react-native|@react-native(-community)?)|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|@react-navigation/.*|@sentry/react-native|native-base|react-native-svg)"
Configure transform explicitly
Add this transform block to handle file types:jstransform: { "^.+\\.(js|jsx|ts|tsx)$": "babel-jest" },
Alternative Solution: TypeScript + ts-jest
If you prefer using ts-jest with Expo:
module.exports = {
preset: "jest-expo",
transform: {
"^.+\\.(js|jsx|ts|tsx)$": "ts-jest"
},
transformIgnorePatterns: [
"node_modules/(?!(jest-)?react-native|react-clone-referenced-element|@react-native-community|expo(nent)?|@expo(nent)?/.*|react-navigation|@react-navigation/.*|@unimodules/.*|native-base|react-native-svg)"
],
// ...rest of your configuration
};
Why These Solutions Work
Conflict Resolution
- Preset conflicts: Removes conflicts between
ts-jest
andjest-expo
presets - JSX transformation: Ensures JSX syntax gets transformed correctly
- node_modules handling: New regex matches patterns of React Native ecosystem modules that require transformation
Critical Configuration Elements
transformIgnorePatterns rewrite
The updated pattern excludes common React Native and Expo packagesjs// Breakdown: node_modules/(?! ... ) // Negate exclude for modules that need processing (jest-)?react-native // Handles both react-native and jest-react-native |@react-native(-community)? // Covers react-native community packages |expo(nent)? // Includes all Expo-related packages |@expo(nent)?/.* // Covers scoped Expo packages ...other patterns // Additional essential packages
Transformation handling
Explicittransform
declaration ensures all JS/TS files get processed:js"^.+\\.(js|jsx|ts|tsx)$": "babel-jest"
WARNING
If you see lingering issues after configuration changes:
- Clear Jest cache:bash
npx jest --clearCache
- Verify Babel configuration exists:js
module.exports = { presets: ['babel-preset-expo'], };
Final Configuration Check
Your Jest setup should include:
// jest.config.js
module.exports = {
preset: "jest-expo",
transform: {
"^.+\\.(js|jsx|ts|tsx)$": "babel-jest"
},
transformIgnorePatterns: [
"node_modules/(?!(jest-)?react-native|@react-native(-community)?|expo(nent)?|@expo(nent)?/.*|react-navigation|@react-navigation/.*|@sentry/react-native|native-base|react-native-svg)"
],
testEnvironment: "jsdom",
setupFiles: ["<rootDir>/test/setup.ts"],
setupFilesAfterEnv: [
"@testing-library/jest-native/extend-expect",
"<rootDir>/jest-setup-after-env.js"
]
};
This configuration resolves the "Unexpected token '<'" error by ensuring all React Native components and JSX syntax are properly transformed before Jest execution.