Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

babel-jest does not transpile import/export in node_modules when Babel 7 is used #6229

Closed
dantman opened this issue May 22, 2018 · 43 comments

Comments

@dantman
Copy link

commented May 22, 2018

馃悰 Bug Report

I started getting the dreaded SyntaxError: Unexpected token import error again for lodash-es. And I spent hours debugging it, because I already had .babelrc and package.json:jest configured properly ("modules": "commonjs", a jest.transform for babel-jest, and transformIgnorePatterns set to not ignore node_modules/lodash-es).

After a lot of debugging and a little searching, it appears that Babel 7 has stopped using the project's .babelrc code in node_modules. This means that all the previous suggestions to just tell transformIgnorePatterns to transpile certain packages in node_modules and set "modules": "commonjs" in the test env to make WebPack import work with jest no longer work.

To Reproduce

Steps to reproduce the behavior:

  • Import an es-modules using library like lodash-es into your project
  • Write a Jest test that imports the file you import the es-modules using package
  • Setup a recent version of Babel 7
  • Configure .babelrc to use the env preset to transpile ES6 modules to CommonJS
  • Configure Jest to transform .js files with babel-jest and transformIgnorePatterns to not ignore the es-modules using package

Expected behavior

When babel-jest is used to transpile ES-modules using packages like lodash-es it should transpile the imports to CommonJS so they work with Jest.

Practically I believe it should be sufficient to add transform-modules-commonjs to the plugins list that babel-jest uses when the filename is a node_modules file and Babel 7 is used. This would also fix the fact that it's not good practice for the project's .babelrc (which may also include plugins for non-standard things like JSX and flow) to be used just to transpile ES6 / modules code in packages.

Link to repl or repo (highly encouraged)

https://gist.github.com/dantman/820f6232acc6f53bd1e57d21b09e1f89

Run npx envinfo --preset jest

Paste the results here:

  System:
    OS: macOS Sierra 10.12.6
    CPU: x64 Intel(R) Core(TM) i5-7267U CPU @ 3.10GHz
  Binaries:
    Node: 9.11.1 - ~/.nvm/versions/node/v9.11.1/bin/node
    Yarn: 1.6.0 - /usr/local/bin/yarn
    npm: 5.6.0 - ~/.nvm/versions/node/v9.11.1/bin/npm
  npmPackages:
    jest: ^22.4.4 => 22.4.4
@SimenB

This comment has been minimized.

Copy link
Collaborator

commented May 23, 2018

I don't think Jest should add babel transforms, beyond the ones it needs for its own purposes.

That said, Jest should load your babel config itself, so weird that it doesn't work...

@dantman

This comment has been minimized.

Copy link
Author

commented May 23, 2018

babel-jest doesn't load the confic, it reads it and uses it for caching, but to my knowledge it leaves babelrc handling up to Babel as it should.

However Babel no longer uses project config inside node_modules. So the only one able to add config for node_modules at this point is babel-jest.

@SimenB

This comment has been minimized.

Copy link
Collaborator

commented May 23, 2018

babel-jest doesn't load the confic, it reads it and uses it for caching, but to my knowledge it leaves babelrc handling up to Babel as it should.

Oh, you're correct, I confused it with the merge done by the createTransformer factory.

This seems more like a Babel issue rather than Jest, though. Is there an issue over there about it, and discussing the use case of transpiling node_modules?

@dantman

This comment has been minimized.

Copy link
Author

commented May 23, 2018

No, this is a change they explicitly made. They decided project config shouldn't affect node_modules, which is entirely reasonable since project config can contain stage-0, react/jsx, flow and other things that should not be used in packages. So it doesn't make sense for this to be considered a Babel bug or have an issue there.

They explicitly decided .babelrc should not affect node_modules. And they already give whoever is calling babel-core to transform files the ability to define plugins/presets that will run on the file even if it is in node_modules. Babel isn't doing anything unreasonable.

@luke-j

This comment has been minimized.

Copy link

commented May 25, 2018

Any updates on this? This is behaviour which was working before and is now not, which seems to be to be a clear regression. Fair enough if the behaviour is to be removed, but lacking any clear documentation indicating that, this just feels like a bug.

@mpospelov

This comment has been minimized.

Copy link

commented May 25, 2018

I had the same issue and I found this comment.
So you should rename the .babelrc file to babel.config.js which will export .babelrc object.

@luke-j

This comment has been minimized.

Copy link

commented May 28, 2018

Thanks for the suggestion @mpospelov. Unfortunately, it didn't seem to work for me.

@manico

This comment has been minimized.

Copy link

commented May 29, 2018

I have a problem on Mac also.
When I updated node modules cannot run tests anymore.
It fails to transpile from node_modules package even tough I set transformIgnorePatterns (did not change them since it worked).

