1

friends! I have trouble with webpack build. In webpack I use babel 6^ + this presets:

presets: ['es2015', 'stage-1', 'react']

After npm start I catch error:

ERROR in ./src/common/components/layout/Header.js
Module build failed: SyntaxError: C:/Users/Anton/projects/isomorphic-redux-app/src/common/components/layout/Header.js: Unexpected token (13:15)
  11 |   }
  12 |
  13 |   handleToggle = () => this.setState({open: !this.state.open});
     |                ^
  14 |
  15 |   render() {
  16 |     return (

At first I thought that I have error in code, and I just copy/paste it from Material-UI docs, but it's broken too. Header.js file:

import React, { Component, PropTypes } from 'react';
import LeftNav from 'material-ui/lib/left-nav';
import AppBar from 'material-ui/lib/app-bar';
import RaisedButton from 'material-ui/lib/raised-button';

export default class Header extends Component {

  constructor(props) {
    super(props);
    this.state = {open: false};
  }

  handleToggle = () => this.setState({open: !this.state.open});

  render() {
    return (
      <div>
        <RaisedButton
          label="Controlled LeftNav That Opens From Right"
          onTouchTap={this.handleToggle} />
        <LeftNav width={200} openRight={true} open={this.state.open} >
          <AppBar title="AppBar"/>
        </LeftNav>
      </div>
    );
  }
}

And webpack.config:

var path = require('path');
var webpack = require('webpack');
var merge = require('merge');
var ExtractTextPlugin = require('extract-text-webpack-plugin');


var webpackConfig = {
  output: {
    path: path.join(__dirname, 'dist'),
    filename: 'bundle.js',
    publicPath: '/static/'
  },
  plugins: [
    new webpack.optimize.OccurenceOrderPlugin(),
    new webpack.NoErrorsPlugin()
  ]
};

if (process.env.NODE_ENV === 'production') {

  webpackConfig = merge(webpackConfig,{
    devtool: "source-map",
    entry : [
      './src/client/index.js'
    ],
    resolve: {
      extensions: ["", ".js", ".jsx"]
    },
    module: {
    loaders: [{
    test: /\.js$/,
    loader: 'babel',
    exclude: /node_modules/,
    include: __dirname,
    query: {
      presets: ['es2015', 'stage-1', 'react'],

    }
      },
      { 
        test: /\.jsx$/, 
        loader: 'babel', 
        exclude: /node_modules/,
        include: __dirname,
        query: {
          presets: ['es2015', 'stage-1', 'react'],

        }
      },
      { test: /\.(png|jpg|gif|jpeg)$/, loader: 'url-loader?limit=8192'},
      { test: /\.css$/, loader: ExtractTextPlugin.extract('style-loader', 'css-loader?sourceMap') }
    ]},
    plugins : [
      new webpack.DefinePlugin({
       'process.env': {
          NODE_ENV: JSON.stringify('production')
        }
      }),
      new ExtractTextPlugin("app.css"),
      new webpack.optimize.UglifyJsPlugin({minimize: true})
    ]  
  });

}else{

  webpackConfig = merge(webpackConfig,{
    devtool: 'inline-source-map',
    module: {
      loaders: [{
    test: /\.js$/,
    loader: 'babel',
    exclude: /node_modules/,
    include: __dirname,
      env: {
        development: {
          plugins: [
            'react-transform'
          ],
          extra: {
            'react-transform': {
              transforms: [{
                transform:  'react-transform-hmr',
                imports: ['react'],
                locals:  ['module']
              },
              {
                transform: 'react-transform-catch-errors',
                imports: ['react','redbox-react' ]
              }
            ]}
          }
        }
      },//
        query: {
//          optional: ['runtime'],
      presets: ['es2015', 'stage-1', 'react'],

    }
  },
  { 
    test: /\.jsx$/, 
    loader: 'babel', 
    exclude: /node_modules/,
    include: __dirname,
    env: {
        development: {
          plugins: [
            'react-transform'
          ],
          extra: {
            'react-transform': {
              transforms: [{
                transform:  'react-transform-hmr',
                imports: ['react'],
                locals:  ['module']
              },
              {
                transform: 'react-transform-catch-errors',
                imports: ['react','redbox-react' ]
              }
            ]}
          }
        }
      },
    query: {
      presets: ['es2015', 'stage-1', 'react'],

    }
  },
  { test: /\.(png|jpg|gif|jpeg)$/, loader: 'url-loader?limit=8192'},
  { test: /\.css$/, loader: ExtractTextPlugin.extract('style-loader', 'css-loader?sourceMap') }
]},
entry : [
  'webpack-hot-middleware/client',
  './src/client/index.js',
],
resolve: {
  extensions: ["", ".js", ".jsx"]
},
plugins : [
  new webpack.HotModuleReplacementPlugin(),
  new ExtractTextPlugin("app.css")
    ]  
  });

}

module.exports = webpackConfig;

How I can resolve it?

1
  • What does your Webpack config look like? Commented Jan 20, 2016 at 10:00

4 Answers 4

2

You don't need the arrow function (and it is invalid syntax) here because you are defining a class method:

handleToggle = () => this.setState({open: !this.state.open});

Try this instead:

handleToggle() { this.setState({open: !this.state.open}); } 

However, because class methods don't automatically bind, you need to bind it in the constructor or when you use it:

constructor(props) {
    super(props);
    this.state = {open: false};
    this.handleToggle = this.handleToggle.bind(this);
  }

If you were inside the render or another class method, you would need to add const or equivalent to the front (when using assignment with =):

render() {
    const handleToggle = () => this.setState({open: !this.state.open});
}
Sign up to request clarification or add additional context in comments.

Comments

1

If you want to use arrow functions on a class and avoid binding to the constructor (this bit):

this.handleToggle = this.handleToggle.bind(this);

Then you can use babel's transform class properties. To do this, download the module in your command line:

npm i --save babel-plugin-transform-class-properties

Then in your .babelrc:

{
  "plugins": ["transform-class-properties"]
}

Then you can use the cleaner syntax and remove binding in the constructor:

handleToggle = () => this.setState({open: !this.state.open});

This is supposed to be in the stage-0 or stage-1 preset, but I've only ever managed to make it work by referencing the plugin explicitly (as above).

Comments

0

If I am correct, you are trying to use property initializer which is an ES7 feature. To fix this, you will have to use stage-1 preset.

More information here

Comments

0

You need to use Babel stage 1 to get class properties.

http://babeljs.io/docs/plugins/preset-stage-1/

step 1: add dependency as follows:

npm install babel-preset-stage-1 --save

step 2: change .babelrc file as follows:

{
  "presets": ["es2015", "react","stage-1"]
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.