jestjs / jest

Delightful JavaScript Testing.
https://jestjs.io
MIT License
44.23k stars 6.46k forks source link

Error: SyntaxError: Cannot use import statement outside a module #9292

Closed lean closed 4 years ago

lean commented 4 years ago

I have this issue when I'm trying to run the tests with this configuration:

jest.config.js

module.exports = {
  verbose: true,
  preset: 'react-native-web'
}

babel.config.js

module.exports = {
  presets: [
    '@babel/react',
    [
      '@babel/preset-env',
      {
        targets: {
          esmodules: true,
        },
      },
    ],
  ],
  plugins: [
    '@babel/plugin-proposal-function-bind',
    '@babel/plugin-proposal-class-properties',
    '@babel/plugin-syntax-dynamic-import',
    [
      'module-resolver',
      {
        alias: {
          '^react-native$': 'react-native-web',
        },
      },
    ],
  ],
  env: {
    production: {
      plugins: [
        [
          'transform-react-remove-prop-types',
          {
            mode: 'remove',
            ignoreFilenames: ['node_modules'],
          },
        ],
      ],
    },
  },
}

Then, the error:

    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import React from 'react'
                                                                                             ^^^^^^

    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)
daveyleo commented 4 years ago

I am also seeing this issue. For me it has cropped up when upgrading to the new react-native-modal-datetime-picker module that has an import and export default in it's index.js file and is isolated to our jest unit tests. Any insight you have on this issue would be appreciated.

brandonaaskov commented 4 years ago

We enabled tests in a Heroku pipeline for one of our apps, and this error started popping up. I can't replicate it locally, or in a Docker container (node 8 and LTS tested). I have no idea what's causing this, and the fact that it only happens in my Heroku environment has me scratching my head even more.

UPDATE This turned out to be pretty specific to our codebase and having NODE_ENV set to production in our test environment. Heroku defaults to setting that to test but we were overriding that causing some problems. I doubt this will help future travelers who have the same problem. Godspeed!

bln-engaged commented 4 years ago

I'm seeing this with crossfilter2 with jest unit tests.

/c/Users/newbe/play/edgauge/cvu-prototype-portal/node_modules/crossfilter2/src/index.js:1

({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import xfilterArray from './array';
                                                                                         ^^^^^^

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)
  at node_modules/dc/src/footer.js:21:28
  at Object.<anonymous> (node_modules/dc/src/footer.js:35:1)

Using jest@24.9.0 from react-scripts@3.3.0 importing crossfilter2@1.5.0.

Update: I resolved my issue with crossfilter by upgrading to crossfilter 1.5.1 which changed it's CommonJS entry point.

lukmajewski commented 4 years ago

In my configurations ts-jest + jest-puppeteer I added the following transform property to jest.config.js:

module.exports = {
  preset: 'jest-puppeteer',
  transform: {"\\.ts$": ['ts-jest']}
};

and this solved the issue

lean commented 4 years ago

I could resolve the issue with this help: https://stackoverflow.com/questions/55794280/jest-fails-with-unexpected-token-on-import-statement

zohaibtanwir commented 4 years ago

@lukmajewski answer helped me too.

alimurtaza0830 commented 4 years ago

I am having the same issue, i'm using CRA, don't know what to do.

tattivitorino commented 4 years ago

I am having this issue with @react-native-firebase/app v6

/.../node_modules/@react-native-firebase/app/lib/index.js:18
    import { getFirebaseRoot } from './internal/registry/namespace';
    ^^^^^^

    SyntaxError: Cannot use import statement outside a module

    > 1 | import firebase from '@react-native-firebase/app';
        | ^
      2 | import '@react-native-firebase/firestore';
      3 | import '@react-native-firebase/crashlytics';
      4 | 

      at ScriptTransformer._transformAndBuildScript (node_modules/@jest/transform/build/ScriptTransformer.js:537:17)
      at ScriptTransformer.transform (node_modules/@jest/transform/build/ScriptTransformer.js:579:25)
      at Object.<anonymous> (src/config/rnFirebase.js:1:1)

My jest config is in the package.json as follows, could it be a problem?

{
  "scripts": {
    "postinstall": "jetify",
    "android": "react-native run-android",
    "ios": "react-native run-ios",
    "web": "expo start --web",
    "start": "react-native start",
    "test": "jest"
  },
  "dependencies": {
    "@react-native-community/async-storage": "^1.7.1",
    "@react-native-firebase/app": "^6.2.0",
    "@react-native-firebase/auth": "^6.2.0",
    "@react-native-firebase/crashlytics": "^6.2.0",
    "@react-native-firebase/firestore": "^6.2.0",
    "expo": "~36.0.0",
    "expo-asset": "^8.0.0",
    "expo-font": "^8.0.0",
    "expo-linear-gradient": "^8.0.0",
    "expo-location": "^8.0.0",
    "expo-permissions": "^8.0.0",
    "formik": "^2.0.8",
    "geofirestore": "^3.3.1",
    "geolib": "^3.2.0",
    "haversine": "^1.1.1",
    "js-sha256": "^0.9.0",
    "lodash": "^4.17.15",
    "moment": "^2.24.0",
    "moment-duration-format": "^2.3.2",
    "native-base": "^2.13.8",
    "react": "~16.9.0",
    "react-dom": "~16.9.0",
    "react-native": "~0.61.4",
    "react-native-base64": "^0.0.2",
    "react-native-dotenv": "^0.2.0",
    "react-native-elements": "^1.2.7",
    "react-native-gesture-handler": "~1.5.0",
    "react-native-keyboard-aware-scroll-view": "^0.9.1",
    "react-native-maps": "^0.26.1",
    "react-native-maps-animated-polyline": "^1.0.6",
    "react-native-maps-super-cluster": "^1.6.0",
    "react-native-reanimated": "~1.4.0",
    "react-native-safe-area-context": "0.6.0",
    "react-native-safe-area-view": "^1.0.0",
    "react-native-scalable-image": "^1.0.0",
    "react-native-screens": "~2.0.0-alpha.12",
    "react-native-splash-screen": "^3.2.0",
    "react-native-svg": "^9.13.6",
    "react-native-unimodules": "~0.7.0",
    "react-native-web": "~0.11.7",
    "react-navigation": "^4.0.10",
    "react-navigation-drawer": "^2.2.2",
    "react-navigation-header-buttons": "^3.0.4",
    "react-navigation-stack": "^1.9.4",
    "react-navigation-tabs": "^2.5.6",
    "react-redux": "^7.1.1",
    "redux": "^4.0.4",
    "redux-thunk": "^2.3.0",
    "reselect": "^4.0.0",
    "throttle-debounce": "^2.1.0"
  },
  "devDependencies": {
    "@babel/core": "~7.6.0",
    "babel-jest": "~24.9.0",
    "jest": "~24.9.0",
    "jest-expo": "^36.0.0",
    "jetifier": "~1.6.4",
    "metro-react-native-babel-preset": "~0.56.0",
    "react-native-svg-transformer": "^0.14.3",
    "react-test-renderer": "~16.9.0",
    "redux-devtools-extension": "^2.13.8"
  },
  "jest": {
    "projects": [
      {
        "preset": "jest-expo/ios"
      },
      {
        "preset": "jest-expo/android"
      }
    ],
    "transformIgnorePatterns": [
      "node_modules/(?!(jest-)?react-native|react-clone-referenced-element|@react-native-community|expo(nent)?|@expo(nent)?/.*|react-navigation|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base|@react-native-firebase/.*|react-native-firebase)"
    ]
  },
  "private": true
}

What am I missing? I am new to unit testing so any help will be very much appreciated!!!

stefcameron commented 4 years ago

@lean's StackOverflow link helped me solve this issue. Thanks!

Demidarus commented 4 years ago

Hi , I am new to Vue Unit Testing and i keep getting the same Error after trying my first test.It seems to work for the first 2 import statements , but not for the epic-spinners one .I tried everything and looked up a lot over the forums and Github , but i couldnt find a solution. everything i try doesnt seem to work. I need help please !

Thanks :)

Error

 PASS  test/jesttest.spec.js (5.243s)
  ● Console

    console.log test/jesttest.spec.js:18
      red

 FAIL  test/ExitUserCompany.spec.js
  ● Test suite failed to run

    Jest encountered an unexpected token

    This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.

    By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".

    Here's what you can do:
     • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     • If you need a custom transformation specify a "transform" option in your config.
     • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/en/configuration.html

    Details:

    C:\9raya\anforderungsportal\anforderungsportal\frontend\node_modules\epic-spinners\src\lib.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import HollowDotsSpinner from './components/lib/HollowDotsSpinner.vue';
                                                                                             ^^^^^^

    SyntaxError: Cannot use import statement outside a module

      73 | import {CompanyService} from "@/common/api/company.service";
      74 | import {AssetDBDataService} from "@/common/api/assetDBData.service";
    > 75 | import { SelfBuildingSquareSpinner } from 'epic-spinners'
         | ^
      76 | 
      77 |   moment.locale('de');
      78 | 

      at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1059:14)
      at src/layouts/MainLayout.vue:75:1
      at Object.<anonymous> (src/layouts/MainLayout.vue:290:3)