antongolub added a commit to qiwi/uniconfig that referenced this issue Jun 8, 2018
@macrozone

This comment has been minimized.

Copy link

commented Jul 2, 2018

this happend to me when i updated a react-native project to 0.56.0. Since then, jest test can't be run anymore. transformIgnorePatterns seems to be completly ignored.

@austinkelleher

This comment has been minimized.

Copy link

commented Jul 6, 2018

Any additional thoughts on this @SimenB? I'm also seeing this issue.

@fhadsheikh

This comment has been minimized.

Copy link

commented Jul 9, 2018

I've got the same issue as @marcelerz. Ever since updating to React Native 56.0, transformIgnorePatterns seems to be ignored.

@austinkelleher

This comment has been minimized.

Copy link

commented Jul 9, 2018

For the record, I was able to fix the issue of my module in the node_modules folder not compiling properly by:

  1. Changing the filename .babelrc to babel.config.js and module.exports the config object
  2. Adding transformIgnorePatterns to my Jest config:
"transformIgnorePatterns": [
  // Change MODULE_NAME_HERE to your module that isn't being compiled
  "/node_modules/(?!MODULE_NAME_HERE).+\\.js$"
]
@amahrt

This comment has been minimized.

Copy link

commented Aug 15, 2018

Thanks @austinkelleher

We had something similar but a bit different,

your fix didn't work first - but then we realized that we were missing the .+\\.js$ at the end of the line, which worked just fine with jest and babel 6 but doesn't with babel 7.

