React class component babel error: "Missing class properties transform"

See original GitHub issue

I’ve jumped into using Nx today and so far I love it and intend to keep using it! Just came across the following problem and it looks like it could be an issue with how Nx sets up React apps?

Expected Behavior

Can use class properties/arrow functions in React components

Current Behavior

Defining anything in a React component class (extends React.Component) fails with:

ERROR in ./app/app.tsx
Module build failed (from /d/path/node_modules/babel-loader/lib/index.js):
SyntaxError: /d/path/apps/appname/src/app/app.tsx: Missing class properties transform.

Failure Information

Looks like the same as this issue: babel/babel#2729

This comment explains that it’s something to do with the order of the babel presets: https://github.com/babel/babel/issues/2729#issuecomment-245401360

Steps to Reproduce

npx create-nx-workspace@latest repro-thing --preset=react

Use the following apps/repro-thing/src/app/app.tsx (a simple counter app):

import React from 'react';
import './app.scss';

type Props = {};

type State = {
  count: number;
};

export class App extends React.Component<Props, State> {
  constructor(props) {
    super(props);
    this.state = { count: 1 };
  }

  updateCount = (amount: number) => {
    this.setState({ count: this.state.count + amount });
  };

  render() {
    return (
      <div className="app">
        <h1>counter</h1>

        <div>
          <button onClick={() => this.updateCount(-1)}>-</button>

          {this.state.count}

          <button onClick={() => this.updateCount(1)}>+</button>
        </div>
      </div>
    );
  }
}

export default App;

Run npm start and wait for “Failed to compile.

I’ve tried the same code in a React app generated with npx create-react-app thing --typescript and this example works as expected.

Context

Dependencies/Versions

  "dependencies": {
    "document-register-element": "1.13.1",
    "react": "16.9.0",
    "react-dom": "16.9.0",
    "@nestjs/common": "^6.2.4",
    "@nestjs/core": "^6.2.4",
    "@nestjs/platform-express": "^6.2.4",
    "reflect-metadata": "^0.1.12"
  },
  "devDependencies": {
    "@babel/core": "7.5.5",
    "@babel/plugin-proposal-decorators": "7.4.4",
    "@babel/preset-env": "7.5.5",
    "@babel/preset-react": "7.0.0",
    "@babel/preset-typescript": "7.3.3",
    "@nestjs/schematics": "^6.3.0",
    "@nestjs/testing": "^6.2.4",
    "@nrwl/cypress": "8.4.13",
    "@nrwl/eslint-plugin-nx": "8.4.13",
    "@nrwl/jest": "8.4.13",
    "@nrwl/nest": "^8.4.13",
    "@nrwl/node": "8.4.13",
    "@nrwl/react": "8.4.13",
    "@nrwl/web": "8.4.13",
    "@nrwl/workspace": "8.4.13",
    "@testing-library/react": "8.0.5",
    "@types/jest": "24.0.9",
    "@types/node": "~8.9.4",
    "@types/react": "16.9.1",
    "@types/react-dom": "16.8.5",
    "@typescript-eslint/eslint-plugin": "2.0.0-alpha.4",
    "@typescript-eslint/parser": "2.0.0-alpha.4",
    "babel-loader": "8.0.6",
    "babel-plugin-macros": "2.6.1",
    "concurrently": "^4.1.2",
    "core-js": "3.1.4",
    "cypress": "3.4.1",
    "dotenv": "6.2.0",
    "eslint": "6.1.0",
    "eslint-config-prettier": "6.0.0",
    "eslint-plugin-import": "2.18.2",
    "eslint-plugin-jsx-a11y": "6.2.3",
    "eslint-plugin-react": "7.14.3",
    "eslint-plugin-react-hooks": "1.6.1",
    "jest": "24.1.0",
    "prettier": "1.16.4",
    "regenerator-runtime": "0.13.3",
    "ts-jest": "24.0.0",
    "ts-node": "~7.0.0",
    "tslint": "~5.11.0",
    "typescript": "~3.4.5"
  }

Failure Logs

logs

Other

