jestjs / jest

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

SyntaxError: Unexpected token import with babel-preset-env #4604

Closed damianobarbati closed 6 years ago

damianobarbati commented 6 years ago

What is the current behavior?

imac:react-redux-test damz$ yarn test
yarn test v0.27.5
$ jest --no-cache --coverage
 FAIL  ./test.js
  ● Test suite failed to run

    /Users/damz/Desktop/react-redux-test/test.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import _cloneDeep from 'lodash-es/cloneDeep';function _asyncToGenerator(fn) {return function () {var gen = fn.apply(this, arguments);return new Promise(function (resolve, reject) {function step(key, arg) {try {var info = gen[key](arg);var value = info.value;} catch (error) {reject(error);return;}if (info.done) {resolve(value);} else {return Promise.resolve(value).then(function (value) {step("next", value);}, function (err) {step("throw", err);});}}return step("next");});};}import { configure, shallow } from 'enzyme';
                                                                                             ^^^^^^

    SyntaxError: Unexpected token import

      at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/script_transformer.js:305:17)
          at Generator.next (<anonymous>)
          at Promise (<anonymous>)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        1.082s
Ran all test suites.
----------|----------|----------|----------|----------|----------------|
File      |  % Stmts | % Branch |  % Funcs |  % Lines |Uncovered Lines |
----------|----------|----------|----------|----------|----------------|
All files |  Unknown |  Unknown |  Unknown |  Unknown |                |
----------|----------|----------|----------|----------|----------------|
error Command failed with exit code 1.

Repro? Repro here: https://github.com/damianobarbati/react-redux-test Simply clone, yarn install and yarn test.

Maybe this is due to latest babel-preset-env + browserslist?

"browserslist": [
    "chrome 58",
    "safari 10"
],
"babel": {
    "presets": [
        [
            "env",
            {
                "modules": false,
                "useBuiltIns": "usage",
                "debug": false
            }
        ],
        "stage-0",
        "react",
        "jest"
    ],
    "plugins": [
        "lodash",
        "transform-decorators-legacy",
        "transform-class-properties"
    ]
},
"jest": {
    "bail": true,
    "verbose": true
},
"dependencies": {
    "autobind-decorator": "2.1.0",
    "axios": "^0.16.2",
    "babel-eslint": "8.0.1",
    "babel-jest": "21.2.0",
    "babel-plugin-lodash": "3.2.11",
    "babel-plugin-transform-class-properties": "6.24.1",
    "babel-plugin-transform-decorators-legacy": "1.3.4",
    "babel-polyfill": "7.0.0-alpha.1",
    "babel-preset-env": "2.0.0-alpha.19",
    "babel-preset-react": "6.24.1",
    "babel-preset-stage-0": "6.24.1",
    "enzyme": "3.1.0",
    "enzyme-adapter-react-16": "1.0.1",
    "enzyme-to-json": "3.1.1",
    "eslint": "4.8.0",
    "eslint-plugin-import": "^2.7.0",
    "eslint-plugin-jest": "21.2.0",
    "eslint-plugin-react": "^7.4.0",
    "jest": "21.2.1",
    "lodash-es": "4.17.4",
    "moxios": "0.4.0",
    "prop-types": "^15.6.0",
    "react": "16.0.0",
    "react-dom": "16.0.0",
    "react-redux": "^5.0.6",
    "react-test-renderer": "16.0.0",
    "recompose": "0.25.1",
    "redux": "^3.7.2",
    "redux-mock-store": "^1.3.0",
    "redux-promise": "0.5.3",
    "redux-thunk": "2.2.0"
}
cpojer commented 6 years ago

It seems like you aren't including the ES module to commonjs transform. Please add that.

Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions. Thank you :)

thymikee commented 6 years ago

You need to setup "test" env in your babel config and configure babel-preset-env to use "modules": "commonjs". There's a lot of examples in this issue tracker and in the wild.

damianobarbati commented 6 years ago

Thanks for helping @thymikee, I realize this is not an help forum but I tried this configuration you mentioned here too https://github.com/facebook/jest/issues/4263#issuecomment-322045234