artkravchenko added a commit to artkravchenko/production-react-boilerplate that referenced this issue Aug 19, 2018
fix(test): enable babel-jest to transform JSX (#2)
babel-jest requires babel config to be stored in .js file
to transform JSX expressions via @babel/preset-react.
See facebook/jest#6229 (comment)
@master-7

This comment has been minimized.

Copy link

commented Sep 7, 2018

  鈼 Test suite failed to run

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

    SyntaxError: Unexpected identifier

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

package.json

"jest": {
    "transform": {
      "^.+\\.(js|jsx|ts)$": "babel-jest",
      "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/internals/jest/fileTransform.js",
      "\\.(css|less)$": "<rootDir>/internals/jest/cssTransform.js"
    },
    "setupTestFrameworkScriptFile": "<rootDir>/internals/jest/settings.js",
    "testURL": "http://localhost/"
  }

Versions:

"jest": "^23.5.0",
"babel-jest": "^23.4.2"

/internals/jest/settings.js

import Enzyme from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'

Enzyme.configure({ adapter: new Adapter() })

Could you please help?

@norbertkeri

This comment has been minimized.

Copy link

commented Sep 10, 2018

Renaming .babelrc to babel.config.js worked for me

@SimenB

This comment has been minimized.

Copy link
Collaborator

commented Sep 11, 2018

See #6053 (comment), it explains the need for babel.config.js. I don't think Jest should do anything special here, open to being convinced otherwise, though.

@komali2

This comment has been minimized.

Copy link

commented Oct 17, 2018

SimenB, that solution is not working for vue-cli.

vuejs/vue-cli#1584

We don't have .babelrc, or .babel.config.js. I tried creating a basic one, it didn't work.

@moon004

This comment has been minimized.

Copy link

commented Oct 27, 2018

@master-7 , i had similar problem, my advice to u is the followings:

  1. it's better to have a separate jest.config.js
  2. yarn add --dev babel-jest babel-core@^7.0.0-bridge.0 @babel/core regenerator-runtime (look at https://jestjs.io/docs/en/getting-started.html#using-babel )
  3. create a babel.config.js file, and put the following code inside.
  presets: [
    '@babel/preset-env',
    '@babel/preset-react',
  ],
  env: {
    test: {
      presets: [
        '@babel/preset-env',
        '@babel/preset-react',
      ],
      plugins: [
        '@babel/plugin-proposal-class-properties',
        'transform-es2015-modules-commonjs',
        'babel-plugin-dynamic-import-node',
      ],
    },
  },
};
  1. npm test again. make sure your package.json test:, is scripted correctly.
@jeffery021121

This comment has been minimized.

Copy link

commented Feb 19, 2019

in babelrc, if you set the env of presets as ['@babel/preset-env',{modules: false}], the import would not work. so let the modules of env not be false would solve this problem.

@komali2

This comment has been minimized.

Copy link

commented May 28, 2019

It appears jest also cannot parse babel configs that are in a package.json.

I had to take my package.json babel config:

"babel":  {
  "presets": [
    [
      "env",
      {
        "modules": false
      }
    ]
  ],
  "env": {
    "test": {
      "presets": [
        [
          "env",
          {
            "targets": {
              "node": "current"
            }
          }
        ]
      ]
    }
  }
}

and create a babel.config.js

module.exports = {
  "presets": [
    [
      "env",
      {
        "modules": false
      }
    ]
  ],
  "env": {
    "test": {
      "presets": [
        [
          "env",
          {
            "targets": {
              "node": "current"
            }
          }
        ]
      ]
    }
  }
}

@gselsidi

This comment has been minimized.

Copy link

commented Jun 4, 2019

I installed Jest without babel with following instructions: npm install --save-dev jest , I still get this error when trying to use import....

@kevinhaas

This comment has been minimized.

Copy link

commented Jun 4, 2019

SyntaxError: Unexpected token export

orly?

Went through all of these threads. My regex was fine, I had a babel.config.js and not a .babelrc or package.json entry, etc, etc, etc. I have had this project on babel 7 for a little while, but only got this error when adding a new library.

@sormy had the only response that worked. If I need to re-import the babel config like this, it would seem this is a jest issue. Removing that solution and following the docs results in an error. I understand what the config expects and how it plays with babel. This does not seem like the expected behavior.

@gselsidi

This comment has been minimized.

Copy link

commented Jun 4, 2019

@kevinhaas yeah think I'm just going to switch to Mocha then deal with these issues for now.

@kevinhaas

This comment has been minimized.

Copy link

commented Jun 14, 2019

I was mistaken. After clearing the cache, I realize you don't need the custom transform. All jest seems to want is the transformIgnorePatterns to be correct, and to have the babel.config.js in the ROOT directory. Seems like it needs to be updated to respect package.json babel config, as this is a valid location according to babel.

@Alendorff

This comment has been minimized.

Copy link

commented Jun 20, 2019

Renaming .babelrc to babel.config.js worked for me

For me too. I had fully working setup with babelrc, but then I migrated from babel-6 to 7 and update some packages. After that jest started to complain against lodash-es again despite I had transformIgnorePatterns already.

Why does rename work at all?

@SimenB

This comment has been minimized.

Copy link
Collaborator

commented Jun 20, 2019

Seems like it needs to be updated to respect package.json babel config, as this is a valid location according to babel.

We use @babel/core to load the config using https://babeljs.io/docs/en/babel-core#loadpartialconfig. If babel doesn't find your config, that's not an issue with jest.

Why does rename work at all?

Because that's how Babel works: https://babeljs.io/docs/en/configuration#what-s-your-use-case. You need babel.config.js to transpile from node_modules.

@clintonmedbery

This comment has been minimized.

Copy link

commented Jun 25, 2019

test: { plugins: ['@babel/plugin-transform-modules-commonjs', 'dynamic-import-node', 'require-context-hook'] }

in babel.config.js and
"test": "BABEL_ENV=test node ./node_modules/jest/bin/jest.js --config ./jest.json",

in package.json did it for me.

krassowski added a commit to krassowski/jupyterlab-go-to-definition that referenced this issue Jul 4, 2019
@hudidit

This comment has been minimized.

Copy link

commented Jul 14, 2019

Seems like it needs to be updated to respect package.json babel config, as this is a valid location according to babel.

We use @babel/core to load the config using https://babeljs.io/docs/en/babel-core#loadpartialconfig. If babel doesn't find your config, that's not an issue with jest.

Why does rename work at all?

Because that's how Babel works: https://babeljs.io/docs/en/configuration#what-s-your-use-case. You need babel.config.js to transpile from node_modules.

For those who had been struggling like me, listen to this man @SimenB here!

Before you try anything else, copy your babel config and jest config into separate babel.config.js and jest.config.js. This may save you from several hours, maybe days of googling, debugging and frustration.

I've been trying these ways:

  • Modify the versions of babel/jest/babel-jest
  • Modify the configs of babel/jest in package.json
  • Scratching my head to come up with another possible way

It turns out that none of the above is necessary.

Here is a glimpse of those key configuration files:

package.json

Pay attention that I'm using Babel@7 and jest@23. Babel@7 barely requires any configuration.

{
  "dependencies": {
    "@babel/core": "7.1.0",
    "babel-core": "7.0.0-bridge.0",
    "babel-jest": "23.6.0",
    "babel-preset-react-app": "^6.1.0",
    "jest": "23.6.0",
    "jest-pnp-resolver": "1.0.1",
    "jest-resolve": "23.6.0"
  },
  "browserslist": [
    ">0.2%",
    "not dead",
    "not ie <= 11",
    "not op_mini all"
  ],
  "devDependencies": {
    "@types/jest": "^23.3.10"
  }
}

babel.config.js

NOTHING fancy at all. Doesn't even have to explicitly set configs for test environment.

module.exports = {
  "presets": [
    "react-app"
  ]
};

jest.config.js

Most of the content is copied from "jest": {...} in package.json. This is a ejected create-react-app project(with TypeScript), so most of the configs below were generated automatically while "ejecting". I've add comments to the lines which need to be noticed.

module.exports = {
  "collectCoverageFrom": [
    "src/**/*.{js,jsx,ts,tsx}",
    "!src/**/*.d.ts"
  ],
  "resolver": "jest-pnp-resolver",
  "setupFiles": [
    "react-app-polyfill/jsdom"
  ],
  "testMatch": [
    "<rootDir>/src/**/__tests__/**/*.{js,jsx,ts,tsx}",
    "<rootDir>/src/**/?(*.)(spec|test).{js,jsx,ts,tsx}"
  ],
  "testEnvironment": "jsdom",
  "testURL": "http://localhost",
  "transform": {
    "^.+\\.(js|jsx|ts|tsx)$": "<rootDir>/node_modules/babel-jest",
    "^.+\\.(css|less)$": "<rootDir>/config/jest/cssTransform.js",
    "^(?!.*\\.(js|jsx|ts|tsx|css|json)$)": "<rootDir>/config/jest/fileTransform.js"
  },
  "transformIgnorePatterns": [
    "^.+\\.module\\.(css|sass|scss)$",
    "node_modules/(?!(reactjs-click-outside|@babel/runtime)/)", // The modules that need to be transpiled. You might not need this.
    // "[/\\\\]node_modules[/\\\\].+\\.(js|jsx|ts|tsx)$", // This line is no longer needed.
  ],
  "moduleNameMapper": {
    // "^react-native$": "react-native-web", // This was generated while "ejecting", not necessary.
    "^.+\\.module\\.(css|sass|scss)$": "identity-obj-proxy",
    "\\.(css|less)$": "identity-obj-proxy", // If you are importing css/less in JS files
  },
  "moduleDirectories": [
    "node_modules" // This is required
  ],
  "moduleFileExtensions": [
    "web.js",
    "js",
    "web.ts",
    "ts",
    "web.tsx",
    "tsx",
    "json",
    "web.jsx",
    "jsx",
    "node"
  ]
}

Hope this is helpful.

@buixuanhai

This comment has been minimized.

Copy link

commented Jul 23, 2019

For me, after using babel.config.js, installing babel-cli in devDependencies works.

@bryan-gilbert

This comment has been minimized.

Copy link

commented Jul 23, 2019

Solution found. I fought with this same issue for a couple of days.

    /projectRoot/client/tests/unit/example.spec.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import { shallowMount } from '@vue/test-utils';
                                                                                                  ^

    SyntaxError: Unexpected token {

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

I found the solution. When I updated the package.json babel-jest the project broke. Changing babel-jest back to an earlier version, removing node modules, install and the project REMAINS BROKEN.

To reproduce. Put "babel-jest": "^23.6.0", into your devDependencies. Verify unit tests work. Upgrade to "babel-jest": "^24.8.0", the unit tests will fail. Revert to 23.6.0 and remove all node_modules, npm install, run the unit tests and they continue to fail.

To fix

  1. rm -rf node_modules
  2. downgrade to babel-jest 23.6
  3. IMPORTANT rm package-lock.json
  4. run npm install

Without step 3 the tests will continue to fail with the same error.

@onyegood

This comment has been minimized.

Copy link

commented Sep 12, 2019

@master-7

This is how I solved that same problem.

Add to your dependencies list in your package.json file

"@babel/core": "^7.4.5",
"@babel/plugin-proposal-class-properties": "^7.4.4",
 "@babel/plugin-proposal-object-rest-spread": "^7.4.4",
"@babel/preset-env": "^7.4.5",
"@babel/preset-react": "^7.0.0",
 "babel-cli": "^6.26.0",
"enzyme": "^3.10.0",
"enzyme-adapter-react-16": "^1.14.0",
"enzyme-to-json": "^3.4.0"

Your .babelrc in your root directory should look like this

{
  "presets": [
    "@babel/env", 
    "@babel/react"
  ],    
  "plugins": [
    "@babel/plugin-proposal-class-properties", 
    "@babel/plugin-proposal-object-rest-spread"
  ]
}

Create jest.config.json file in you root directory and the content should look like this

{
    "setupFiles": [
        "raf/polyfill",
        "<rootDir>/test/setupTests.js"
    ],
    "snapshotSerializers": [
        "enzyme-to-json/serializer"
    ]
}

Create a folder in your root directory called test and add setupTests.js file into it (test/setupTests.js). The content should look like this

import Enzyme from "enzyme";

import Adapter from "enzyme-adapter-react-16";

Enzyme.configure({ adapter: new Adapter() });

In package.json, in the script object let you test look like this

"test": "jest --config=jest.config.json --watch"

Delete your node_module folder and reinstall it again
npm install Or yarn install

Then do yarn test to run your test

I hope this help

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
You can鈥檛 perform that action at this time.