P.Brian.Mackey
P.Brian.Mackey

Reputation: 44285

Does Jest support ES6 import/export?

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?

Upvotes: 206

Views: 167333

Answers (13)

Paulo Coghi
Paulo Coghi

Reputation: 14969

[Dec 2023 UPDATE]

Now you can support ES6 and ESM (ECMAScript modules) natively.

It's a prerequisite to set "type": "module" to your package.json.

Here are the steps:

Step 1: Prevent Jest from trying to transform ESM code to CommonJS, updating your Jest config (package.json example below) with:

"jest": {
    ...
    "transform": {}
}

Step 2: To be able to parse ES modules without an external transformer (e.g., babel), start Node with the --experimental-vm-modules flag. This can be done by changing how Jest is started by the npm "test" script (again inside package.json):

"scripts": {
    "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js"
}

And that's it. :)

You can even uninstall your transformer packages if you were using them just for the tests.


[OUTDATED answer, just for historic purposes]

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.

Upvotes: 224

Gambitier
Gambitier

Reputation: 590

To resolve this issue, you'll need to configure Jest to handle ES6 modules properly. You can do this by using Babel to transpile your code so that Node.js can understand the ES6 syntax.

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

.babelrc

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

jest.config.js

module.exports = {
    testEnvironment: 'node',
    setupFilesAfterEnv: ['./jest.setup.js'],
    clearMocks: true,
    roots: ['./test'],
    testMatch: ['**/*.test.js'],
    transform: {
        '^.+\\.js$': 'babel-jest',
    },
    moduleNameMapper: {
        '^src/(.*)$': './src/$1',
        '^test/(.*)$': './test/$1',
    },
    .
    .
    .
    .
}

Upvotes: -1

Alex Aleluia
Alex Aleluia

Reputation: 61

To solve you need to add on package.json

"type": "module",

And set test property on package.json to

"test": "node --experimental-vm-modules node_modules/.bin/jest"

It works for me on node version v16.19.0. Reference - kevinhooke

Upvotes: 1

Kostanos
Kostanos

Reputation: 10424

As for today, with node 16 and jest 29 I only needed to define a test script as below:

package.json

"type": "module",
...
"scripts": {
    ...
    "test": "NODE_OPTIONS='--experimental-vm-modules' jest ."
  },

Upvotes: 2

Avi Cohen
Avi Cohen

Reputation: 3414

all is explained in the jest docs: jest docs

1.

npm install --save-dev babel-jest @babel/core @babel/preset-env
  1. in file: babel.config.js

    module.exports = {
      presets: [['@babel/preset-env', {targets: {node: 'current'}}]],
    };
    

Upvotes: 0

Gilbert
Gilbert

Reputation: 3324

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'
});

Upvotes: 1

CodeFinity
CodeFinity

Reputation: 1350

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

Should be good!

Upvotes: 10

bFunc
bFunc

Reputation: 1465

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.

Upvotes: 0

Radovan Kuka
Radovan Kuka

Reputation: 2047

UPDATE 2020 - native support of ECMAScript modules (ESM)


According to this issue, there is native support of ESM from [email protected]. 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)

Upvotes: 123

YOSEPH NOH
YOSEPH NOH

Reputation: 97

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"]
}

Upvotes: 4

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

Upvotes: 42

Adam Tuttle
Adam Tuttle

Reputation: 19824

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

Upvotes: 0

Razvan Antalut
Razvan Antalut

Reputation: 65

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"]
}

Upvotes: 4

Related Questions