"babel": {
    "presets": [
        [
            "env",
            {
                "modules": false,
                "useBuiltIns": "usage",
                "debug": false
            }
        ],
        "stage-0",
        "react",
        "jest"
    ],
    "plugins": [
        "lodash",
        "transform-decorators-legacy",
        "transform-class-properties"
    ],
    "env": {
        "test": {
            "presets": [
                [
                    "env",
                    {
                        "modules": "commonjs",
                        "useBuiltIns": "usage",
                        "debug": false
                    }
                ],
                "stage-0",
                "react",
                "jest"
            ],
            "plugins": [
                "lodash",
                "transform-decorators-legacy",
                "transform-class-properties",
                "transform-es2015-modules-commonjs"
            ]
        }
    }
},

and a whole lot of other ones but it looks like they're ignored. So I thought it was a problem of compatibility with latest babel-preset-env Thanks again for helping though : )

damianobarbati commented 6 years ago

Also, Babel explicitly says it is transpiling modules (setting debug=true in babel-preset-env options):

babel-preset-env: `DEBUG` option

Using targets:
{
  "chrome": "58",
  "safari": "10"
}

Using modules transform: commonjs <=== THANKS BUT I DON'T TRUST YOU

Using plugins:
  transform-exponentiation-operator { "safari":"10" }
  transform-async-to-generator { "safari":"10" }
rimzici commented 6 years ago

npm install --save-dev babel-jest

configuring jest as follows inside package.json solved the issue for me.

"jest": { "transform": { "^.+\\.jsx$": "babel-jest", "^.+\\.js$": "babel-jest" } }

"react-native": "^0.50.1", "jest": "^21.2.1", "babel-jest": "^21.2.0",

lunafi-evan commented 6 years ago

I've been struggling with this for a few hours now, can anyone spot what I'm missing? I always get:

SyntaxError: Unexpected token import

Here are my config files below, using babel-jest to transpile .js files, and adding a "test" env in .babelrc.

package.json

{
   "scripts": { 
     "test:unit": "jest --config jest-config.js"
   },
  "devDependencies": {
    "babel-core": "^6.26.0",
    "babel-jest": "^22.0.3",
    "babel-preset-2017": "0.0.0",
    "babel-preset-env": "^1.6.1",
    "babel-preset-es2015": "^6.24.1",
    "jest": "^22.0.3",
   }
}

jest-config.js

module.exports = {
  'rootDir': './',
  'verbose': true,
  'collectCoverage': true,
  'collectCoverageFrom': ['./**/*.js'],
  'coverageDirectory': '<rootDir>/coverage',
  'moduleFileExtensions': [
    'js'
  ],
  'transform': {
    '^.+\\.js$': 'babel-jest'
  },
  'coverageThreshold': {
    'global': {
      'branches': 70,
      'functions': 85,
      'lines': 85,
      'statements': 85
    }
  },
  'testResultsProcessor': './node_modules/jest-junit'
};

.babelrc

