When using Jest with a class that has private fields (introduced in Node.js 12), the tests fail with a syntax error – “unexpected character '#'”
Prerequisites
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.
No error, Jest should support private class fields with the # syntax, since they can be used in Node.js 12 without flags or transpilers.
See steps to reproduce above:
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
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: {}.
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-devand then add a config file
babel.config.jswith the following content: