When you use ECMAScript Modules in Node (v13.6.0 for me) combined with Jest, the following error occurs:
SyntaxError: Cannot use import statement outside a module
at ScriptTransformer._transformAndBuildScript (node_modules/@jest/transform/build/ScriptTransformer.js:537:17)
at ScriptTransformer.transform (node_modules/@jest/transform/build/ScriptTransformer.js:579:25)
Here is the test code I am trying to execute.
import { checks } from '../../../../src/utils/index.js'
describe('Array type check', () => {
test('to return false when not an array', () => {
expect(checks.array('string')).toEqual(false)
})
})
I suspect the issue is Jest is not configured to run Node code using "type: module" (ECMAScript Modules).
I resolved the issue by doing the following:
yarn add ts-jest -D
then in your jest.config.js
file put following:
module.exports = {
transform: {
'^.+\\.ts?$': 'ts-jest',
},
};
Correct, ESM is not supported. You can track #4842. In the meantime, you need to transpile to cjs (using babel, typescript, etc)
A more complete set of steps is:
npm i --save-dev jest babel-jest @babel/preset-env
module.exports
in your jest.config.js
transform: {
"^.+\\.jsx?$": "babel-jest"
},
babel.config.json
file with the following{
"presets": ["@babel/preset-env"]
}
After this, I was able to get files with imports working just fine.
I had the same problem when I started to used babel... But later, I had a solution... I haven't had the problem anymore so far... Currently, Node v12.14.1, "@babel/node": "^7.8.4", I use babel-node and nodemon to execute (node is fine as well..)
package.json:
"start": "nodemon --exec babel-node server.js "debug": "babel-node debug server.js" !!note: server.js is my entry file, you can use yours.
launch.json:
When you debug, you also need to config your launch.json file "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/babel-node" !!note: plus runtimeExecutable into the configuration.
Of course, with babel-node, you also normally need and edit another file, such as babel.config.js/.babelrc file
{
"presets": ["@babel/preset-env"]
}
Awsome workaround!!
FYI for some people, if you are using a .babelrc the changes didn't work for me. I had to delete my .babelrc it and just use the suggested babel.config.json
@smpeters solution worked for me, but I want to see if I can explain exactly why it worked, because TBH I have no idea what those steps actually do (but thank you @smpeters for posting them!)
babel-jest
module, "babel-jest"
is a path to that module. So I guess if the module were called babel-jest-hooray
then the "path to transformer" would be the string "babel-jest-hooray"
.babel-jest
module? Seems like it exists to use Babel to transform jest files, i.e. to solve this exact problem. If my supposition above is correct, then this is what it is: https://github.com/facebook/jest/blob/master/packages/babel-jest/src/index.ts#L163babel-jest
is a glue between Babel—which doesn't know about Jest—and Jest.@babel/preset-env
module is installed.@babel/preset-env
module? It is "a smart preset that allows you to use the latest JavaScript without needing to micromanage which syntax transforms", which basically means it sets all the defaults you want to do normal and unsurprising things. Nice!"preset"
configuration option comes in.Whew!
@smpeters I'm getting a ReferenceError: regeneratorRuntime is not defined
and it points to a async await function as the culprit.
Any ideas about this?
@changyeamoon I think that's because @babel/preset-env
doesn't have an explicit target and is by default targeting all web browsers, attempting to transform all code in the process.
If using Node, babel.config.json
should look like:
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"node": true
}
}
]
]
}
I solved the fucking thing by migrating the .babelrc
file to babel.config.js
! Shocker.
I solved the fucking thing by migrating the
.babelrc
file tobabel.config.js
! Shocker.
How did you do the migration?
Well I spent a whole day on this trying to figure out... turns out for me I reused a .js file from another project that was set to compiled everything. The new project did not and that .js file was exporting an ESM. So I changed the name to .ts and bang zoom! There's probably a way to include .js in the compile so it gets converted to ESM but since I'm converting everything to TS anyway I didn't bother. Please feel free to let me know though if you find out.
With the current version of ts-jest I didn't need the babel stuff. ts-jest 25.5.1 and typescript 3.9.3.
this is my jest.config.js
module.exports = {
preset: 'ts-jest',
coverageDirectory: 'coverage',
collectCoverageFrom: ['src/**/*.{ts,tsx,js,jsx}', '!src/**/*.d.ts'],
};
Dear @smpeters
I have the same issue on react-native. you solution did not work
I solved it for my React Native project. First I initialized a new TypeScript template with npx react-native init
and compared tsconfig.json files. I missed the following settings:
"module": "commonjs",
"lib": ["ES6"],
"isolatedModules": true,
"strict": true,
"noEmit": true,
Then I configured transformIgnorePatterns
for my es libs.
https://github.com/nrwl/nx/issues/812
In my case, there was a problem loading lodash
, so I solved by mocking the functions I needed to use, such as lodash-es/round
, so under __mocks__
folder, I just added another folder with lodash-es
and a file round.js
with something like module.exports = jest.fn(numb => numb);
That did the trick. Hope it helps someone else.
I solved the fucking thing by migrating the
.babelrc
file tobabel.config.js
! Shocker.
That's really helped, I've shocked too :)
I've came across this issue and wanted to leave a solution that worked in my case. We are using some internally developed library that we use in our apps. Because of that the libraries are only delivered as ES6 modules, so trying to test them threw an error from the issue title. What I had to do to fix was:
transformIgnorePatterns: ['node_modules/(?!@foobar)/']
Where foobar
is the library name we are using. From how I understand this allows Babel to transform ES6 modules correctly for Jest. And it got rid of the error.
My solution works for React JSX files. The other is for Typescript files.
They are similar solutions to similar problems.
On Sun, Aug 30, 2020 at 6:05 AM Danny Hinshaw notifications@github.com
wrote:
I'm just over here trying to figure out why @ziishaned
https://github.com/ziishaned 's answer is downvoted to oblivion when it
works for me:
[image: Screen Shot 2020-08-30 at 7 02 40 AM]
https://user-images.githubusercontent.com/24684771/91657446-f4b54f00-ea8e-11ea-8b10-fbd90c2de9ec.pngMeanwhile @smpeters https://github.com/smpeters solution seems to be
widely accepted and doesn't work for me...:
[image: Screen Shot 2020-08-30 at 7 04 51 AM]
https://user-images.githubusercontent.com/24684771/91657475-1e6e7600-ea8f-11ea-95f1-1e0312b8bdf8.png—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/facebook/jest/issues/9395#issuecomment-683406678, or
unsubscribe
https://github.com/notifications/unsubscribe-auth/AAAJQUTAG2GFPTYSA2ZXJGTSDIW63ANCNFSM4KFPEIEQ
.
For new coming, use this
jest.config.js
module.exports = {
preset: 'ts-jest/presets/js-with-babel'
};
@abrcdf1023 thank you.
Most helpful comment
A more complete set of steps is:
npm i --save-dev jest babel-jest @babel/preset-env
module.exports
in yourjest.config.js
babel.config.json
file with the followingAfter this, I was able to get files with imports working just fine.