{
  "presets": [
    [
      "env",
      {
        "modules": false
      }
    ]
  ],
  "env": {
    "test": {
      "presets": [
        [
          "env",
          {
            "modules": false
          }
        ]
      ]
    }
  }
SimenB commented 6 years ago

modules: true in test, not false.

http://facebook.github.io/jest/docs/en/webpack.html#using-with-webpack-2

(PR welcome updating docs to use env instead of es2015)

AuthorProxy commented 6 years ago

So for anybody who has issues, this is a sample configuration to get it work:

npm i --save-dev jest

.babelrc

{
  "presets": [["env", {
    "debug": false,
    "modules": false
  }], "stage-0", "react"],
  "plugins": [
    "react-hot-loader/babel",
    "syntax-dynamic-import",
    "transform-class-properties",
    "transform-decorators-legacy"
  ],
  "env": {
    "test": {
      "presets": [["env", {
        "modules": "commonjs"
      }]]
    }
  }
}

tests.spec.js

// @flow
/* eslint-env jest */

describe('sample', () => {
  it('should be able to run tests', () => {
    expect(1 + 2).toEqual(3);
  });
});

package.json (cutted, nothing special for jest)

...
  "scripts": {
    "test": "jest",
    "test:watch": "npm test -- --watch",
    ...
    }

"devDependencies": {
    "babel-cli": "^6.26.0",
    "babel-core": "^6.26.0",
    "babel-eslint": "^8.2.2",
    "babel-jest": "^22.4.3",
    "babel-loader": "^7.1.4",
    "babel-plugin-syntax-dynamic-import": "^6.18.0",
    "babel-plugin-transform-decorators-legacy": "^1.3.4",
    "babel-plugin-transform-flow-strip-types": "^6.22.0",
    "babel-preset-env": "^1.6.1",
    "babel-preset-flow": "^6.23.0",
    "babel-preset-react": "^6.24.1",
    "babel-preset-stage-0": "^6.24.1",
    "css-loader": "^0.28.10",
    "dotenv-webpack": "^1.5.5",
    "eslint": "^4.18.2",
    "eslint-config-airbnb": "^16.1.0",
    "eslint-loader": "^2.0.0",
    "eslint-nibble": "^4.2.1",
    "eslint-plugin-babel": "^4.1.2",
    "eslint-plugin-flowtype": "^2.46.1",
    "eslint-plugin-import": "^2.9.0",
    "eslint-plugin-jsx-a11y": "^6.0.3",
    "eslint-plugin-react": "^7.7.0",
    "file-loader": "^1.1.11",
    "flow-bin": "^0.67.1",
    "flow-typed": "^2.3.0",
    "flux-standard-action": "^2.0.1",
    "html-loader": "^0.5.5",
    "html-webpack-plugin": "^3.0.4",
    "jest": "^22.4.3",
    "nodemon": "^1.17.3",
    "npm-run-all": "^4.1.2",
    "style-loader": "^0.20.3",
    "svg-react-loader": "^0.4.5",
    "url-loader": "^1.0.1",
    "webpack": "^4.4.1",
    "webpack-bundle-analyzer": "^2.11.1",
    "webpack-cli": "^2.0.10",
    "webpack-dev-server": "^3.1.1"
  },
  "dependencies": {
    "auth0-js": "^9.4.2",
    "axios": "^0.18.0",
    "babel-polyfill": "^6.26.0",
    "bootstrap": "^4.0.0",
    "date-fns": "^1.29.0",
    "dotenv": "^5.0.1",
    "express": "^4.16.3",
    "history": "^4.7.2",
    "http-proxy-middleware": "^0.18.0",
    "jwt-decode": "^2.2.0",
    "moment": "^2.21.0",
    "normalizr": "^3.2.4",
    "path": "^0.12.7",
    "prop-types": "^15.6.1",
    "react": "^16.2.0",
    "react-datepicker": "^1.2.2",
    "react-day-picker": "^7.1.1",
    "react-dom": "^16.2.0",
    "react-helmet": "^5.2.0",
    "react-hot-loader": "^4.0.0",
    "react-input-mask": "^1.2.2",
    "react-loadable": "^5.3.1",
    "react-redux": "^5.0.7",
    "react-router-dom": "^4.2.2",
    "react-router-redux": "^5.0.0-alpha.9",
    "react-select": "^1.2.1",
    "react-yandex-maps": "^2.1.4",
    "redux": "^3.7.2",
    "redux-actions": "^2.3.0",
    "redux-devtools-extension": "^2.13.2",
    "redux-form": "^7.3.0",
    "redux-immutable-state-invariant": "^2.1.0",
    "redux-logger": "^3.0.6",
    "redux-thunk": "^2.2.0",
    "styled-components": "^3.2.0"
  }
}
...

webpack the latest, and nothing special to jest too

reggie3 commented 6 years ago

@AuthorProxy Which config file does your sample go in? babel.rc, webpack.config, or the "jest" portion of package.json. And if webpack.config, what version of webpack are you using?

AuthorProxy commented 6 years ago

