Reputation: 13
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?
Upvotes: 1
Views: 4662
Reputation:
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"]
}
Upvotes: 0
Reputation: 23
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).
Upvotes: 1
Reputation: 67296
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});
}
Upvotes: 2
Reputation: 2977
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
Upvotes: 0