Jest: Jest does not support private class fields

Created on 8 Oct 2019  ·  9Comments  ·  Source: facebook/jest

8497 🐛 Bug Report

When using Jest with a class that has private fields (introduced in Node.js 12), the tests fail with a syntax error – “unexpected character '#'”

To Reproduce

Prerequisites

  • Node.js version at least 12.0.0 is installed
  • Yarn is installed

Steps to reproduce the behavior

Clone this repository: https://github.com/technology-ebay-de/zapperment

git clone [email protected]:technology-ebay-de/zapperment.git
cd zapperment

Checkout branch jest-issue:

git checkout jest-issue

Install npm dependencies:

yarn

Change directory to workspace backend:

cd packages/backend

Run tests:

yarn test

The console shows the following error:

 FAIL  src/model/SceneBuilder.test.js
  ● Test suite failed to run

    SyntaxError: /Users/pahund/git/zapperment/packages/backend/src/model/SceneBuilder.js: Unexpected character '#' (7:2)

       5 |
       6 | module.exports = class {
    >  7 |   #foo = 'foo';
         |   ^
       8 |
       9 |   constructor({ storage }) {
      10 |     this.storage = storage;

      at Parser.raise (../../node_modules/@babel/parser/lib/index.js:6400:17)
      at Parser.readToken_numberSign (../../node_modules/@babel/parser/lib/index.js:6729:12)
      at Parser.getTokenFromCode (../../node_modules/@babel/parser/lib/index.js:7073:14)
      at Parser.nextToken (../../node_modules/@babel/parser/lib/index.js:6600:12)
      at Parser.next (../../node_modules/@babel/parser/lib/index.js:6540:10)
      at Parser.eat (../../node_modules/@babel/parser/lib/index.js:6545:12)
      at Parser.expect (../../node_modules/@babel/parser/lib/index.js:7714:10)
      at Parser.parseClassBody (../../node_modules/@babel/parser/lib/index.js:10702:10)
      at Parser.parseClass (../../node_modules/@babel/parser/lib/index.js:10677:22)
      at Parser.parseExprAtom (../../node_modules/@babel/parser/lib/index.js:8897:21)

  console.log jest.setup.js:3
    Jest is using Node version 12.11.0

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        0.651s
Ran all test suites.

If you delete line 7 in the module SceneBuilder.js, the tests run without error.

Expected behavior

No error, Jest should support private class fields with the # syntax, since they can be used in Node.js 12 without flags or transpilers.

Link to repl or repo

See steps to reproduce above:

envinfo

  System:
    OS: macOS Mojave 10.14.6
    CPU: (8) x64 Intel(R) Core(TM) i7-6920HQ CPU @ 2.90GHz
  Binaries:
    Node: 12.11.0 - ~/.nvm/versions/node/v12.11.0/bin/node
    Yarn: 1.19.0 - /usr/local/bin/yarn
    npm: 6.11.3 - ~/.nvm/versions/node/v12.11.0/bin/npm
Bug Report Needs Repro Needs Triage

Most helpful comment

The problem (and therefore the solution) is the babel configuration in jest.
The fix is to add a babel configuration file with the correct presets and plugins.
First install the correct packages:
npm i @babel/preset-env @babel/plugin-proposal-class-properties --save-dev

and then add a config file babel.config.js with the following content:

module.exports = {
  presets: [
    [
      '@babel/preset-env',
      {
        targets: {
          node: true,
        },
      },
    ],
  ],
  plugins: [
    '@babel/plugin-proposal-class-properties',
  ]
};

All 9 comments

I've found a workaround for this.

In my Jest config, I'm disabling Babel transpilation completely using transformIgnorePatterns:

module.exports = {
  testEnvironment: "node",
  transformIgnorePatterns: ['.*']
};

The workaround doesn't seem to work with the coverage flag

The problem (and therefore the solution) is the babel configuration in jest.
The fix is to add a babel configuration file with the correct presets and plugins.
First install the correct packages:
npm i @babel/preset-env @babel/plugin-proposal-class-properties --save-dev

and then add a config file babel.config.js with the following content:

module.exports = {
  presets: [
    [
      '@babel/preset-env',
      {
        targets: {
          node: true,
        },
      },
    ],
  ],
  plugins: [
    '@babel/plugin-proposal-class-properties',
  ]
};

Yup, either disable babel completely by specifying transform: {} in your jest configuration, or configure babel to have the plugin.

It's unfortunate https://github.com/babel/babel/issues/7660 never went anywhere

@SimenB I think that PR went somewhere with v25.3.0

Yeah, this has been fixed since my comment

I can see it works but I can't still test them in my suites. How do you deal with #method is not defined?

That's a question for StackOverflow, not this issue tracker

Yup, either disable babel completely by specifying transform: {} in your jest configuration, or configure babel to have the plugin.

Also there is an important point for jest runs with --coverage flag. By default jest uses babel to collect code coverage, so don't forget to set coverageProvider: "v8"(docs) in your jest config if you choose the way with transform: {}.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

calebmer picture calebmer  ·  72Comments

iffy picture iffy  ·  137Comments

eldh picture eldh  ·  84Comments

paularmstrong picture paularmstrong  ·  66Comments

pfftdammitchris picture pfftdammitchris  ·  76Comments