Test Suites: 1 failed, 1 passed, 2 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        22.188s

package.json (with Jest config)

{
  "scripts": {
    "serve": "vue-cli-service serve --host localhost",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint",
    "test": "jest"
  },
  "dependencies": {
    "@babel/polyfill": "^7.2.5",
    "@babel/runtime": "^7.3.1",
    "axios": "^0.18.0",
    "bulma": "^0.7.5",
    "deep-object-diff": "^1.1.0",
    "epic-spinners": "^1.1.0",
    "etcdjs": "^2.4.2",
    "etcdjs-promise": "^1.0.0",
    "js-base64": "^2.5.1",
    "js-file-download": "^0.4.9",
    "keycloak-js": "^4.0.0",
    "luxon": "^1.17.1",
    "moment": "^2.24.0",
    "register-service-worker": "^1.5.2",
    "url-loader": "^1.0.1",
    "vee-validate": "^2.2.12",
    "vue": "2.6.5",
    "vue-axios": "^2.1.4",
    "vue-cookies": "^1.6.1",
    "vue-datetime": "^1.0.0-beta.10",
    "vue-router": "^3.0.1",
    "vue-select": "^3.1.0",
    "vuedraggable": "^2.23.0",
    "vuex": "^3.1.0",
    "vuex-router-sync": "^5.0.0"
  },
  "devDependencies": {
    "@babel/plugin-transform-runtime": "^7.2.0",
    "@vue/cli-plugin-babel": "^3.3.0",
    "@vue/cli-plugin-eslint": "^3.3.0",
    "@vue/cli-plugin-pwa": "^3.3.0",
    "@vue/cli-service": "^3.3.0",
    "@vue/test-utils": "^1.0.0-beta.31",
    "ant-design-vue": "^1.4.5",
    "babel-core": "^7.0.0-bridge.0",
    "babel-jest": "^25.1.0",
    "babel-plugin-import": "^1.11.0",
    "jest": "^25.1.0",
    "jest-transform-stub": "^2.0.0",
    "less": "^3.9.0",
    "less-loader": "^4.1.0",
    "vue-jest": "^3.0.5",
    "vue-template-compiler": "2.6.5"
  },
  "jest": {
    "moduleFileExtensions": [
      "js",
      "json",
      "vue",
      "ts"
    ],
    "moduleNameMapper": {
      "^@/(.*)$": "<rootDir>/src/$1",
      "^.+.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$": "jest-transform-stub"
    },
    "transform": {
      ".*\\.(vue)$": "vue-jest",
      "^.+\\.js$": "<rootDir>/node_modules/babel-jest",
      ".+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$": "jest-transform-stub"
    },
    "modulePaths": [
      "<rootDir>/src",
      "<rootDir>/node_modules"
  ],
  "transformIgnorePatterns": ["/node_modules/(?!epic-spinners)/"]
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not ie <= 8"
  ]
}

.babelrc

{
    "env": {
      "test": {
        "presets": [["@babel/env", { "targets": { "node": "current" } }]]
      }
    }
  }

babel.config.js

module.exports = {
  plugins: [
    [
      "import",
      { libraryName: "ant-design-vue", libraryDirectory: "es", style: true }
    ],
    "@babel/plugin-syntax-dynamic-import"
  ]
}
dimahali commented 4 years ago

I wrote an article to sum up the solutions as i was unable to find a proper solution for the issue. Hope this will help https://xperimentalhamid.com/how-do-i/fix-cannot-use-import-statement-outside-a-module/

ghost commented 4 years ago

I'm having this problem I've never had before. What can I do.

screenshot 2020-04-06 a las 18 59 31

fnlearner commented 4 years ago

and how can i solve this problem in a vue project using @vue/composition

module.exports = {
  preset: "@vue/cli-plugin-unit-jest/presets/typescript-and-babel",
  transformIgnorePatterns: [
    "/node_modules/(?!lib-to-transform|other-lib)",
    "./src/common/index.js",
  ]
};

it is my jest.config.js