@reggie3 check the updated answer

francis-li commented 6 years ago

This minimal setup worked for me (jest w/ ES6):

.babelrc

{
  "env": {
    "test": {
      "presets": [
        ["env", { "modules": "commonjs" }]
      ]
    }
  }
}

package.json

{
  "devDependencies": {
    "babel-core": "^6.23.1",
    "babel-jest": "^22.4.3",
    "babel-preset-env": "^1.3.3",
    "jest": "^22.0.0"
  },
  "scripts": {
    "test": "NODE_ENV=test jest"
  },
  "engines": {
    "node": "^9.0.0"
  }
}
Izhaki commented 6 years ago

For those like me...

Mind untranspiled imports from node_modules

Quite a few libraries ship nowadays with the module property set in package.json pointing at the untranspiled (es6, typescript) version of the library. Some bundlers use these by default.

However, as the docs state:

Sometimes it happens (especially in React Native or TypeScript projects) that 3rd party modules are published as untranspiled. Since all files inside node_modules are not transformed by default, Jest will not understand the code in these modules, resulting in syntax errors. To overcome this, you may use transformIgnorePatterns to whitelist such modules. You'll find a good example of this use case in React Native Guide.

And the solution given here:

"transformIgnorePatterns": [
  "node_modules/(?!(react-native|my-project|react-native-button)/)"
]

(goes in jest.config.js or jest key in package.json)

Having included the above, meant neither ["env", { "modules": "commonjs" }] in .babelrc nor any transfrom override in jest was needed.

maarekj commented 6 years ago

@Izhaki You save my day

prarad commented 6 years ago

super minimal :) .babelrc { "presets": ["env"] }

StefanoSega commented 6 years ago

This actually works for me on my disk but it fails miserably when creating a Docker image.

My .babelrc looks like:

{
    "presets": [
       ["env", { "modules": false }],
      "react"
    ],
    "plugins": [
        "transform-object-rest-spread",
        "transform-decorators-legacy",
        "transform-class-properties",
        "syntax-dynamic-import"
    ],
    "env": {
      "development": {
        "presets": [
          "react-hmre"
        ]
      },
      "test": {
        "presets": [
          ["env"], 
          "react"
        ],
        "plugins": [
            "transform-class-properties"
        ]
      }
    }
  }

When dockerizing it returns the error:

FAIL tests/react/utils/dataParsing.test.js
  ● Test suite failed to run

    /app/tests/jestsetup.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import Enzyme from 'enzyme';
                                                                                             ^^^^^^

    SyntaxError: Unexpected token import

      at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/script_transformer.js:316:17)

The Dockerfile is:

FROM node:carbon

COPY ./ui /app
WORKDIR /app

RUN npm install

ENV NODE_ENV production
ENV DEBUG api

RUN npm run build:deploy

EXPOSE 8080
CMD ["node", "server"]

and the package script build:deploy runs immediately jest --no-cache

wiretapjs commented 6 years ago

I was getting the same error and i tried numerous recommendations made in this issue thread and the recommendation that fixed the issue for me was adding babel-jest to my project.

Make sure you have babel-jest added to your project as a dependency in your package.json file under devDependencies.

Next add this to your package.json file:

package.json "jest": { "setupTestFrameworkScriptFile": "/config/test-setup.js", "transform": { "^.+\.jsx?$": "babel-jest", "^.+\.js$": "babel-jest" } }

Lastly make sure you import babel-polyfill in your test-setup.js file that runs before your tests run which is what will transpile your es2015 code to normal javascript.

test-setup.js import 'babel-polyfill';

davecranwell-adestra commented 6 years ago

Just a note that on latest versions of webpack modules: true - mentioned in several responses above - isn't a valid option. You'll get the error:

Invalid Option: The 'modules' option must be either 'false' to indicate no modules, 
or a module type which can be be one of: 'commonjs' (default), 'amd', 'umd', 'systemjs'.

modules: commonjs is most likely what you want.

donaldpipowitch commented 6 years ago

