Leo Odishvili
Leo Odishvili

Reputation: 1042

Jest encountered an unexpected token with react-native

So I'm trying to write tests on my React Native app with Jest and TypeScript. While using old babel version everything worked fine, but because of some project problems we had to upgrade babel to 7.0.0. After that I couldn't make it work. Any help is appreciated

Jest encountered an unexpected token This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript. By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".

/app/node_modules/react-native-calendar-events/index.ios.js:3 import { NativeModules } from 'react-native';

SyntaxError: Unexpected token import

package.json:

"dependencies": {
    "react": "16.4.1",
    "react-native": "0.56.0",
    "react-native-calendar-events": "^1.6.1",
    "react-redux": "^5.0.7",
    "react-router": "^4.3.1",
    "react-router-native": "^4.3.0",
    "react-router-redux": "5.0.0-alpha.9",
    "redux": "^4.0.0",
    "redux-api-middleware": "^2.3.0",
    "redux-form": "^7.4.2",
    "redux-thunk": "^2.3.0",
    "urijs": "^1.19.1"
  },
  "devDependencies": {
    "@babel/core": "^7.0.0",
    "@babel/preset-env": "^7.0.0",
    "@types/history": "^4.7.0",
    "@types/jest": "^23.3.1",
    "@types/react": "^16.4.13",
    "@types/react-native": "^0.56.17",
    "@types/react-router": "^4.0.30",
    "@types/react-router-native": "^4.2.3",
    "babel-core": "^7.0.0-bridge.0",
    "babel-jest": "^23.4.2",
    "babel-loader": "^8.0.2",
    "babel-preset-react-native": "^5.0.0",
    "jest": "^23.5.0",
    "react-native-typescript-transformer": "^1.2.10",
    "react-test-renderer": "^16.4.2",
    "ts-jest": "^23.1.4",
    "typescript": "^3.0.3"
},


"jest": {
    "preset": "react-native",
    "transform": {
      "^.+\\.ts?$": "ts-jest",
      "^.+\\.tsx?$": "ts-jest",
      "^.+\\.js$": "babel-jest"
    },
    "testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)?$",
    "moduleFileExtensions": [
      "ts",
      "tsx",
      "js",
      "jsx",
      "json",
      "node"
    ],
    "moduleNameMapper": {
      "^.+\\.(css|less|scss)$": "identity-obj-proxy"
    },
    "transformIgnorePatterns": [
      "/node_modules/(?!(react-native|my-project|react-native-button|react-native-calendar-events)/)"
    ]
  }

babelrc:

{
  "presets": ["react-native", ["@babel/preset-env", {"modules": "commonjs"}]],
  "env": {
    "test": {
      "presets": ["react-native", ["@babel/preset-env"]]
    }
  }
}

Upvotes: 18

Views: 18809

Answers (2)

Florin Dobre
Florin Dobre

Reputation: 10252

This is a config that worked for me:

jest.config.js

module.exports = {
  preset: 'react-native',
  moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
  moduleDirectories: ['./node_modules', 'src'],
  cacheDirectory: '.jest/cache',
  transformIgnorePatterns: [
    '<rootDir>/node_modules/(?!@react-native|react-native)',
  ],
  moduleNameMapper: {
    '^[./a-zA-Z0-9$_-]+\\.svg$': '<rootDir>/tests/SvgStub.js'
  },
  setupFiles: ['./node_modules/react-native-gesture-handler/jestSetup.js'],
  modulePathIgnorePatterns: ['<rootDir>/packages/'],
  watchPathIgnorePatterns: ['<rootDir>/node_modules'],
}

babel.config

{
   presets: ['module:metro-react-native-babel-preset'],
   plugins: [
        'react-native-reanimated/plugin'
   ]
};

package.json

  "dependencies": {
   
    "react-native": "0.69.6",
    "react-native-reanimated": "2.9.1",
   
  },
  "devDependencies": {
    "@babel/core": "^7.19.3",
    "@babel/register": "^7.18.9",
    "@babel/runtime": "^7.19.4",
    "@react-native-community/eslint-config": "^3.1.0",
    "@testing-library/react-native": "^7.1.0",
    "@types/i18n-js": "^3.8.3",
    "@types/jest": "^29.0.0",
    "@types/pubsub-js": "^1.8.1",
    "@types/react": "~18.0.0",
    "@types/react-dom": "17.0.14",
    "@types/react-native": "^0.69.6",
    "@types/react-test-renderer": "^18.0.0",
    "@types/redux-mock-store": "^1.0.2",
    "@types/redux-thunk": "^2.1.0",
    "@types/styled-components": "^5.1.26",
    "@types/styled-components-react-native": "^5.1.3",
    "@typescript-eslint/eslint-plugin": "^5.40.1",
    "@typescript-eslint/parser": "^5.40.1",
    "babel-jest": "29.2.2",
    "babel-plugin-transform-remove-console": "^6.9.4",
    "eslint": "^7.32.0",
    "eslint-config-prettier": "^8.5.0",
    "eslint-plugin-prettier": "^4.2.1",
    "jest": "^29.2.2",
    "jest-junit": "^14.0.1",
    "jetifier": "^1.6.5",
    "lint-staged": "^13.0.3",
    "metro-react-native-babel-preset": "^0.70.3",
    "prettier": "^2.7.1",
    "react-native-svg-transformer": "^1.0.0",
    "react-test-renderer": "18.0.0",
    "redux-mock-store": "^1.5.4",
    "ts-jest": "^29.0.3",
    "ts-mock-imports": "^1.3.8",
    "typescript": "^4.8.4"
  },

Sources: https://github.com/facebook/jest/issues/11591#issuecomment-899508417

Upvotes: 0

Leo Odishvili
Leo Odishvili

Reputation: 1042

Found the solution. In transform you should use react-native/jest/preprocessor.js instead of babel-jest.

"jest": {
    "preset": "react-native",
    "moduleDirectories": [
      "node_modules",
      "src"
    ],
    "transform": {
      "^.+\\.ts?$": "ts-jest",
      "^.+\\.tsx?$": "ts-jest",
      "^.+\\.js$": "<rootDir>/node_modules/react-native/jest/preprocessor.js" <--- over here
    },
    "testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)?$",
    "moduleFileExtensions": [
      "ts",
      "tsx",
      "js",
      "jsx",
      "json",
      "node"
    ],
    "moduleNameMapper": {
      "^.+\\.(css|less|scss)$": "identity-obj-proxy"
    },
    "transformIgnorePatterns": []
}

Upvotes: 22

Related Questions