gangsthub commented 4 years ago

I solved the f***ing thing by migrating the .babelrc file to babel.config.js! Shocker.

GooBall commented 4 years ago

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

Ditto :man_facepalming:. I had to move over to a .babelrc for integration with parcel (they don't support babel.config.js). Rather annoying that I am now going to have to have both for the time being...

richbrill commented 4 years ago

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

I solved the thing by actually creating any sort of babel configuration file in the first place! Duh...

christopher-18 commented 4 years ago

Facing same problem. .bablerc

{
  "presets": ["module:metro-react-native-babel-preset"]
}

package.json

{

  "scripts": {
    "start": "node node_modules/react-native/local-cli/cli.js start",
    "test": "jest",
    "prepare": "patch-package",
    "postinstall": "jetify -r"
  },
  "rnpm": {
    "assets": [
      "./assets/fonts/"
    ]
  },
//this contains some other dependencies
  "dependencies": {
    "react": "^16.8.6",
    "react-native": "^0.59.2",
   "react-native-router-flux": "^4.0.6",
    "react-navigation": "^2.18.3",
  },
  "devDependencies": {
    "@babel/core": "^7.4.3",
    "babel-core": "^6.26.3",
    "babel-jest": "^23.4.2",
    "babel-preset-react-native": "^5.0.2",
    "jest": "^23.5.0",
    "jest-transform-stub": "^1.0.0",
    "jetifier": "^1.6.4",
    "metro-react-native-babel-preset": "^0.51.1",
    "react-test-renderer": "^16.3.1"
  },
  "jest": {
    "preset": "react-native",
    "transform": {
      "^.+\\.js$": "<rootDir>/node_modules/react-native/jest/preprocessor.js"
    },
    "transformIgnorePatterns": [
      "node_modules/(?!react-native|react-navigation)",
      "node_modules/(?!react-native|react-native-router-flux)",
    ],
    "moduleNameMapper": {
      ".+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$": "jest-transform-stub"
    },
    "collectCoverage": true
  }
}

One of the test case which I am executing aboutus.test.js

import "react-native";
import AboutUs  from "../scenes/aboutus/aboutUs";
import renderer from "react-test-renderer";

const tree = renderer.create(<AboutUs />).toJSON();

it("renders Floating Input Screen ", () => {
  expect(tree).toMatchSnapshot();
});

On running npm test

_tests_/aboutus.test.js
   Test suite failed to run

 node_modules\react-navigation-deprecated-tab-navigator\src\index.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import createTabNavigator from './createTabNavigator';
                                                                                             ^^^^^^

    SyntaxError: Cannot use import statement outside a module

      at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/script_transformer.js:403:17)
      at Object.<anonymous> (component/react-native-router-flux/src/navigationStore.js:20203:96)

Is there anything in my initial configuration, as it was working fine when i was using react native 0.53 version.

ghost commented 4 years ago

Have a similar issue

Hi everyone, I'm workin' with a webpack.config.js'and main.js files, but I'm still getting errors, it must be the node version, I've the latest v14.4.0 and I'm still getting these errors.

I already did the type: module in package.json and it doesn't work because I get another error in the terminal.

I always get these errors in all my projects, both with .ts and .js files, some time ago I didn't get these errors, and I used to work with ES6 imports/exports, but recently, without knowing why, it doesn't let me work anymore and I gotta import packages and modules with the CommonJS require().

screenshot 2020-06-16 a las 16 20 15

screenshot 2020-06-16 a las 16 20 23

screenshot 2020-06-16 a las 16 20 32

ghost commented 4 years ago

Also had this issue recently. Posted a working configuration here https://stackoverflow.com/a/63118113/6456392

Hope it helps! 🙌

lifeeric commented 4 years ago

If you're using Typescript, then you should install ts-jest and configure it!

elyobo commented 4 years ago

Similar issue, but the module I'm having problems with has both es6 and cjs versions, and I'd rather use the cjs version rather than transpile the es6 one. The fixes I've seen all seem to be forcing babel to transpile, which seems like a bad fix when an already transpiled version is available. Is there a way to have jest prefer the commonjs version main instead of module?

Edit: this is very odd, because it seems like module is not actually supported :thinking:

Edit: OK, it's because I'm explicitly importing the module path version, because the thing I want isn't exported from the default entry :facepalm:

