181

I'm using Jest to test my React app.

Recently, I added DeckGL to my app. My tests fail with this error:

Test suite failed to run

/my_project/node_modules/deck.gl/src/react/index.js:21
export {default as DeckGL} from './deckgl';
^^^^^^

SyntaxError: Unexpected token export

  at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/script_transformer.js:318:17)
  at Object.<anonymous> (node_modules/deck.gl/dist/react/deckgl.js:9:14)
  at Object.<anonymous> (node_modules/deck.gl/dist/react/index.js:7:15)

This looks like an issue with Jest transforming a node module before running it's tests.

Here is my .babelrc:

{
  "presets": ["react", "es2015", "stage-1"]
}

Here is my jest setup:

"jest": {
    "testURL": "http://localhost",
    "setupFiles": [
      "./test/jestsetup.js"
    ],
    "snapshotSerializers": [
      "<rootDir>/node_modules/enzyme-to-json/serializer"
    ],
    "moduleDirectories": [
      "node_modules",
      "/src"
    ],
    "moduleNameMapper": {
      "\\.(css|scss)$": "<rootDir>/test/EmptyModule.js"
    }
  },

I seem to have the correct things necessary to transform export {default as DeckGL }. So any ideas whats going wrong?

skyboyer
  • 22,209
  • 7
  • 57
  • 64
Don P
  • 60,113
  • 114
  • 300
  • 432
  • Did you forgot to add a semicolon to the line above the export? – GuyT Apr 04 '18 at 09:00
  • @DonP, can you try using the recommended [ts-jest](https://github.com/kulshekhar/ts-jest) and see if it helps? I don't want to crowd this question with another answer if it doesn't help you out – Tarun Lalwani Apr 06 '18 at 03:55
  • Nothing here helped but https://github.com/facebook/create-react-app/issues/2537#issuecomment-390341713 mentioned you can pass in `transformIgnorePatterns` as a command-line argument to `npm`/`yarn`/`craco` in package.json's `scripts`, and that worked! – Ahmed Fasih Jun 23 '22 at 20:58

14 Answers14

170

This means, that a file is not transformed through TypeScript compiler, e.g. because it is a JS file with TS syntax, or it is published to npm as uncompiled source files. Here's what you can do.

Adjust your transformIgnorePatterns allowed list:

{
  "jest": {
    "transformIgnorePatterns": [
      "node_modules/(?!@ngrx|(?!deck.gl)|ng-dynamic)"
    ]
  }
}

By default Jest doesn't transform node_modules, because they should be valid JavaScript files. However, it happens that library authors assume that you'll compile their sources. So you have to tell this to Jest explicitly. Above snippet means that @ngrx, deck and ng-dynamic will be transformed, even though they're node_modules.

Ates Goral
  • 137,716
  • 26
  • 137
  • 190
Ria Anggraini
  • 2,237
  • 2
  • 9
  • 26
  • Had to combine this with @Jimi Pajala's answer to get things to work when running tests. – s1mm0t Jul 28 '19 at 20:43
  • 26
    What is the reason for the nested negative lookahead `(?!...(?!...))` in the regex? – Hjulle Sep 27 '19 at 14:02
  • 21
    where do I put this? which file? – Elad Katz Jun 09 '20 at 17:22
  • 11
    @EladKatz I'm new to this, but I think this block is meant for package.json, and without the 'jest' wrapper you could put it in jest.config.js. – aweibell Sep 23 '20 at 10:09
  • 9
    Might just want to simplify the RegExp like this: `node_modules\/(?!(@ngrx|deck.gl|ng-dynamic))` – rmolinamir Jan 18 '22 at 07:04
  • 1
    This works for me, in my case Jest can't deal with imports from `lodash-es`. Whitelisting the package like this resolves the issue. – Son Nguyen Jul 06 '22 at 09:10
  • 3
    @EladKatz in the `jest.config.js` file. – Bullsized Jan 03 '23 at 12:30
  • This has fixed my tests but has made the tests long. Around 1 minute per test. – Hughesey Mar 31 '23 at 08:22
  • this helped some of my tests pass, but then a bunch failed with the following... any thoughts? SyntaxError: C:\Code\altitude-traffic\client\node_modules\domino\lib\sloppy.js: 'with' in strict mode. (10:4) 8 | Window_run: function _run(code, file) { 9 | if (file) code += '\n//@ sourceURL=' + file; > 10 | with(this) eval(code); | ^ 11 | }, 12 | EventHandlerBuilder_build: function build() { 13 | try { – Paul Fabbroni Apr 19 '23 at 16:43
  • my pkg files are in es6, and everything is like as you said, but adding `"/node_modules/(?!(THE_PKG)/)",` does not makes any difference and i still get the same `SyntaxError: Unexpected token 'export'` which point to the module that i'm trying to import from that es6 package – amdev Jul 19 '23 at 11:44
  • Thanks for the hint and explanation, this worked – SAM Aug 30 '23 at 06:48
60

And if you are using 'create-react-app', it won't allow you to specify 'transformIgnorePatterns' via Jest property in package.json

As per this https://github.com/facebook/create-react-app/issues/2537#issuecomment-390341713

You can use CLI as below in your package.json to override and it works :

"scripts": {
  "test": "react-scripts test --transformIgnorePatterns \"node_modules/(?!your-module-name)/\"",
},
Farhan Salam
  • 1,257
  • 11
  • 16
Ram
  • 671
  • 7
  • 6
  • 8
    CRA [3.0.2 added](https://github.com/facebook/create-react-app/pull/6055#event-2419503373) support for Jest `transformIgnorePatterns` in package.json. – medmunds Jan 17 '20 at 23:04
  • Worth noting that if you're using `react-app-rewired`, it takes over the processing for the `jest` property in `package.json`, and concatenates rather than replaces. So this solution will not work and you will have to place it in the script options or inside the overrides script – MichaelM Jul 05 '23 at 15:09
40

This is because Node.js cannot handle ES6 modules.

You should transform your modules to CommonJS therefore.

Babel 7 >=

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

And to use only for test cases add to .babelrc, Jest automatically gives NODE_ENV=test global variable.

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

Babel 6 >=

npm install --save-dev babel-plugin-transform-es2015-modules-commonjs

to .babelrc

"env": {
    "test": {
      "plugins": ["transform-es2015-modules-commonjs"]
    }
}
Roger Perez
  • 2,807
  • 29
  • 31
Jimi Pajala
  • 2,358
  • 11
  • 20
  • 9
    This works! However, make sure to run `jest --clearCache` I had to do that before it started working. – Dan Zuzevich Nov 02 '18 at 16:44
  • 1
    where do I add: "env": { "test": { "plugins": ["@babel/plugin-transform-modules-commonjs"] } } – joeCarpenter May 15 '19 at 01:48
  • 2
    @joeCarpenter to your `.babelrc` or to other babel config file you might be using eg `babel.config.js`. If you don't yet have one you can create new file in the project root with name `.babelrc` and add this under root `{ }` -tags. – Jimi Pajala May 15 '19 at 04:08
  • 4
    Had to combine this answer with @Ria Anggraini's answer to get things to work when running tests. – s1mm0t Jul 28 '19 at 20:43
18

Jest by default won't compile files in the node_modules directory.

transformIgnorePatterns [array]

Default: ["/node_modules/"]

An array of regexp pattern strings that are matched against all source file paths before transformation. If the test path matches any of the patterns, it will not be transformed.Default: ["/node_modules/"]

DeckGL seems to be in ES6, to make jest able to read it, you need to compile this as well.
To do that, just add an exception for DeckGL in the transformignorePatterns

"transformIgnorePatterns": ["/node_modules/(?!deck\.gl)"]

https://facebook.github.io/jest/docs/en/configuration.html#transformignorepatterns-array-string

lukas-reineke
  • 3,132
  • 2
  • 18
  • 26
9

It was work around #1 on this page that fixed it for me though workaround #2 on that page is mentioned in above answers so they may also be valid.

"Specify the entry for the commonjs version of the corresponding package in the moduleNameMapper configuration"

jest.config.js

    moduleNameMapper: {
        "^uuid$": require.resolve("uuid"), 
        "^jsonpath-plus$": require.resolve("jsonpath-plus") 
...
Elliot Rice
  • 101
  • 1
  • 2
8

In my case I use this config in the file package.json:

"jest": {
    "transformIgnorePatterns": [
      "!node_modules/"
    ]
  }
tomerpacific
  • 4,704
  • 13
  • 34
  • 52
  • Does Jest really give special meaning to a preceding `!` in `transformIgnorePatterns`? I'd guess this is effectively equivalent to writing `transformIgnorePatterns: []`. – ominug Apr 06 '23 at 18:06
  • Great answer. FYI if you want to exclude everything but your workspace you can write the pattern like this: `"!node_modules/(?!@src/*.)"` – kernel Aug 22 '23 at 11:15
5

I was having this issue with a monorepo. A package in the root node_modules was breaking my tests. I fixed by changing my local .babelrc file to babel.config.js. Explanation: https://github.com/facebook/jest/issues/6053#issuecomment-383632515

Pietro Coelho
  • 1,894
  • 1
  • 26
  • 34
  • Thanks for pointing that out. It worked for me after renaming the file and adding the exception for my esm library in `transformIgnorePatterns`! – Evgeniya Manolova Jul 06 '23 at 12:10
1

I was upgrading a project that uses a version of babel that reads the config from .babelrc, when I upgraded to a newer version I read:

https://babeljs.io/docs/en/configuration#whats-your-use-case

What's your use case?

You are using a monorepo?

You want to compile node_modules?

babel.config.json is for you!

On top of:

{
  "jest": {
    "transformIgnorePatterns": [
      "node_modules/(?!(module))"
    ]
  }
}

I renamed .babelrc to babel.config.json too.

Mauricio Poppe
  • 4,817
  • 1
  • 22
  • 30
0

This code worked for me // .babelrc

{
  "presets": [
    ["env", {
      "modules": "commonjs", // <- Check and see if you have this line
      "targets": {
        "browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
      }
    }],
    "stage-2"
  ],
  "plugins": ["transform-vue-jsx", "transform-runtime"],
  "env": {
    "test": {
      "presets": ["env", "stage-2"],
      "plugins": ["transform-vue-jsx", "transform-es2015-modules-commonjs", "dynamic-import-node"]
    }
  }
}

jest understands commonJs so it needs babel to transform the code for it before use. Also jest uses caching when running code. So make sure you run jest --clearCache before running jest.

Tested Environment:
Node v8.13.0
Babel v6+
Jest v27

NevetsKuro
  • 604
  • 7
  • 14
0

I'm using a monorepo (it contains multiple packages for the frontend and backend).

The package I'm testing imports a file from another package that uses the dependency uuid.

All the files are in Typescript (not Javascript).

The package I'm testing has a tsconfig file for testing only, called tsconfig.test.json. It has the properties commonjs and allowJs. Adding allowJs solves the problem when importing uuid, I don't know why.

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "../../dist/out-tsc",
    "module": "commonjs",
    "types": [
      "jest",
      "node"
    ],
    // Necessary to import dependency uuid using CommonJS
    "allowJs": true
  },
  "include": [
    "jest.config.ts",
    "**/*.test.ts",
    "**/*.d.ts"
  ]
}
Guillem Puche
  • 1,199
  • 13
  • 16
0

I got same error. Library A gave such error. I did not use this library in my code directly. I played with jest config a lot of time. But I found that I forget to mock library B in ...test.tsx file. After mocking there was not that error. Sounds pretty stupid but it works for me.

Jiml
  • 377
  • 3
  • 9
0

I had the exact same problem when using jest with vite+swc and a component using the d3 library (d3-array and d3-shape was having a problem).

This advice to add this to jest.config.js solved it:

transformIgnorePatterns: ['node_modules/(?!@ngrx|(?!deck.gl)|d3-scale)'],

This got me wondering why this worked because I don't use ngrx or deck.gl. But then I noticed that this is equivalent to:

 transformIgnorePatterns: ['(?!abc|(?!def))'],

The advice also works:

transformIgnorePatterns: ['!node_modules/'],

Which led me to the final answer of

transformIgnorePatterns: [],

Just adding this line with an empty array is the simplest answer which worked.

Dirk R
  • 602
  • 7
  • 14
0

I had the same problem after upgrading 2 projects from Angular 12 to Angular 14 and 15.

After much searching, the ONLY thing that turned both projects in good ones again was by upgrading the 'Rxjs' package to a newer/newest version. The ONLY thing.

Be sure to have that RxJs upgraded. After that I made sure to have the tslib upgraded as well.

The base Jest configuration was via this course.

tm1701
  • 7,307
  • 17
  • 79
  • 168
-4

I had the same error of importing dataSet from vis-data.js library

import { DataSet } from 'vis-data/esnext';

So I just removed /esnext from the path and now it works:

import { DataSet } from 'vis-data';
Jeremy Caney
  • 7,102
  • 69
  • 48
  • 77
Saymon
  • 1