Changing the function to a normal class function and then binding this function to the scope rather than defining an arrow function works, e.g.:

  constructor(props) {
    super(props);
    this.state = { count: 1 };

    this.updateCount = this.updateCount.bind(this);
  }

  updateCount(amount: number) {
    this.setState({ count: this.state.count + amount });
  };

but this means you have to bind every method, which I’d rather avoid.

This error also occurs for other value types, e.g. numbers:

export class App extends React.Component<Props, State> {
  thing = 1
  
  constructor(props) {
    ...

Gives the following command-line error:

[ui] ERROR in ./app/app.tsx
[ui] Module build failed (from /d/path/node_modules/babel-loader/lib/index.js):
[ui] SyntaxError: /d/path/apps/appname/src/app/app.tsx: Missing class properties transform.
[ui]   10 |
[ui]   11 | export class App extends React.Component<Props, State> {
[ui] > 12 |   thing = 1
[ui]      |   ^
[ui]   13 | 
[ui]   14 |   constructor(props) {
[ui]   15 |     super(props);

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:5
  • Comments:14 (4 by maintainers)

github_iconTop GitHub Comments

5reactions
jhlabscommented, Apr 24, 2020

@jaysoo I am using NX with NextJS and several react libraries that are run with Storybook. The exact same error as mentioned above appears when I run Storybook, but not for NextJS. Could it be that the fix did not apply to Storybook installs? I tried to fix it with the hotfix above and custom .babelrc configurations, but could not get it to work. Thanks for your help!

3reactions
maxim-khacommented, Aug 4, 2020

@kimon89, @jhlabs Guys try something like this webpack.config.js

const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
const rootWebpackConfig = require('../../../.storybook/webpack.config');
// Export a function. Accept the base config as the only param.
module.exports = async ({ config, mode }) => {
    config = await rootWebpackConfig({ config, mode });

    const tsPaths = new TsconfigPathsPlugin({
        configFile: './tsconfig.json',
       });
    
      config.resolve.plugins
        ? config.resolve.plugins.push(tsPaths)
        : (config.resolve.plugins = [tsPaths]);
      
    config.resolve.extensions.push('.tsx');
    config.resolve.extensions.push('.ts');
    config.module.rules.push({
        test: /\.(ts|tsx)$/,
        loader: require.resolve('babel-loader'),
        options: {
            presets: [
                '@babel/preset-env',
                '@babel/preset-react',
                '@babel/preset-typescript',                                           
            ],
            "plugins": [
                ["@babel/plugin-proposal-decorators", { "legacy": true }],
                ["@babel/plugin-proposal-class-properties", { "loose" : true }]
              ],          
        },
       
    });
    // This is needed for "@storybook/addon-storysource.
    // Without this story source code won't show in storybook.
    config.module.rules.push({
        test: /\.stories\.(ts|tsx)?$/,        
        loaders: [
            require.resolve('@storybook/source-loader'),            
          ],
        enforce: 'pre',
    });

    return config;
};

adding

   "plugins": [
                ["@babel/plugin-proposal-decorators", { "legacy": true }],
                ["@babel/plugin-proposal-class-properties", { "loose" : true }]
              ], 

solve problem for me.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Error: Missing class properties transform - Stack Overflow
The fix in my case was defining 'transform-class-properties' plugin in the options attribute of my webpack.config.js, i'm using babel V6
Read more >
Low-Tech Fix for "Missing class properties transform" Errors?
A lot of coders are encountering “Missing class properties transform” errors, as some ES7 syntax is not yet supported by Babel. E.g.:
Read more >
babel/plugin-proposal-class-properties
Example. Below is a class with four class properties which will be transformed. class Bork { //Property initializer syntax instanceProperty = "bork"; ...
Read more >
robot - Netlify Support Forums
Build ERROR opt/build/repo/.cache/loader.js: Missing class properties ... @babel/plugin-proposal-class-properties but nothing works.
Read more >
storybook missing class properties transform. - You.com
I am getting "Missing class properties transform" error message. Changing .babelrc of that project (lib) to: json { "presets": ["@nrwl/react/babel"], ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found