Edit: I wish there was a sane way to do a module or main relative import, rather than having to specify the full path (which then forces the resolver to use that version instead of picking the right cjs or es6 version), or having to expose the export (which then forces large bundle sizes on anything using the cjs version, which can't tree shake).

kauecastro commented 4 years ago

In my case I'm using nextJs, and I solved my problem removing "next/babel" preset when I'm on Test enviroment (For any reason, using "next/babel", console shows the error: "SyntaxError: Cannot use import statement outside a module"):

babel.config.js

const isTest = String(process.env.NODE_ENV) === 'test';

const config = { presets: [...], plugins: [...]}

if(!isTest) {
  config.presets.push("next/babel")
}

module.exports: config;
JSONRice commented 4 years ago

@kauecastro NextJS is very nice. What solved the problem for me was rather simple. An upgrade from Jest v23 to v24 resolved the issue. I tried everything here and also tweaked my jest.config.js and babel.config.js and nothing worked. Here's what is in my package.json and it works perfectly:

"jest": "^24.9.0"
tillsanders commented 4 years ago

Just a quick reminder for everyone (including my future self in about 6 months – Hi 👋 Yes, I'm talking to you!):

This can also occur when you're trying to import a file that is importing a dependency that is simply not using the ES6 syntax. Most jest configurations are not (re-)compiling files from the node_modules directory, so make sure to import the CJS/UMD/ES6 version of your dependency, and not the ESM version. Sounds obvious and is definitely RTFM, but it took me a while to find this 🤷‍♂️

wongJonathan commented 3 years ago

As a relative beginner to configuring jest, I had a hard time figuring out why this error was happening on my project. What worked for me was to make sure that the transform property in the jest config included ts, tsx, js, and jsx for ts-jest and have transformIgnorePatterns include the path too that node module.

fsevenm commented 3 years ago

I still get the error. Any help please!

 FAIL  tests/topup-package/topup-package.spec.ts
  ● Test suite failed to run

    /home/fsevenm/nodejs-projects/deliverit/tests/test-environment.ts:1
    import NodeEnvironment from "jest-environment-node";
    ^^^^^^

    SyntaxError: Cannot use import statement outside a module

      at runTestInternal (node_modules/jest-runner/build/runTest.js:223:5)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        0.025 s
// test-environment.ts
import NodeEnvironment from "jest-environment-node";
import { createUser, destroyUsers } from "./utils";

class TestEnvironment extends NodeEnvironment {
  async setup(): Promise<void> {
    await super.setup();
    const { token } = await createUser();

    this.global.authToken = token;
  }

  async teardown(): Promise<void> {
    await destroyUsers();
    await super.teardown();
  }
}

export default TestEnvironment;
// jest.config.js
module.exports = {
  preset: "ts-jest",
  testEnvironment: "<rootDir>/tests/test-environment.ts",
  moduleNameMapper: {
    "@src/(.*)$": "<rootDir>/src/$1",
  },
  testPathIgnorePatterns: ["/node_modules/", "<rootDir>/build/"],
  globalTeardown: "<rootDir>/tests/teardown.ts",
};
joao-esteves commented 3 years ago

What worked for me was changing the modules option of Babel's ENV preset from false to auto.

{
  "presets": [
    ["@babel/preset-env", { "modules": "auto" }]
  ]
}
AKclown commented 3 years ago

In my configurations ts-jest + jest-puppeteer I added the following transform property to jest.config.js:

module.exports = {
  preset: 'jest-puppeteer',
  transform: {"\\.ts$": ['ts-jest']}
};

and this solved the issue

Thanks for helping me

willmeierart commented 3 years ago

What worked for me was changing the modules option of Babel's ENV preset from false to auto.

{
  "presets": [
    ["@babel/preset-env", { "modules": "auto" }]
  ]
}

thank you so much!

reginadiana commented 3 years ago

This work for me:

Add an file .babelrc

{
    "presets": [
      [
        "@babel/preset-env",
        {
          "useBuiltIns": "entry",
          "corejs": {"version": "3"}
        }
      ]
    ]
  }
tobek commented 3 years ago

For those who are running into this issue only on CircleCI, I was finally able to fix it there, the issue was that I hadn't added jest.config.js and babel.config.js to .circleci/config.yml's persist_to_workspace paths, so the files were being deleted between jobs when the workspace was reattached for tests after checking out the repo and building. No jest/babel configs and it's not going to work!

Thought I was going crazy. Had to SSH into CircleCI to fix, which I didn't know was an option and is a handy debugging tool.

github-actions[bot] commented 3 years ago

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions.