Skip to content

Instantly share code, notes, and snippets.

@rstacruz
Last active April 23, 2024 00:19
Show Gist options
  • Star 48 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save rstacruz/511f43265de4939f6ca729a3df7b001c to your computer and use it in GitHub Desktop.
Save rstacruz/511f43265de4939f6ca729a3df7b001c to your computer and use it in GitHub Desktop.
Setting up Jest with ESM

Setting up Jest with ESM

Here are some different ways on how to set up Jest to support ESM. This applies for Jest v25, Node v13, and Babel v7.

Method A: Native Node.js support

Node v14 and Jest v26 support ESM natively with the --experimental-vm-modules flag.

Install cross-env:

yarn add --dev cross-env

Add NODE_OPTIONS to the scripts.test in package.json:

"scripts": {
  "test": "cross-env NODE_OPTIONS=--experimental-vm-modules jest"
}

See tne Jest documentation for more info: https://jestjs.io/docs/ecmascript-modules

Method B: Using Babel

Add babel-jest.

yarn add --dev @babel/core @babel/plugin-transform-modules-commonjs babel-jest

Configure Babel. We'll use env.test here so not to interfere with your build process.

// babel.config.js
module.exports = {
  env: {
    test: {
      plugins: ["@babel/plugin-transform-modules-commonjs"]
    }
  }
};

Configure Jest:

// jest.config.js
module.exports = {
  "transform": {
    "^.+\\.[t|j]sx?$": "babel-jest"
  },
};

You're done.

Method C: Using jest-esm-transformer

Add jest-esm-transformer - this is a preset configuration of Babel to support ESM transpilation.

yarn add --dev jest-esm-transformer

Configure Jest.

// jest.config.js
module.exports = {
  "transform": {
    "\\.m?jsx?$": "jest-esm-transformer"
  },
};

You're done.

Method D: Using standard-things/esm

As of March 2020, using esm is currently not possible. Follow these threads for details.

Method E: Using buble

See buble-jest.

@sherlock1982
Copy link

The important thing for B,C and other transform based methods.
Jest doesn't transform node_modules by default so you need to modify transformIgnorePatterns to include modules you want to be transformed. For example like this:

transformIgnorePatterns: [
    "node_modules/(?!(stringify-entities|character-entities-legacy|character-entities-html4)/)"
],

Method E:

If you use ts-jest allow it to process js files as well.

transform: {
    ".*\\.(tsx?|js)$": "ts-jest",
},

And add allowJs=true to your tsconfig.json or tsconfig.spec.json.

@mcshaman
Copy link

mcshaman commented Aug 1, 2021

@sherlock1982 even with the transformIgnorePatterns I am not able to import ESM packages. I am currently using a node package called lowdb which I have been struggling to implement into a Jest test workflow. Fingers crossed I find a solution...

@mcshaman
Copy link

mcshaman commented Aug 1, 2021

Ok, so it turns out that the issue was to do with the fact that lowdb doesn't include a main property in their package.json, only the new exports property which jest-resolve does not yet support. I have posted my work around in Jest's Github issues.

@nalliot
Copy link

nalliot commented Jan 6, 2022

Thanks ! The Method C is not mentioned that much on SO and it was the perfect solution for a node project that doesn't use babel and has mixed esm and commonjs code.

@rwd
Copy link

rwd commented Jan 10, 2022

Method C got this working for us in a Nuxt & Vue 2 project with @vue/vue2-jest, where the other methods did not.

We also needed a Babel config of:

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

@viT-1
Copy link

viT-1 commented Jan 11, 2022

#9430 but can't configure it without annoying error
SyntaxError: Cannot use import statement outside a module

@CharlieGreenman
Copy link

@viT-1 got the same. Arg, this is frustrating

@viT-1
Copy link

viT-1 commented Jan 19, 2022

@CharlieGreenman I found mistake, it was single babel.config.json without separating for different environments (by NODE_ENV).
My (Windows) solution.
But have problems with globals & console (aren't defined).

@webdevamit
Copy link

Method C : kind of working for me but there are cases like optional changing it is still not able to recognize it, in the mean time did anyone had a work around for this.
the case scenario is like I had utility function in react JavaScript file which in turn using lodash function and I am trying to use this utility functions in automation test cases using jest, its stucked to optional chaining part and some other parts as well.
do anyone of you here can recommend something better

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment