Reputation: 63768
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?
Upvotes: 252
Views: 273764
Reputation: 356
I think Ria Anggraini's accepted solution above is correct, but it's worth noting if you're using Next.js that you might be affected by this issue. next/jest.js
makes it hard to transpile modules in node_modules
, but you can modify the baked config like this:
import nextJest from 'next/jest.js'
const createJestConfig = nextJest({
dir: './',
})
// add any custom config to be passed to Jest
/** @type {import('jest').Config} */
const config = {
...
// setting `transformIgnorePatterns` in here does not work
}
// work around https://github.com/vercel/next.js/issues/35634
async function hackJestConfig() {
// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
const nextJestConfig = await createJestConfig(config)();
// /node_modules/ is the first pattern, so overwrite it with the correct version
nextJestConfig.transformIgnorePatterns[0] = '/node_modules/(?!(micromark-extension-gfm))/';
return nextJestConfig;
}
export default hackJestConfig
Upvotes: 5
Reputation: 38770
In my case, it was due to a project exporting ESM syntax via .js
and Jest interpreting that as CommonJS, despite following all the guides to overwrite transformIgnorePatterns
.
The solution was to switch from jest
to vitest
.
vitest
: https://vitest.dev/guide/jest
to vitest
in your test script in package.json
Optionally you could a vitest.config.ts
file and add a default config:
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
globals: true,
},
});
Because vitest
does not export the Jest globals (like describe
), you can either set globals: true
, or manually import the required keywords in your test.
For a basic project, that's all that's needed. Vitest will handle ESM natively, and as an added bonus, it will be much faster.
Upvotes: 0
Reputation: 318
My solution to this issue with jest is to mock the esm files that it is having trouble with (in my case it is nanoid)
jest.config.js
{
...
setupFiles: ["./mock.js"]
}
src/mock.js
jest.mock('nanoid', () => {
return { nanoid: () => '1234' };
});
Upvotes: 3
Reputation: 31
The bottom line here did it for me:
transform: {
'^.+\\.ts?$': ['ts-jest', { isolatedModules: true, useESM: true }],
'^.+\\.tsx?$': [
'ts-jest',
{ useESM: true, tsconfig: { jsx: 'react-jsx' } }
],
'^.+\\.jsx?$': require.resolve('babel-jest')
}
That is, in addition to my babel.config.js:
module.exports = {
presets: [
['@babel/preset-env', { targets: { node: 'current' } }],
'@babel/preset-typescript'
]
};
Hope this helps someone too! I've been using the plasmo framework for building browser extensions--nothing else helped me get Jest going.
Upvotes: -1
Reputation: 101
This works for me:
//jest.config.js
const esModules = [
'nanoid',
'p-cancelable',
'reaflow',
'easy-email-core',
'uuid/dist/esm-browser',
'd3-path/src',
'd3-shape/src',
].join('|');
module.exports = {
testEnvironment: 'jsdom',
setupFiles: ['<rootDir>/setup.jest.js'],
globals: {
Uint8Array: Uint8Array,
},
transformIgnorePatterns: [`/node_modules/(?!${esModules})`],
transform: {
'^.+.[tj]sx?$': [
'babel-jest',
],
},
};
In mi case all items within esModules were giving me errors of "SyntaxError: Unexpected token export"
then
//babel.config.js
module.exports = {
// [...]
presets: [['@babel/preset-env', { targets: { node: 'current' } }], '@babel/preset-typescript'],
plugins: ['@babel/plugin-transform-react-jsx'],
env: {
test: {
plugins: ['@babel/plugin-transform-modules-commonjs'],
},
},
};
Upvotes: 0
Reputation: 3656
Was having the same problem.
export function flatten (target, opts) {
^^^^^^
SyntaxError: Unexpected token 'export'
I made sure my jest was properly installed and set up, as per Next.js docs, but still same issue. None of the popular solutions here were working for me either.
However, while running npm i
, I noticed this warning:
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE package: '[email protected]',
npm WARN EBADENGINE required: { node: '>=18' },
npm WARN EBADENGINE current: { node: 'v16.19.1', npm: '8.19.3' }
npm WARN EBADENGINE }
Since version 6.0.0, the flat package is distributed in ECMAScript modules.
The quickest way to fix it was to downgrade it to a version that is compatible with my node.js and my project settings:
npm i flat@5
And since then I've been able to run jest as expected (perhaps updating the node.js version would've solved it too).
Upvotes: 0
Reputation: 4636
I had the exact same problem when using jest 29.7.0 with React 18.
In my case this config worked after changing the .babelrc
into babel.config.js
module.exports = {
"jest": {
"transformIgnorePatterns": [
"node_modules/(?!(module))"
]
}
}
Upvotes: 1
Reputation: 7601
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.
Upvotes: 0
Reputation: 739
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.
Upvotes: 2
Reputation: 397
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.
Upvotes: 0
Reputation: 2655
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.
Upvotes: 210
Reputation: 4876
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.
Upvotes: 1
Reputation: 1414
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"
]
}
Upvotes: 1
Reputation: 121
In my case I use this config in the file package.json:
"jest": {
"transformIgnorePatterns": [
"!node_modules/"
]
}
Upvotes: 12
Reputation: 151
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")
...
Upvotes: 14
Reputation: 1
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';
Upvotes: -4
Reputation: 2378
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"]
}
}
Upvotes: 40
Reputation: 1006
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
Upvotes: 0
Reputation: 761
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)/\"",
},
Upvotes: 69
Reputation: 2072
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
Upvotes: 7
Reputation: 3322
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
Upvotes: 21