Jest: Jest doesn't play nice with Node 8.3.0's object rest/spread properties.

Created on 11 Aug 2017  路  21Comments  路  Source: facebook/jest

Do you want to request a feature or report a bug?

I'm reporting a bug regarding Node 8.3.0's object rest/spread properties.

What is the current behavior?

I had just updated to Node 8.3.0 and started using the object spread syntax in my code and it runs fine. However, when I test that same code, Jest errors out when it sees that type of syntax. I created a test demo repo to demonstrate: https://github.com/icylace/jest-vs-node-8.3.0

What is the expected behavior?

Jest should not complain about syntax that Node 8.3.0 can handle.

Please provide your exact Jest configuration and mention your Jest, node, yarn/npm version and operating system.

  • Jest 20.0.4
  • Node 8.3.0
  • Yarn 0.27.5
  • macOS Sierra 10.12.6
Bug Confirmed

Most helpful comment

@ksmithut you can always use whatever Node version you need and a babel transform just for the test, until this is resolved.

If you don't use Babel, It's as easy as running yarn add babel-plugin-transform-object-rest-spread --dev and adding .babelrc to your root and:

{
  "env": {
    "test": {
      "plugins": ["transform-object-rest-spread"]
    }
  }
}

All 21 comments

@icylace

Do you know of a way to get back to a working jest? I don't have a version of [email protected] still because I ran brew cleanup before I ran into this issue :confounded:. I tried removing node & reinstalling thinking it would install the _LTS_, but it gave me [email protected] which still leaves jest hanging. I've been looking at homebrew for how to get a specific version of node but it looks like my options are node@6 & node@4 (not sure about the other options printed out when running brew search node).

@rockchalkwushock

I love Homebrew but would never use it directly for switching between Node versions. For that I use Node Version Manager.

For getting back Node 8.2.1, try running these commands in your terminal:

brew install nvm
nvm install 8.2.1
nvm use 8.2.1

@icylace thanks so much man!

It concerns me that the version/features of node running my tests is not the version running in my production environment. I get the use case for mocking things for a browser environment, but for a node environment, I don't see why jest can't just use the existing runtime. That's likely ignorance on my part for not understanding the complexities of how jest is doing it's thing. I've also tried setting "testEnvironment": "node" in my jest config to no avail.

@ksmithut you can always use whatever Node version you need and a babel transform just for the test, until this is resolved.

If you don't use Babel, It's as easy as running yarn add babel-plugin-transform-object-rest-spread --dev and adding .babelrc to your root and:

{
  "env": {
    "test": {
      "plugins": ["transform-object-rest-spread"]
    }
  }
}

@thymikee Thanks :) I think I'll just avoid using object spread in my code for now. It's as easy as using Object.assign(). Not the prettiest, but I'd like to avoid any semblance of using babel, even if Jest is using it on my code.

Edit: To be clear, I like babel and what it does, but I'm literally using object spread in one place. Not worth a new dependency and a new file to fix. In face, I think I'm using object spread because of a bug in another library... Sometimes I think I need to rethink my life choices, lol

Just bumped into this as well, and since using 8.4.0 removes the need to use babel on my node server (finally we have rest/spread operators!), I'm only adding a .babelrc file for jest.
I'm curious to understand why this happens, though. Does jest rely on a different version of node internally?

@p4bloch I don't think it uses a different version of node. I think it runs the code through the babel transpiler, and the babel transpiler doesn't understand the rest/spread syntax without a plugin. This is more of bug with babel.

This plugin did the trick for me. It doesn't try to transpile the object spread to anything, simply makes babel aware of the syntax and doesn't touch it (since node already understands it).

yarn add --dev babel-plugin-syntax-object-rest-spread
{
  "plugins": ["syntax-object-rest-spread"]
}

The problem is not hte jest is running hte code in some different Node, but that its running babel over the source code, and BABEL doesn't understand object rest/spread syntax, and throwing a parser error, unless you add the syntax plugin as @potz notes

I see, thanks for the clarification. Is there a way to tell jest not to use Babel at all? That option would solve this in a very flexible way.

It is, you can pass custom transformer doing nothing. However you'll loose the benefit of jest.mock() hoisting your code above ES modules.
I think we could include this syntax-object-rest-spread plugin in babel-jest, what do you think @cpojer?

Also facing this in node 8.5. Object rest/spread operators are now supported natively, even without the --harmony flag. Inspired by these awesome news, I switched a few Object.assign(...) cases to {a, b, c, ...rest} and enjoyed the node scripts working. However, jest failed to run all the new code, e.g.:

const { a, ...rest } = { a: 10, b: 20 };
console.log(a, rest);

When something like this is a part of a test, that test fails; otherwise, coverage reports generate with errors.

What's the mechanism behind this behaviour? How can jest not understand the syntax that my node runtime does? Any suggestions on how to pass the tests just by tweaking jest.config.js?

What's the mechanism behind this behaviour? How can jest not understand the syntax that my node runtime does?

Just read the comments in this issue. In particular https://github.com/facebook/jest/issues/4248#issuecomment-329472472

Any suggestions on how to pass the tests without introducing babel to the project?

Jest includes babel, so you just need to add the .babelrc with a single plugin.

Would be interesting to know how much is babel baked into jest core. Could we add an option to make it bypass it and use node directly? Or there are core features that depend on babel?

Mocking dependencies requires hoisting requires which depends on babel

Thanks for your comment @SimenB. I was able to overcome the issue by creating the .babelrc file with the content that @potz suggests. This is quite confusing though: a project that uses node runtime without babel does need babel to run tests in the same (?) runtime.

The situation is counter-intuitive, so it'd be great to be able to remove .babelrc file from the project and still use jest (at least in future). Unfortunately, I'm struggling to understand what makes object rest/spread operators special given that they are native in node 8.5.

Thanks @SimenB for pushing that PR. That will allow us to remove the .babelrc file and avoid confusions in babel free projects.

@kachkaev is not that they are special, is just that they are not understood by Babel. Jest complains before even sending the code to node runtime, because it thinks that's a syntax error. Poor node runtime doesn't even have a chance to run the code, even though it understands the object spread natively.

The conversation goes like:
Node: - "hey Babel, you can send me this code, I can run this thing"
Babel: - "uh... no, this is like, syntax error. Never seen this spread thing before.. not sending it"
Node: - "damn, Babel! I said I could run it"

Then we add the plugin to the .babelrc file, and now Babel can now know that Node could run this thing all along in the first place, and simply ignore the syntax passing it along. Everybody's happy.

As for the object spread syntax not being included by default on Babel presets, that probably has to do with not being an 100% accepted proposal yet or something (this always confuses me as well).

@SimenB 's PR will make things less confusing from now on.

my babel config is set to target the current node version if in test environment. this makes jest test work fine but with --coverage it fails

Turned out to be a babel version mismatch. I had 7.1 of parser installed somewhere. Getting the latest of 7.3 made it work.

Was this page helpful?
0 / 5 - 0 ratings