title: Node+React+Babel+Webpack, Unexpected token error
body: <p>First of all, I REALLY tried to fix it myself, I found several similar questions here, but none helped me.</p>
  
  <p>Getting this error:</p>
  
  <pre><code>ERROR in ./src/components/App.jsx
  Module parse failed: D:\JS projects\habr-app\src\components\App.jsx Unexpected token (54:6)
  You may need an appropriate loader to handle this file type.
  |   render() {
  |     return (
  |       &lt;div className='App'&gt;
  |         &lt;h1&gt;Hello World!&lt;/h1&gt;
  |         &lt;div&gt;
   @ ./src/client.js 3:0-42
   @ multi (webpack)-dev-server/client?http://0.0.0.0:8050 webpack/hot/dev-server babel-polyfill ./src/client.js
  </code></pre>
  
  <p>client.js file:</p>
  
  <pre><code>import React      from 'react';
  import ReactDOM   from 'react-dom';
  import App        from './components/App';
  
  ReactDOM.render ("&lt;App /&gt;", document.getElementById('react-view'));
  </code></pre>
  
  <p>render function in App.jsx looks like this:</p>
  
  <pre><code>render() {
      return (
        &lt;div className='App'&gt;
          &lt;h1&gt;Hello World!&lt;/h1&gt;
          &lt;div&gt;
            &lt;p&gt;Введите Ваше имя:&lt;/p&gt;
            &lt;div&gt;&lt;input onChange={this.handleNameChange} /&gt;&lt;/div&gt;
            {this.renderGreetingWidget()}
          &lt;/div&gt;
        &lt;/div&gt;
      );
    }
  </code></pre>
  
  <p>webpack.config.js file:</p>
  
  <pre><code>global.Promise         = require('bluebird');
  
  var webpack            = require('webpack');
  var path               = require('path');
  var ExtractTextPlugin  = require('extract-text-webpack-plugin');
  var CleanWebpackPlugin = require('clean-webpack-plugin');
  
  var publicPath         = 'http://localhost:8050/public/assets';
  var cssName            = process.env.NODE_ENV === 'production' ? 'styles-[hash].css' : 'styles.css';
  var jsName             = process.env.NODE_ENV === 'production' ? 'bundle-[hash].js' : 'bundle.js';
  
  var plugins = [
    new webpack.DefinePlugin({
      'process.env': {
        BROWSER:  JSON.stringify(true),
        NODE_ENV: JSON.stringify(process.env.NODE_ENV || 'development')
      }
    }),
    new ExtractTextPlugin(cssName)
  ];
  
  if (process.env.NODE_ENV === 'production') {
    plugins.push(
      new CleanWebpackPlugin([ 'public/assets/' ], {
        root: __dirname,
        verbose: true,
        dry: false
      })
    );
    plugins.push(new webpack.optimize.DedupePlugin());
    plugins.push(new webpack.optimize.OccurenceOrderPlugin());
  }
  
  module.exports = {
    entry: ['babel-polyfill', './src/client.js'],
    resolve: {
      extensions:         ['.js', '.jsx']
    },
    plugins: [
       new ExtractTextPlugin("styles.css"),
       new webpack.LoaderOptionsPlugin({
         debug: true,
         options: {
           eslint: { configFile: '.eslintrc' }
         }
       })
    ],
    output: {
      path: `${__dirname}/public/assets/`,
      filename: jsName,
      publicPath
    },
    module: {
      rules: [
        {
          test: /\.css$/,
          use: ExtractTextPlugin.extract({
            fallback: "style-loader",
            use: "css-loader"
          })
        }
      ],
      loaders: [
        {
          test: /\.css$/,
          loader: ExtractTextPlugin.extract({fallback: 'style-loader', use: 'css-loader!postcss-loader'})
        },
        {
          test: /\.less$/,
          loader: ExtractTextPlugin.extract({fallback: 'style-loader', use: 'css-loader!postcss-loader!less-loader'})
        },
        { test: /\.gif$/, loader: 'url-loader?limit=10000&amp;mimetype=image/gif' },
        { test: /\.jpg$/, loader: 'url-loader?limit=10000&amp;mimetype=image/jpg' },
        { test: /\.png$/, loader: 'url-loader?limit=10000&amp;mimetype=image/png' },
        { test: /\.svg/, loader: 'url-loader?limit=26000&amp;mimetype=image/svg+xml' },
        { test: /\.(woff|woff2|ttf|eot)/, loader: 'url-loader?limit=1' },
        { test: /\.jsx?$/, loaders: ['react-hot-loader', 'babel-loader?presets[]=react,presets[]=es2015'],
                            exclude: [/node_modules/, /public/] , query: {presets: ['es2015', 'react', 'react-hot']} },
        { test: /\.json$/, loader: 'json-loader' },
      ]
    },
    devtool: process.env.NODE_ENV !== 'production' ? 'source-map' : null,
    devServer: {
      headers: { 'Access-Control-Allow-Origin': '*' }
    }
  };
  </code></pre>
  
  <p>The only way I can fix this problem - is to put quotes around html in render:</p>
  
  <pre><code>render() {
      return (
        `&lt;div className='App'&gt;
          &lt;h1&gt;Hello World!&lt;/h1&gt;
          &lt;div&gt;
            &lt;p&gt;Введите Ваше имя:&lt;/p&gt;
            &lt;div&gt;&lt;input onChange={this.handleNameChange} /&gt;&lt;/div&gt;
            {this.renderGreetingWidget()}
          &lt;/div&gt;
        &lt;/div&gt;`
      );
    }
  </code></pre>
  
  <p>But after that I'm gettin this error in browser and nodemon:</p>
  
  <pre><code>Invariant Violation: App.render(): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object.
  </code></pre>
  
  <p>I checked and rechecked all dependencies, modules and my files.
  Still, I cant find an error. Could someone help me, please?</p>
  
  <p>P.S. Sorry for my awful English.</p>
  
  <p>Funny thing. When I start nodemon without those quotes in App.jsx, my page loads, but without css. After that I add quotes <code></code> in file App.jsx and now webpack-devserver builds everything right, and page gets .css after refresh. JS-script still doesnt work on it, but looks almost like it should... Right until I restart nodemon... It starts to show same error "Invariant Violation: App.render(): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object."</p>