308

I have a React application (not using Create React App) built using TypeScript, Jest, Webpack, and Babel. When trying to run yarn jest, I get the following error:

jest error

I have tried removing all packages and re-adding them. It does not resolve this. I have looked at similar questions and documentation and I am still not understanding something. I went so far as to follow another guide for setting up this environment from scratch and still received this issue with my code.

Dependencies include...

"dependencies": {
  "@babel/plugin-transform-runtime": "^7.6.2",
  "@babel/polyfill": "^7.6.0",
  "babel-jest": "^24.9.0",
  "react": "^16.8.6",
  "react-dom": "^16.8.6",
  "react-test-renderer": "^16.11.0",
  "source-map-loader": "^0.2.4"
},
"devDependencies": {
  "@babel/core": "^7.6.0",
  "@babel/preset-env": "^7.6.0",
  "@babel/preset-react": "^7.0.0",
  "@types/enzyme": "^3.9.2",
  "@types/enzyme-adapter-react-16": "^1.0.5",
  "@types/jest": "^24.0.13",

The component's import lines...

import * as React from "react";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import HomePage from "./components/pages";
import {
  Footer,
  Header,
  Navigation,
} from "./components/shared";

The test file....

import * as React from "react";
import * as renderer from "react-test-renderer";
import App from "../App";

it("Renders the Footer correctly", () => {
  const tree = renderer
    .create(<App />)
    .toJSON();
  expect(tree).toMatchSnapshot();
});

I expected to be able to use named imports in my components without my tests blowing up. It appears to fix the issue if I only use default imports throughout my solution, but I would prefer to not go that route.

Dave Mackey
  • 4,306
  • 21
  • 78
  • 136
Logan Shoemaker
  • 3,377
  • 2
  • 13
  • 11
  • 2
    FYI, I was running into this when setting up a custom TestSequencer for Jest and I just switched to using `require` instead of `import`, just for this one file. – Joshua Pinter Apr 11 '20 at 18:04
  • This can happen due to issue with environment variables too. See my other, but related answer here: https://stackoverflow.com/a/63749183 – Bence Szalai Sep 04 '20 at 23:57
  • In case anyone is running into this currently, this solution fixed this error in my case. https://github.com/react-hook-form/resolvers/issues/396#issuecomment-1114248072 – diemondtank May 13 '22 at 19:49
  • @diemondtank its apparently a package (hookform) specific solution. I see `if (pkg.name === '@hookform/resolvers')` in the `resolver.js`. – 丶 Limeー来夢 丶 Aug 10 '22 at 01:12
  • This appears to be caused by a bug in Jest: https://github.com/facebook/jest/issues/8365 – Elias Zamaria Oct 26 '22 at 23:58

26 Answers26

247

I was having the same failure (also using Babel, Typescript and Jest), it was driving me crazy for hours!

Ended up creating a new babel.config.js file specifically for the tests. I had a large .babelrc that wasn't getting picked up by jest no matter what I did to it. The main app still uses the .babelrc as this overrides babel.config.js files.

Steps I took:

Install jest, ts-jest, babel-jest, and @babel/preset-env:

npm i jest ts-jest babel-jest @babel/preset-env

Add babel.config.js (only used by jest)

module.exports = {presets: ['@babel/preset-env']}

In jest.config.js update to:

module.exports = {
  preset: 'ts-jest',
  transform: {
    '^.+\\.(ts|tsx)?$': 'ts-jest',
    '^.+\\.(js|jsx)$': 'babel-jest',
  }
};

package.json

  "scripts": {
    "test": "jest"
dyslexicanaboko
  • 4,215
  • 2
  • 37
  • 43
ajwl
  • 2,479
  • 1
  • 11
  • 4
91

Use Babel to transpile those JS Modules and you'll be able to write your tests with es6.

Install Babel/preset-env

npm i -D @babel/preset-env

Create a babel configuration file with the preset

//babel.config.js
module.exports = {presets: ['@babel/preset-env']}
Natan Williams
  • 1,447
  • 1
  • 8
  • 13
  • 5
    Direct and concise, thank you! For my project derived on [`tsdx`](https://github.com/formium/tsdx) this was the trick (along with `@babel/preset-react`). – Jason R Stevens CFA Sep 29 '20 at 13:33
  • 4
    Thank you, this resolved the issue on my end – Victor Karangwa Jul 27 '21 at 08:57
  • 5
    `npm i -D @babel/preset-env` gave me an error. Needed `npm i --save-dev @babel/preset-env` – guero64 Jan 10 '22 at 13:18
  • 4
    This works perfectly! _(Just note that you *cannot* be using `"type": "module",` in your `package.json` if you go this route.)_ – skladany Jun 09 '22 at 13:24
  • This worked almost perfectly. Had to use `babel.config.json` instead with ```{ "presets": ["@babel/preset-env"] }``` – Chantz Feb 21 '23 at 02:49
  • When `"type": "module"` filename extension should be **cjs** so name will look like this babel.config.cjs – FoC Jul 07 '23 at 08:40
34

I solved this by migrating the .babelrc file to babel.config.js! Shocker.

Troy Alford
  • 26,660
  • 10
  • 64
  • 82
Paul Melero
  • 1,323
  • 15
  • 15
22

I fixed it by simply appending the pattern after the run statement in package.json runner

{
  "scripts": {
    ...
    "test": "react-scripts test --transformIgnorePatterns 'node_modules/(?!my-library-dir)/'"
    ...

Then, just run npm test

Kostas Minaidis
  • 4,681
  • 3
  • 17
  • 25
Sonic Soul
  • 23,855
  • 37
  • 130
  • 196
17

For future references,

I solved the problem by using below jest config, after reading Logan Shoemaker's answer.

module.exports = {
  verbose: true,
  setupFilesAfterEnv: ["<rootDir>src/setupTests.ts"],
  moduleFileExtensions: ["js", "jsx", "ts", "tsx"],
  moduleDirectories: ["node_modules", "src"],
  moduleNameMapper: {
    "\\.(css|less|scss)$": "identity-obj-proxy"
  },
  transform: {
    '^.+\\.(ts|tsx)?$': 'ts-jest',
    "^.+\\.(js|jsx)$": "babel-jest",
    "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/file.js",
  }
};
Onur Özkan
  • 918
  • 1
  • 10
  • 20
  • 4
    My Jest config was only missing **moduleDirectories: ["node_modules", "src"],** of which I added and everything start working as expected. Thank you – ZAD Jul 12 '21 at 15:30
  • Thank you, `moduleFileExtensions: ["ts", "tsx", "js", "jsx" ]` fixed it in my case – Zeid Al-Rashwani Jun 13 '23 at 15:26
13

try this thing if you are using babel 6

  1. Adding @babel/plugin-transform-modules-commonjs in the plugin section of babel.config.js

or

  1. For my case import issue was due to the react file drop by adding that to transformIgnorePatterns

"transformIgnorePatterns": ["/node_modules/(?!react-file-drop)"]

Dennis
  • 20,275
  • 4
  • 64
  • 80
WaysToGo
  • 331
  • 3
  • 7
11

Solution: my named imports were coming from index.js files and I believe ts-jest needed them as index.ts files (I'm using Typescript). If anyone else runs into this error, couldn't hurt to check if you derped your file extensions.

I wasted a lot of time on this, unfortunately, but I learned a lot about webpack configurations and Babel.

Logan Shoemaker
  • 3,377
  • 2
  • 13
  • 11
  • 19
    How did you solve the problem with the `index.js` in other modules? – Teodor Ciuraru May 19 '20 at 08:25
  • 2
    I spend two hours resolving this error. And well, after reading this answer, I want to cry right now T_T. I'm migrating from js to typescript and I forgot to rename ".js" to ".ts" – aldenn Aug 30 '21 at 22:08
  • Why must the imports come from `index.ts` only? I have plenty of TS files from where I directly do `export class ABC` and I'd expect it to work. :-( – ankush981 Sep 11 '22 at 10:38
  • Also curious to know how did you sort this specific issue in the end. – Christopher Jan 10 '23 at 21:21
5

Add your test script in package.json with Node experimental feature: --experimental-vm-modules

In this way you won't require babel or other dependencies.

Examples:

"test": "NODE_OPTIONS='--experimental-vm-modules --experimental-specifier-resolution=node' jest"

If you get this error: zsh: command not found: jest, try with node passing jest.js like this:

"test": "NODE_OPTIONS='--experimental-vm-modules --experimental-specifier-resolution=node --trace-warnings' node node_modules/jest/bin/jest.js --detectOpenHandles"
  • For me, the following: ` "test": "NODE_OPTIONS='--experimental-vm-modules --experimental-specifier-resolution=node' jest",` doesn't fix the error, but instead changes it from `SyntaxError: Cannot use import statement outside a module` to `Must use import to load ES Module: ` – Matthew Strasiotto Aug 25 '23 at 03:31
  • Add `--experimental-modules` in your flags – Adrian Escutia Soto Sep 01 '23 at 16:32
4

I'm surprised that none of the answers does not give an elegant solution:

jest.config.js

module.exports = {
  ...,
  globals: {
    "ts-jest": {
      isolatedModules: true,
    },
  },
};

This compiles each file separately therefore avoiding the no exports issue.

Townsheriff
  • 569
  • 6
  • 14
2

Create .babelrc on the main directory and add this code and install these packages @babel/core, @babel/preset-env and @babel/preset-react

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "modules": "commonjs"
      }
    ],
    "@babel/preset-react"
  ]
}
Mohammed
  • 163
  • 1
  • 3
2

I discovered that this error might be triggered when you try to load a dependency that is made for the browser and, thus, cannot work with jest (node).

I had a lot of trouble solving this issue for @zip.js/zip.js lib. But I could do it like that:

Here is my jest.config.js. Adapt it to your need. The trick here is the moduleNameMapper that will make all imports to zip.js point to the file __mocks__/@zip.js/zip.js I created in my root folder.

export default {
  preset: 'ts-jest',
  testEnvironment: 'node',
  moduleNameMapper: {
    '@zip.js/zip.js': '<rootDir>/__mocks__/@zip.js/zip.js',
  },
}

And here is what I have in <rootDir>/__mocks__/@zip.js/zip.js file:

module.exports = {}
Sharcoux
  • 5,546
  • 7
  • 45
  • 78
1

Matching file extensions:

I importing a file named Todo.jsx in the root as ./src/Todo/. Whenever I changed it to Todo.js the problem went away.

Disclaimer: I'm not sure what the requirement is for having your file extension as jsx vs js for your components. It did not effect me at all, but I could imagine it could mess with intellisense or snippets.

Sam Autrey
  • 121
  • 1
  • 4
1

For me renaming file to babel.config.js worked. Here is my config file an NX project using next with Typescript along with Twin-macro


// .babelrc.js >> babel.config.js
module.exports = {
  presets: [
    [
      "@nrwl/react/babel",
      {
        "runtime": "automatic",
        "targets": {
          "browsers": [">0.25%", "not dead"]
        },
        "preset-react": {
          runtime: "automatic",
          importSource: "@emotion/react",
        },
      }
    ],
    '@babel/preset-env',
    '@emotion/babel-preset-css-prop',
    '@babel/preset-typescript'
  ],
  plugins: ['@emotion', 'macros', '@babel/plugin-transform-runtime', 'react-docgen'],
}

Also, please note even updating package.json works, https://kulshekhar.github.io/ts-jest/docs/getting-started/presets/#basic-usage

// package.json
"jest": {
    // Replace `ts-jest` with the preset you want to use
    // from the above list
    "preset": "ts-jest"
  }
STEEL
  • 8,955
  • 9
  • 67
  • 89
1

I needed to do a couple things to get this to work for me

  1. Rename my .babelrc to babel.config.js and make a little change:
// .babelrc
{
  "presets": [
    [
      "@babel/preset-env",
      {
        "corejs": "3.26",
        "useBuiltIns": "usage"
      }
    ],
    "@babel/preset-react"
  ],
  ...
}
// babel.config.js - This still works fine with webpack
module.exports = {
  "presets": [
    [
      "@babel/preset-env",
      {
        "corejs": "3.26",
        "useBuiltIns": "usage"
      }
    ],
    "@babel/preset-react"
  ],
  ...
}
  1. Add the following to my jest config file:
{
  ...  
  "transformIgnorePatterns": [
    "node_modules/(?!(react-leaflet-custom-control)/)"
  ],
  ...
}

Where react-leaflet-custom-control was the package causing issues for me.

Akaisteph7
  • 5,034
  • 2
  • 20
  • 43
0

I encountered the same problem with Typescript, Jest, and VueJS/VueCli 3. The normal build has no problem. only happens for Jest. I struggled for hours by searching. But no answer actually works. In my case, I have a dependency on my own typescript package which I specific "target": "es6" in the tsconfig.json. That's the root cause. So the solution is simply to change the dependent's (Not the same project) back to es5 tsconfig.json:

{
  "compilerOptions": {
    "target": "es5",
    ...
  },
  ...
}
Jianwu Chen
  • 5,336
  • 3
  • 30
  • 35
0

Personnaly I followed @ajwl setup but discovered that jsdom-worker inside setupFiles: section of jest.config.js was triggering that same error. Once removed, my tests were passing.

P.S. my babel.config.js is a bit different, since I have a Vuejs (v2) SPA (bundled with Vitejs):

module.exports = {
  plugins: ['@babel/plugin-transform-modules-commonjs'],
  presets: [['@babel/preset-env', { targets: { node: 'current' } }]]
}
onekiloparsec
  • 2,013
  • 21
  • 32
0

The problem is likely that jest doesn't support esmodules natively. Which can cause problems if youre typescript target is es6 or greater.

If you are testing the built typescript output, you could simply add a module=commonjs flag while transpiling. That way, your code can run with es6 or greater and still work with Jest.

"scripts": {
  "test": tsc --module commonjs && jest {your-output-folder}/
}

What's great about this is that I didn't have to add any additional babel dependencies or special jest runners :)

Cameron
  • 2,805
  • 3
  • 31
  • 45
0

I solved it by changing my tsconfig.json to a compatible native output

"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */

It is not ideal in every scenario but you might be okay with this.

0

All I had to do, was simply updating the package @babel/preset-env in the dev dependencies to the latest version

// package.json
"@babel/preset-env": "^7.18.6"
user17028407
  • 129
  • 1
  • 4
0

None of the answers helped me, what did help me was making sure my NODE_ENV was set to test, since babel config is per NODE_ENV using the wrong NODE_ENV by accident that is not configured in babel config will mean you wont be using babel and the typescript files will not be transformed.

It took me couple of hours to figure this one out so i hope it will save someone else the time it took me.

Kostyantin2216
  • 616
  • 1
  • 6
  • 15
0

Don't know why and how but how I solved the problem was really interesting. Just add __mocks__ folder in your src folder and create an empty file inside __mocks__ named axios.js

0

Update to the latest version. Imports work with jest 29.5.0 and ts-jest 29.1.0

yarn upgrade jest ts-jest

jest.config.json

  "roots": ["<rootDir>/"],
  "collectCoverageFrom": ["src/*.ts", "src/**/*.ts"],
  "transform": {
    "^.+\\.ts?$": "ts-jest"
  },
  "testMatch": ["<rootDir>/**/?(*.)(spec|test).(ts|js)?(x)"]
}
j4ys0n
  • 615
  • 6
  • 8
-1

Too late for this answer :) After trying all the possible solutions, this worked for me: The solution, that works for me:

  1. create a file named jest/mocks/@react-native-firebase/crashlytics.js

export default () => ({ log: jest.fn(), recordError: jest.fn(), });

  1. create a file named jest/jestSetupFile.js

import mockFirebaseCrashlytics from './mocks/@react-native-firebase/crashlytics';

jest.mock('@react-native-firebase/crashlytics', () => mockFirebaseCrashlytics);

  1. in package.json add

"jest": { "setupFiles": ["./jest/jestSetupFile.js"] },

Bonanza
  • 19
  • 6
-1

Using pnpm I had to change the transformIgnorePatterns to the correct path node_modules/.pnpm:

transformIgnorePatterns: ['/node_modules/.pnpm/(?!package-name)']
minlare
  • 2,454
  • 25
  • 46
-7

If you're using TypeScript, and you have a tsconfig.json file, try removing "module": "esnext" if you're using it

enter image description here

Sam Lahm
  • 93
  • 1
  • 10
-16

Running npm ci fixed this problem for me.

Matheus
  • 1
  • 1