I tried every suggestion in this thread and in other thread, but nothings seemed to work. My babel config seems to be loaded correctly, but is not applied. Creating a custom transformer seems to solve this: module.exports = require('babel-jest').createTransformer(yourConfig). No idea why.

SimenB commented 6 years ago

How do you load yourConfig?

donaldpipowitch commented 6 years ago

I tried different ways, but ideally I want .babelrc.js as used here. I threw a custom error inside that file to check, if babel-jest loads it and it was loaded. (But I also tried .babelrc and other formats.)

I want a structure like this:

./tests/.babelrc(.js)
./tests/jest.config.js
./tests/some-test.js

and run $ jest --config tests/jest.config.js. I have an example using ts-jest here and now want to create the same example as a js version here.

Update

Could it be that babel-jest loads this file only for some hash, but not to actually use its config? (See here.)

Update 2

This works.

./.babelrc // without .js, because of Babel 6
./tests/jest.config.js
./tests/some-test.js

This doesn't.

./tests/.babelrc // without .js, because of Babel 6
./tests/jest.config.js
./tests/some-test.js

It looks like process.cwd()/.babelrc is checked, not <rootDir>/.babelrc. (Interestingly the same seems to be true for tsconfig.json in ts-jest, but here you can specify the path to fix it.)

ThiefMaster commented 6 years ago

Happens for me as well, and if i cd into the directory that has my babel config (package.json with a babel section) it works fine.

It was working fine a few weeks ago, but after updating (within the ^ semver range) it started breaking.

Rovack commented 5 years ago

For me this only started happening after upgrading some dependencies, including babel-core (6.26.0->6.26.3) and babel-preset-env (1.6.1->1.7.0).

Simply installing babel-jest (23.6.0) solved it, with no configuration changes.

Edit: Upgrading jest from 22 to 23 works as well (without having to explicitly install babel-jest).

minhchu commented 5 years ago

I'm using @babel/preset-env so "presets": ["env"] doesn't work. Here is my working config:

// package.json
{
  "devDependencies": { 
    "@babel/core": "^7.1.2",
    "@babel/preset-env": "^7.1.0"
  }
}
// .babelrc
{
  "presets": [ 
    "@babel/preset-env"
  ]
}
RyanPWalker commented 5 years ago

For me, the problem was that I was importing a function from a path inside the node_module instead of just from the module itself. For example, changing import reduxForm from 'redux-form/es/reduxForm'; to import reduxForm from 'redux-form'; solved this error.

Pioneer-Linzi commented 5 years ago

image this is my babel config , image and this's my jest.conf.js ,I try many methods, but i can't solve this problem,

gpressman commented 5 years ago

For me this only started happening after upgrading some dependencies, including babel-core (6.26.0->6.26.3) and babel-preset-env (1.6.1->1.7.0).

Simply installing babel-jest (23.6.0) solved it, with no configuration changes.

Edit: Upgrading jest from 22 to 23 works as well (without having to explicitly install babel-jest).

I upgraded my jest to the most recent version, then was prompted to add '@babel/plugin-proposal-class-properties' to my babel config (which I had to install) and now I'm running again. Thanks!

shavo007 commented 5 years ago

got this issue also when i was optimizing my webpack. Fixed with the below config

module.exports = {
  presets: [
    [
      '@babel/preset-env',
      {
        modules: false
      }
    ],
    '@babel/preset-react'
  ],
  env: {
    test: {
      presets: [['@babel/preset-env', { modules: 'commonjs' }]]
    }
  },
  plugins: [
    '@babel/plugin-syntax-dynamic-import',
    'transform-react-remove-prop-types',
    [
      'transform-imports',
      {
        'react-router': {
          transform: 'react-router/${member}',
          preventFullImport: true
        }
      }
    ]
  ]
};
jahnaviv commented 4 years ago

Solution of @import Unexpected token=:)

Install package: npm i --save-dev identity-obj-proxy

Add in jest.config.js

module.exports = {
  "moduleNameMapper": {
    "\\.(css|less|scss)$": "identity-obj-proxy"
  }
}
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.