jest: Jest encountered unexpected token with React app

🐛 Bug Report

When trying to run tests with Jest in a React app, I get a Jest encountered an unexpected token error. I copied the Link component and test directly from here. This is the error:

FAIL  src/components/Link.test.js
  ● Test suite failed to run

    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".

    Here's what you can do:
     • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     • If you need a custom transformation specify a "transform" option in your config.
     • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/en/configuration.html

    Details:

    SyntaxError: C:\workspace\react\testapp\src\components\Link.test.js: Unexpected token (8:4)

       6 | test('Link changes the class when hovered', () => {
       7 |   const component = renderer.create(
    >  8 |     <Link page="http://www.facebook.com">Facebook</Link>,
         |     ^
       9 |   );
      10 |   let tree = component.toJSON();
      11 |   expect(tree).toMatchSnapshot();

      at Parser.raise (node_modules/@babel/parser/lib/index.js:3938:15)
      at Parser.unexpected (node_modules/@babel/parser/lib/index.js:5247:16)
      at Parser.parseExprAtom (node_modules/@babel/parser/lib/index.js:6327:20)
      at Parser.parseExprSubscripts (node_modules/@babel/parser/lib/index.js:5923:21)
      at Parser.parseMaybeUnary (node_modules/@babel/parser/lib/index.js:5902:21)
      at Parser.parseExprOps (node_modules/@babel/parser/lib/index.js:5811:21)
      at Parser.parseMaybeConditional (node_modules/@babel/parser/lib/index.js:5783:21)
      at Parser.parseMaybeAssign (node_modules/@babel/parser/lib/index.js:5730:21)
      at Parser.parseExprListItem (node_modules/@babel/parser/lib/index.js:6994:18)
      at Parser.parseCallExpressionArguments (node_modules/@babel/parser/lib/index.js:6123:22)

Here’s my package.json

{
  "name": "testapp",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "scripts": {
    "start": "webpack-dev-server --config ./config/webpack.config.development.js",
    "build": "webpack -p --config ./config/webpack.config.production.js",
    "test": "jest"
  },
  "dependencies": {
    "axios": "^0.18.0",
    "moment": "^2.22.2",
    "polished": "^2.0.3",
    "prop-types": "^15.6.2",
    "react": "^16.4.2",
    "react-delay-render": "^0.1.2",
    "react-dom": "^16.4.2",
    "react-imported-component": "^4.6.2",
    "react-router-dom": "^4.3.1",
    "simple-grid": "^1.0.1",
    "styled-components": "^3.4.5",
    "uuid": "^3.3.2",
    "validator": "^10.7.0"
  },
  "devDependencies": {
    "@babel/core": "^7.0.0",
    "@babel/plugin-proposal-class-properties": "^7.0.0",
    "@babel/plugin-syntax-dynamic-import": "^7.0.0",
    "@babel/preset-env": "^7.0.0",
    "@babel/preset-react": "^7.0.0",
    "babel-core": "7.0.0-bridge.0",
    "babel-jest": "^23.4.2",
    "babel-loader": "^8.0.0",
    "babel-plugin-styled-components": "^1.6.0",
    "css-loader": "^1.0.0",
    "html-webpack-plugin": "^3.2.0",
    "jest": "^23.5.0",
    "mini-css-extract-plugin": "^0.4.2",
    "react-test-renderer": "^16.4.2",
    "regenerator-runtime": "^0.12.1",
    "style-loader": "^0.23.0",
    "webpack": "^4.17.1",
    "webpack-cli": "^3.1.0",
    "webpack-dev-server": "^3.1.7"
  }
}

Here’s my .babelrc file (located in the root directory):

{
  "plugins": [
    "@babel/plugin-proposal-class-properties",
    "babel-plugin-styled-components",
    "@babel/plugin-syntax-dynamic-import"
  ],
  "presets": ["@babel/preset-env", "@babel/preset-react"],
  "env": {
    "development": {
      "plugins": [
        "@babel/plugin-proposal-class-properties",
        ["babel-plugin-styled-components", { "displayName": true }],
        "@babel/plugin-syntax-dynamic-import"
      ],
      "presets": ["@babel/preset-env", "@babel/preset-react"]
    },
    "test": {
      "plugins": [
        "@babel/plugin-proposal-class-properties",
        ["babel-plugin-styled-components", { "displayName": true }],
        "@babel/plugin-syntax-dynamic-import"
      ],
      "presets": ["@babel/preset-env", "@babel/preset-react"]
    },
    "production": {
      "plugins": [
        "@babel/plugin-proposal-class-properties",
        "babel-plugin-styled-components",
        "@babel/plugin-syntax-dynamic-import"
      ],
      "presets": ["@babel/preset-env", "@babel/preset-react"]
    }
  }
}

To Reproduce

Steps to reproduce the behavior:

  • Install Jest with yarn add --dev babel-jest babel-core@^7.0.0-0 @babel/core
  • Create a test
  • Run yarn test

Expected behavior

  • Jest should work

Run npx envinfo --preset jest

Paste the results here:

OS: Windows 10
    CPU: x64 Intel(R) Xeon(R) CPU E3-1505M v6 @ 3.00GHz
  Binaries:
    Yarn: 1.5.1 - C:\Program Files (x86)\Yarn\bin\yarn.CMD
    npm: 5.6.0 - C:\Program Files\nodejs\npm.CMD

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 162
  • Comments: 45 (2 by maintainers)

Commits related to this issue

Most upvoted comments

I have the same problem too.

After 3 days, I just find out the solutions for this issue. There are 2 solutions for this:

Solution 1:

You can change your file name from .babelrc to babel.config.js, and this will work.

Solution 2:

I’m using this way. Create a transform file like this (mine is jest-transforme.js):

const config = {
  babelrc: false,
  presets: [
    [
      "@babel/env",
      {
        modules: false
      }
    ],
    "@babel/react"
  ],
  plugins: [
    ["@babel/plugin-proposal-decorators", { legacy: true }],
    ["@babel/plugin-proposal-class-properties", { loose: true }],
    "transform-es2015-modules-commonjs"
  ]
};
module.exports = require("babel-jest").createTransformer(config);

Here’s my jest.config.js:

module.exports = {
  collectCoverageFrom: ["src/**/*.{js,jsx,mjs}"],
  testMatch: ["<rootDir>/src/**/__tests__/**/*.{js,jsx,mjs}", "<rootDir>/src/**/?(*.)(spec|test).{js,jsx,mjs}"],
  transform: {
    "^.+\\.(js|jsx|mjs)$": "<rootDir>/config/jest/jest-transformer.js"
  },
  transformIgnorePatterns: ["[/\\\\]node_modules[/\\\\].+\\.(js|jsx|mjs)$"]
};

And my I still have my .babelrc

const enviroments = require("./env-config.js");

module.exports = {
  presets: [
    [
      "next/babel",
      {
        "preset-env": {
          useBuiltIns: "entry"
        }
      }
    ]
  ],
  plugins: [
    ["styled-components", { ssr: true, displayName: true, preprocess: false }],
    [
      "module-resolver",
      {
        root: ["./"]
      }
    ]
  ],
  env: {
    dev: {
      plugins: [
        ["transform-define", enviroments],
        ["module-resolver", { root: ["./"] }],
        "transform-decorators-legacy",
        "transform-class-properties"
      ]
    },
    build: {
      plugins: [
        ["transform-define", enviroments],
        ["module-resolver", { root: ["./"] }],
        "transform-decorators-legacy",
        "transform-class-properties"
      ]
    },
    production: {
      presets: [
        [
          "minify", // why add minify here, we run uglify over the whole code bundles
          {
            mangle: false,
            evaluate: false
          }
        ]
      ],
      plugins: [
        ["transform-define", enviroments],
        ["@babel/plugin-proposal-decorators", { legacy: true }],
        ["@babel/plugin-proposal-class-properties", { loose: true }],
        ["module-resolver", { root: ["./"] }]
      ],
      comments: false,
      compact: true,
      minified: true
    }
  }
};

Hope this can have you guys pass this issue. Cheer.

Same problem here.

same problem here… slightly more complicated as I’m working with a monorepo.

@fabioSalimbeni @hoaiduyit @mikedloss I’ve made my React and React Native tests (Jest and enzyme) pass in a Lerna monorepo using Babel 7.

You need to use the new Babel configuration with babel.config.js if you’re working into a monorepo: https://babeljs.io/docs/en/v7-migration.

This is my babel.config.js for the root of the monorepo:

module.exports = {
    overrides: [
        {
            test: 'platforms/webApp1',
            extends: 'platforms/webApp1/babel.config.js'
        },
        {
            test: 'platforms/webApp2',
            extends: 'platforms/webApp2/babel.config.js'
        }
    ]
};

This is how my babel.config.js looks like for webApp1 one of the monorepo apps:

module.exports = {
    env: {
        test: {
            presets: [
                [
                    '@babel/preset-env',
                    {
                        modules: 'commonjs',
                        debug: false
                    }
                ],
                '@babel/preset-flow',
                '@babel/preset-react'
            ],
            plugins: [
                '@babel/plugin-syntax-dynamic-import',
                '@babel/plugin-proposal-class-properties'
            ]
        },
        production: {
            presets: [
                ['@babel/preset-env', { modules: false }],
                '@babel/preset-flow',
                '@babel/preset-react'
            ],
            plugins: [
                '@babel/plugin-syntax-dynamic-import',
                '@babel/plugin-proposal-class-properties'
            ]
        },
        development: {
            presets: [
                ['@babel/preset-env', { modules: false }],
                '@babel/preset-flow',
                '@babel/preset-react'
            ],
            plugins: [
                '@babel/plugin-syntax-dynamic-import',
                '@babel/plugin-proposal-class-properties'
            ]
        }
    }
};

And this is the Jest configuration:

    "jest": {
        "verbose": true,
        "clearMocks": true,
        "collectCoverage": true,
        "setupTestFrameworkScriptFile": "<rootDir>/config/setupTest.js",
        "transform": {
            "^.+\\.js$": "babel-jest"
        },
        "moduleNameMapper": {
            "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
            "\\.(css|scss)$": "<rootDir>/__mocks__/styleMock.js"
        }
    }

setupTest.js looks like:

const Enzyme = require('enzyme');
const Adapter = require('enzyme-adapter-react-16');

Enzyme.configure({ adapter: new Adapter() });

fileMocks.js looks like:

module.exports = 'i-am-a-stubbed-file';

styleMocks.js looks like:

module.exports = {};

You’ll also need to add some Babel plugins and the babel-core version as devDependencies in the package.json of each app:

        ...
        "@babel/cli": "^7.0.0",
        "@babel/core": "^7.0.0",
        "@babel/plugin-proposal-class-properties": "^7.0.0",
        "@babel/plugin-syntax-dynamic-import": "^7.0.0",
        "@babel/preset-env": "^7.0.0",
        "@babel/preset-flow": "^7.0.0",
        "@babel/preset-react": "^7.0.0",
        "babel-core": "7.0.0-bridge.0",
        "babel-eslint": "^9.0.0",
        "babel-jest": "^23.4.2",
        "babel-loader": "^8.0.2",
        ...
        "jest": "^23.5.0",
        "jest-cli": "^23.5.0",
        ...
      

Yeah, running yarn upgrade --latest fixed the issue 😃

In the newer versions of React Jest is built in therefore in package.json the test script should be "test": "react-scripts test" instead of "test": "jest"

I solved a similar problem by doing the following:

1- add enzyme setup file and write the following:

import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';

Enzyme.configure({ adapter: new Adapter() });

2- add jest configuration to your package.json like that:

"jest": {
 "setupFilesAfterEnv": [
  "./path to your setup file/setupEnzyme.js"
 ]
}

3- add .babelrc file to your root path and write the following in it:

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

4- if you got an error on “expect” keyword in your test just run npm install -D chai and import the expect function in your test code like that import { expect } from 'chai';

if you still get an error try to install babel dependencies like that npm install -D @babel/core @babel/preset-env @babel/preset-react

hope this helps.

just .tsx files face same problem?

just spreading the news, Jest v24 was updated to use Babel 7 internally, using babel bridge or babel7-jest shouldn’t be needed anymore https://twitter.com/i/web/status/1088904207653105664

@SimenB I renamed my .babelrc to babel.config.js but it still shows that error with unexpected token. It works with babel7-pre.42 though. Are there any other commonly missed things? 😃 Thanks.

@GeorgianSorinMaxim The problem is my jest app ignore .babelrc file, and change to babel.config.js will solve the problem, but I solved it anyway, my answer is above of this comment.

babel-jest still relies in babel-core from Babel 6, if you want to use Babel 7 you can use this tranformer babel7-jest

In the newer versions of React Jest is built in therefore in package.json the test script should be "test": "react-scripts test" instead of "test": "jest"

Thanks a lot, that solved the issue for me!

For anyone using Create-React-App, adding transformignorepatterns to your package.json will not solve the issue as only certain jest configurations can be changed in package.json when using CRA.

I had issues with Jest picking up an internal library, Jest would display ‘unexpected token’ errors wherever I had my imports from this library.

To solve this, you can change your test script to the below: "test": "react-scripts test --transformIgnorePatterns 'node_modules/(?!(<your-package-goes-here>)/)'",

I renamed .babelrc to babel.config.js and also upgraded to Babel7 and still have the same error as before. My babel.config.js file:

module.exports = function (api) {
  api.cache(true);

  const presets = ["@babel/preset-env"];

  return {
    presets
  };
}

I installed@babel/preset-react and added it to my babel.config.js file. Fixed the error.

babel-jest works just fine with babel 7, no need for a custom transformer

Babel 7 seems to require babel.config.js to work properly, use that instead of babelrc

FYI I think we ended up finding a really silly solution to this, like the entire build system wasn’t behaving well if NODE_ENV=“test” wasm’t set.

After 3 days, I just find out the solutions for this issue. There are 2 solutions for this:

Solution 1:

You can change your file name from .babelrc to babel.config.js, and this will work.

My solution:

I didn’t have a .babelrc file so I figured doing the reverse should work too and created a .babelrc file using the preset info from babel.config.js instead. (I created an additional file, I didn’t rename the original) Upon running the test again I received a new error: Requires Babel "^7.0.0-0", but was loaded with "6.26.3". I googled that error and it led me here. I followed the instructions (npm install babel-core@7.0.0-bridge.0) and the test is now running and passing.

My babel.config.js file was not getting detected by babel-jest, because I put it inside __test__ directory. I moved it to the top directory where package.json was located and everything worked.

I saw this error after making a stupid mistake and writing my first test file with .ts instead of .tsx extension. Far from the original issue but i though it might be helpful for someone 😄