145

If I use import/export from ES6 then all my Jest tests fail with error:

Unexpected reserved word

I convert my object under test to use old school IIFE syntax and suddenly my tests pass. Or, take an even simpler test case:

   var Validation = require('../src/components/validation/validation'); // PASS
   //import * as Validation from '../src/components/validation/validation' // FAIL

Same error. Obviously there's a problem with import/export here. It's not practical for me to rewrite my code using ES5 syntax just to make my test framework happy.

I have babel-jest. I tried various suggestions from GitHub issues. It is no go so far.

File package.json

 "scripts": {
    "start": "webpack-dev-server",
    "test": "jest"
  },
      "jest": {
        "testPathDirs": [
          "__tests__"
        ],
        "testPathIgnorePatterns": [
          "/node_modules/"
        ],
        "testFileExtensions": ["es6", "js"],
        "moduleFileExtensions": ["js", "json", "es6"]
      },

File babelrc

{
  "presets": ["es2015", "react"],
  "plugins": ["transform-decorators-legacy"]
}

Is there a fix for this?

Peter Mortensen
  • 30,030
  • 21
  • 100
  • 124
P.Brian.Mackey
  • 41,438
  • 63
  • 228
  • 337
  • does [this](http://stackoverflow.com/questions/33710319/unexpected-reserved-word-import-when-using-babel) help at all? –  Mar 02 '16 at 19:49
  • @GeorgePompidou - Possibly. I'm not sure if/how the solution applies to babel-jest – P.Brian.Mackey Mar 02 '16 at 19:51
  • it's a matter of specifying something like "presets": ["es2015"] in a package.json or a .babelrc. you are using babel, after all. –  Mar 02 '16 at 19:59
  • @GeorgePompidou - In that case the solution does not work. I already have a babelrc containing es2015, react presets. Standard transpilation works, inside of gulp. It's just the Jest framework that can't handle it. – P.Brian.Mackey Mar 02 '16 at 20:01
  • it worked for someone [here](https://github.com/babel/babel-jest/issues/49) by installing babel-preset-es2015 and babel-preset-react packages. sorry if I'm not being much help--haven't had this issue. –  Mar 02 '16 at 20:04
  • @GeorgePompidou - I agree that the solution works in general. I had to add these values to get Babel to transpile correctly. I mean to say that the solution does not fix the issue at hand. The problem is elsewhere. – P.Brian.Mackey Mar 02 '16 at 20:06
  • Here's the [GitHub issue tracking ES6 module support in Jest](https://github.com/facebook/jest/issues/4842#issuecomment-401877985). – Dan Dascalescu Jul 15 '18 at 04:24
  • @P.Brian.Mackey, if possible, reconsider the accepted answer. Thanks! – Paulo Coghi Mar 22 '19 at 12:56
  • 4
    This question is from 5 years ago and yet jest's support for ES modules is experimental. – aderchox Dec 17 '21 at 21:31

9 Answers9

149

From my answer to another question, this can be simpler:


The only requirement is to configure your test environment to Babel, and add the ECMAScript 6 transform plugin:


Step 1:

Add your test environment to .babelrc in the root of your project:

{
  "env": {
    "test": {
      "plugins": ["@babel/plugin-transform-modules-commonjs"]
    }
  }
}

Step 2:

Install the ECMAScript 6 transform plugin:

npm install --save-dev @babel/plugin-transform-modules-commonjs

And that's it. Jest will enable compilation from ECMAScript modules to CommonJS automatically, without having to inform additional options to your jest property inside package.json.

Peter Mortensen
  • 30,030
  • 21
  • 100
  • 124
Paulo Coghi
  • 12,104
  • 13
  • 66
  • 88
  • 27
    If you don't want to pollute your project with `.babelrc`, you can add the `env` key above under a `babel` key in `package.json`. – Dan Dascalescu Mar 25 '19 at 05:04
  • Good hint! Thanks @DanDascalescu ! – Paulo Coghi Apr 29 '19 at 11:31
  • Actually, funny coincidence: I've *just* worked around [this Jest bug](https://github.com/facebook/jest/issues/8238) the day before by moving the `babel` key out of `package.json` into `babel.config.js`. The bug only affects running transforms on files imported from the parent directory of the project. – Dan Dascalescu Apr 30 '19 at 17:39
  • 5
    I believe the more recent `@babel/plugin-transform-modules-commonjs` replaces `transform-es2015-modules-commonjs` – Albizia Jul 19 '19 at 11:15
  • I will try that, @Albizia ! And, if it works, I will update the answer. Thanks for the note! – Paulo Coghi Jul 19 '19 at 13:08
  • 3
    Man this was taking me forever! Thanks! – Qamar Stationwala Mar 17 '20 at 10:32
  • 1
    This should be the correct answer, so dead simple. – Ben Steward Apr 23 '21 at 16:24
  • This has been a great answer. However it appears that things have changed in the years since. So I'm moving the answer to the newly supported answer comment. – P.Brian.Mackey Dec 06 '21 at 14:07
  • 1
    @P.Brian.Mackey sure! If you already tested the new approach, and Babel isn't needed anymore, this is good news and it's important to update the community about the updated approach. :) – Paulo Coghi Dec 07 '21 at 15:44
93

UPDATE 2020 - native support of ECMAScript modules (ESM)


According to this issue, there is native support of ESM from jest@25.4.0. So you won't have to use babel anymore. At the time of writing this answer (05/2020), to activate that you need to do three simple things:

  • Make sure you don't transform away import statements by setting transform: {} in config file
  • Run node@^12.16.0 || >=13.2.0 with --experimental-vm-modules flag
  • Run your test with jest-environment-node or jest-environment-jsdom-sixteen.

So your Jest configuration file should contain at least this:

export default {
    testEnvironment: 'jest-environment-node',
    transform: {}
    ...
};

And to set --experimental-vm-modules flag, you will have to run Jest as follows:

node --experimental-vm-modules node_modules/jest/bin/jest.js

Also note in the Github issue that this approach does not yet support the jest object. So you may need to import it manually:

import {jest} from '@jest/globals'

(I hope this will change in the future)

Eric
  • 613
  • 1
  • 5
  • 11
Radovan Kuka
  • 1,573
  • 13
  • 19
  • 2
    What is the 'jest-environment-node' and how does it differ from an environment 'node'? – akauppi Aug 06 '20 at 11:26
  • 2
    it's a test environment that will be used for testing. It's `jsdom` by default. You can find more information here https://jestjs.io/docs/en/configuration#testenvironment-string – Radovan Kuka Aug 07 '20 at 08:57
  • I've been running into `Maximum call stack size exceeded` (`internal/vm/module.js:315 const module = await linker(identifier, this);`) with this method. Is there a way to circumvent that? – Twiggeh Sep 15 '20 at 20:02
  • 20
    `NODE_OPTIONS='--experimental-vm-modules' jest` is a bit cleaner to run jest – Relisora Sep 23 '20 at 13:35
  • 4
    As an important note, native support does **not** support mocking as of yet – Justin Dalrymple Mar 07 '21 at 20:42
  • 2
    4th thing to do to make this work: package.json should contain `"type": "module"` for Node to detect files as ESM, see https://nodejs.org/api/packages.html#packages_determining_module_system – Louis Ameline May 02 '21 at 15:41
  • 2
    I only needed `NODE_OPTIONS='--experimental-vm-modules' jest` on node `v14.6.1` and jest `v26.6.3`. No config. – Raine Revere May 09 '21 at 16:29
  • 2
    I also had to add `"type": "modules"` to the root of my `package.json`. See more in the [Jest docs about ES modules](https://jestjs.io/docs/ecmascript-modules). – totymedli May 12 '21 at 14:13
  • FYI, using ESM in `testEnvironment` was only added in 27.0.0: https://github.com/facebook/jest/pull/11232 – Joshua Pinter May 24 '21 at 19:39
32

For an updated configuration, I'm using https://babeljs.io/setup#installation

Select JEST and be happy:

As a reference, the current configuration:

npm install --save-dev babel-jest

In your package.json file, make the following changes:

{
  "scripts": {
    "test": "jest"
  },
  "jest": {
    "transform": {
      "^.+\\.jsx?$": "babel-jest"
    }
  }
}

Install babel preset:

npm install @babel/preset-env --save-dev

Create a .babelrc file:

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

Run your tests:

npm run test
Peter Mortensen
  • 30,030
  • 21
  • 100
  • 124
  • Worked for me! The babel docs have been updated to specify .ts files too in the regex. Didn't need any other dependency for typescript like ts-jest. I did need @babel/preset-typescript. Added it to the list of presets in the .babelrc file. – Mayowa Daniel Mar 24 '21 at 15:40
  • 1
    This is basically the correct answer. Here is another good reference page from jest's own docs https://jestjs.io/docs/getting-started#using-babel – Colin D Aug 26 '21 at 03:13
  • thanks this worked for me. As of now, you do **not** need to add the `transform` to your `package.json`. It is now default. – Scott Coates Dec 07 '21 at 16:05
8

In package.json, kindly set like this one: "test": "node --experimental-vm-modules node_modules/.bin/jest"

Should be good!

CodeFinity
  • 898
  • 2
  • 15
  • 17
  • 1
    Nope! won't do it! Mocks will not work. – avepr Oct 08 '21 at 15:47
  • Sorry to hear that. There are some nuances to getting `jest` to work and even on Windows vs Mac sometimes issues. NS what you are trying to do exactly, but here is [a template](https://github.com/manavm1990/node-starter) repo that I use for Node stuff that has a fully working `jest` (using `nodemon`). It includes other stuff that you may or may not want, but you can at least use as a guide? – CodeFinity Jan 08 '22 at 14:10
  • I followed this answer instead. https://stackoverflow.com/a/52224329/985942 basically use babel to transform everything back to commonjs – avepr Jan 09 '22 at 23:19
  • Right. That's what that repo ends up doing. – CodeFinity Jan 10 '22 at 14:38
3

It's a matter of adding stage-0 to your .babelrc file. Here is an example:

{
  "presets": ["es2015", "react", "stage-0"],
  "plugins": ["transform-decorators-legacy"]
}
Peter Mortensen
  • 30,030
  • 21
  • 100
  • 124
1

I encountered the same issue.

These are what I did:

yarn add --dev babel-jest @babel/core @babel/preset-env

Make file jest.config.js in rootDir.

module.exports = {
    moduleFileExtensions: ["js", "json", "jsx", "ts", "tsx", "json"],
    transform: {
        '^.+\\.(js|jsx)?$': 'babel-jest'
    },
    testEnvironment: 'node',
    moduleNameMapper: {
        '^@/(.*)$': '<rootDir>/$1'
    },
    testMatch: [
        '<rootDir>/**/*.test.(js|jsx|ts|tsx)', '<rootDir>/(tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx))'
    ],
    transformIgnorePatterns: ['<rootDir>/node_modules/']
};

Then make file babal.config.js in rootDir.

Go like this:

module.exports = {
    "presets": ["@babel/preset-env"]
}
YOSEPH NOH
  • 67
  • 3
0

In addition to installing babel-jest (which comes with Jest by default now) be sure to install regenerator-runtime.

Peter Mortensen
  • 30,030
  • 21
  • 100
  • 124
Adam Tuttle
  • 19,517
  • 17
  • 76
  • 110
  • 1
    If I configured jest with a babel config like this `{presets: [['@babel/preset-env', {targets: {node: 'current'}}]]};` then regenerator runtime was not needed (without the node:'current' part it did warn about this). See https://jestjs.io/docs/getting-started#using-babel – Colin D Aug 26 '21 at 03:16
0

To add support for React and react-testing-library it may be useful to eject CreateReactApp and take all needed Jest configuration from the package.json. It is ready to use with another bundler, Rollup in my case.

bFunc
  • 1,294
  • 1
  • 12
  • 22
0

Below is how I setup jest, typescript and ES Modules for my project.

jest.config.js

/**
 * @type {import('ts-jest/dist/types').InitialOptionsTsJest} 
 * To configure ESM support, see: https://kulshekhar.github.io/ts-jest/docs/guides/esm-support
 * 
 **/
export default {
    preset: 'ts-jest/presets/default-esm',
    testEnvironment: 'node',
    extensionsToTreatAsEsm: ['.ts'],
    globals: {
        'ts-jest': {
            useESM: true
        }
    },
    setupFiles: ['<rootDir>/__tests__/setup.ts'],
};

tsconfig.json

{
    "compilerOptions": {
        "target": "ESNext",
        "module": "ESNext",
        "outDir": "./dist",
        "moduleResolution": "node",
       // "strict": true,
        "esModuleInterop": true,
        "inlineSourceMap": true,
    }
}

package.json scripts and devDependencies

"scripts": {
    "start": "node ./dist/server.js",
    "dev": "tsc-watch --onSuccess \"node ./dist/server.js\"",
    "test": "cross-env NODE_OPTIONS=--experimental-vm-modules jest"
  },
"devDependencies": {
    "@jest/globals": "^27.4.4",
    "@types/express": "^4.17.13",
    "@types/jest": "^27.4.0",
    "@types/supertest": "^2.0.11",
    "cross-env": "^7.0.3",
    "supertest": "^6.2.1",
    "ts-jest": "^27.1.3"
  }

__tests__/setup.ts

import dotenv from 'dotenv';


dotenv.config({
    path: './.env.test'
});
Gilbert
  • 1,591
  • 17
  • 23