I couldn't get rid of this SyntaxError: Cannot use import statement outside a module error no matter what I have tried and it got so frustrating. Is there anybody out here solved this issue? I have read a million stackoverflow and github issue threads. No clear solutions.
This is a React, Typescript, Webpack project. I am trying to test a module. But Jest won't transform the module to plain javascript somehow.
/Users/me/dev/Project/project/node_modules/variables/src/variables.js:12
import './main.js';
^^^^^^
SyntaxError: Cannot use import statement outside a module
17 |
18 | */
> 19 | import { GlobalVars } from 'variables'
| ^
20 |
21 | export const Vars = new GlobalVars()
22 |
Using env setup in babel.config: env.test.preset: ['@babel/plugin-transform-modules-commonjs']
modifying transform setup in Jest configuration as '^.+\\.jsx?$': 'babel-jest', '^.+\\.tsx?$': 'ts-jest' and all other possibilities around this.
In Jest configuration, testPathIgnorePatterns, transformIgnorePatterns
Using .babel.config.js instead of .babelrc.js
...and more.
package.json
"jest": {
"preset": "ts-jest",
"testEnvironment": "node"
}
.babelrc.js
module.exports = {
presets: [
['@babel/preset-env', { targets: { node: 'current' } }],
'@babel/preset-react',
'@babel/preset-typescript',
],
plugins: [
'@babel/plugin-transform-runtime',
'@babel/proposal-class-properties',
'@babel/transform-regenerator',
'@babel/plugin-transform-template-literals',
'react-hot-loader/babel',
],
}
variables.ts
import { GlobalVars } from 'variables'
export const Vars = new GlobalVars()
variables.spec.ts
import { Vars } from './variables.ts'
describe('Test The Package', () => {
it('Should accept new variables', () => {
Vars.newVariable = 'new variable'
expect(Vars.newVariable).toEqual('new variable')
})
})
Any idea on how to resolve this problem?
Since Jest is not working with esmodules well, you need to add these configurations in jest.config.js to tell Jest to use commonJS builds instead
moduleNameMapper: {
'^variables$': 'variables/dist/cjs',
'^[NAME OF MODULE YOU WANT TO IMPORT]$': '[NAME OF MODULE YOU WANT TO IMPORT]/dist/cjs'
}
I got stuck in the same situation. Due to I had a private untranspiled package which is based on TypeScript, and all my source files and test files were all applied with ECMA ( import syntax ), I encountered the following error as well.
SyntaxError: Cannot use import statement outside a module
The solutions I have tried.
jest.config.ts.node_modules, including cache, and reinstalled them.After all, I found ECMAScript Modules from the JEST official document, the four steps perfectly solved my problem. I pasted their instructions here, however, you should take a look at the document itself.
tl;dr: tsconfig.spec.json >
{ "compilerOptions": { "allowJs": true } }
Did everything else mentioned here:
Then I debugged into the transformer. First think I realized: the preconfigured workspace does not log anything, not even into ts-jest.log, not with --verbose or --debug and not even the warning, that would have been:
Got a
.jsfile to compile whileallowJsoption is not set totrue(file: {{path}}). To fix this:
- if you want TypeScript to process JS files, set
allowJstotruein your TypeScript config (usually tsconfig.json)- if you do not want TypeScript to process your
.jsfiles, in your Jest config change thetransformkey which value ists-jestso that it does not match.jsfiles anymore
(see: ts-jest-transformer.ts)
A simple solution would be to use a different preset in your jest.config.js file.
Instead of using the default "preset": "ts-jest", try use presets like "preset": "ts-jest/presets/js-with-ts". Based on the documentation, it will:
ts-jest/presets/js-with-ts
TypeScript and JavaScript files (.ts, .tsx, .js, .jsx) will be transformed by ts-jest to CommonJS syntax. You'll need to set allowJs to true in your tsconfig.json file.
Another way to solve it is and possible other subsequent issues regarding babel and typescript is to use ts-jest, quoted from Jest's getting started
However, there are some caveats to using TypeScript with Babel. Because TypeScript support in Babel is purely transpilation, Jest will not type-check your tests as they are run. If you want that, you can use ts-jest instead, or just run the TypeScript compiler tsc separately (or as part of your build process).