title: Can't get Webpack 2 HMR React to work
body: <p>Currently I'm struggling to get HMR working in my Webpack 2 setup. I'll explain my entire setup so I hope this is enough for someone to understand what's happening.</p>
  
  <p>The structure of my project:</p>
  
  <pre><code>config
    dev.js
    prod.js 
  dist
    css
    js
    index.html
  node_modules
  src
    components
      // some JavaScript components
    shared
    stylesheets
    index.js
  .babelrc
  package.json
  webpack.config.js
  </code></pre>
  
  <p>This are the contents of my <code>webpack.config.js</code> file, placed in the root of my project:</p>
  
  <pre><code>function buildConfig(env) {
    return require('./config/' + env + '.js')(env)
  }
  
  module.exports = buildConfig;
  </code></pre>
  
  <p>So in this file I've the option to pass different environments to the <code>buildConfig</code> function. I use this options to use different config files for development and production. This are the contents in my <code>package.json</code> file: </p>
  
  <pre><code>{
    "main": "index.js",
    "scripts": {
      "build:dev": "node_modules/.bin/webpack-dev-server --env=dev",
      "build:prod": "node_modules/.bin/webpack -p --env=prod"
    },
    },
    "devDependencies": {
      "autoprefixer-loader": "^3.2.0",
      "babel-cli": "^6.18.0",
      "babel-core": "^6.24.1",
      "babel-loader": "^6.2.5",
      "babel-preset-latest": "^6.16.0",
      "babel-preset-react": "^6.16.0",
      "babel-preset-stage-0": "^6.16.0",
      "css-loader": "^0.25.0",
      "extract-text-webpack-plugin": "^2.1.0",
      "json-loader": "^0.5.4",
      "node-sass": "^3.13.1",
      "postcss-loader": "^1.3.3",
      "postcss-scss": "^0.4.1",
      "sass-loader": "^4.1.1",
      "style-loader": "^0.13.1",
      "webpack": "^2.4.1",
      "webpack-dev-server": "^2.4.2"
    },
    "dependencies": {
      "babel-plugin-react-css-modules": "^2.6.0",
      "react": "^15.3.2",
      "react-dom": "^15.3.2",
      "react-hot-loader": "^3.0.0-beta.6",
      "react-icons": "^2.2.1"
    }
  }
  </code></pre>
  
  <p>I've of course more fields in my <code>package.json</code> but I won't shown them here since they're irrelevant. </p>
  
  <p>So during development I run the <code>npm run build:dev</code> command in my terminal. This will use the file <code>dev.js</code> from the <code>config</code> folder. This are the contents of the <code>dev.js</code> file:</p>
  
  <pre><code>const webpack = require('webpack');
  const { resolve } = require('path');
  const context = resolve(__dirname, './../src');
  
  module.exports = function(env) {
    return {
      context,
      entry: {
        app: [
          'react-hot-loader/patch',
          // activate HMR for React
          'webpack-dev-server/client?http://localhost:3000',
          // bundle the client for webpack-dev-server
          // and connect to the provided endpoint
          'webpack/hot/only-dev-server',
          // bundle the client for hot reloading
          // only- means to only hot reload for successful updates
          './index.js'
          // the entry point of our app
        ]
      },
      output: {
        path: resolve(__dirname, './../dist'), // `dist` is the destination
        filename: '[name].js',
        publicPath: '/js'
      },
      devServer: {
        hot: true, // enable HMR on the server
        inline: true,
        contentBase: resolve(__dirname, './../dist'), // `__dirname` is root of the project
        publicPath: '/js',
        port: 3000
      },
      devtool: 'inline-source-map',
      module: {
        rules: [
          {
            test: /\.js$/, // Check for all js files
            exclude: /node_modules/,
            use: [{
              loader: 'babel-loader',
              query: {
                presets: ['latest', 'react'],
                plugins: [
                  [
                    "react-css-modules",
                    {
                      context: __dirname + '/../src', // `__dirname` is root of project and `src` is source
                      "generateScopedName": "[name]__[local]___[hash:base64]",
                      "filetypes": {
                        ".scss": "postcss-scss"
                      }
                    }
                  ]
                ]
              }
            }]
          },
          {
            test: /\.scss$/,
            use: [
              'style-loader',
              {
                loader: 'css-loader',
                options: {
                  sourceMap: true,
                  modules: true,
                  importLoaders: 2,
                  localIdentName: '[name]__[local]___[hash:base64]'
                }
              },
              'sass-loader',
              {
                loader: 'postcss-loader',
                options: {
                  plugins: () =&gt; {
                    return [
                      require('autoprefixer')
                    ];
                  }
                }
              }
            ]
          }
        ]
      },
      plugins: [
        new webpack.HotModuleReplacementPlugin(),
        // enable HMR globally
        new webpack.NamedModulesPlugin()
        // prints more readable module names in the browser console on HMR updates
      ]
    }
  };
  </code></pre>
  
  <p>And last but not least, my HMR setup. I've this setup in my <code>index.js</code> file:</p>
  
  <pre><code>import React from 'react';
  import ReactDOM from 'react-dom';
  import { AppContainer } from 'react-hot-loader';
  import TodoApp from './components/TodoApp';
  import './stylesheets/Stylesheets.scss';
  
  const render = (Component) =&gt; {
    ReactDOM.render(
        &lt;AppContainer&gt;
          &lt;Component /&gt;
        &lt;/AppContainer&gt;,
        document.querySelector('#main')
    );
  };
  
  render(TodoApp);
  
  // Hot Module Replacement API
  if (module.hot) {
    module.hot.accept('./components/TodoApp', () =&gt; {
      render(TodoApp)
    });
  }
  </code></pre>
  
  <p>So, when I run my <code>npm start build:dev</code> in my browser and go to <code>http://localhost:3000</code> I see my site working as expected. This is the output in the console:</p>
  
  <pre><code>dev-server.js:49 [HMR] Waiting for update signal from WDS...
  only-dev-server.js:66 [HMR] Waiting for update signal from WDS...
  TodoApp.js:102 test
  client?344c:41 [WDS] Hot Module Replacement enabled.
  </code></pre>
  
  <p>The <code>test</code> text comes from the render function in my <code>TodoApp</code> component. This function looks like this:</p>
  
  <pre><code>render() {
    console.log('test');
    return(
        &lt;div styleName="TodoApp"&gt;
          &lt;TodoForm addTodo={this.addTodo} /&gt;
          &lt;TodoList todos={this.state.todos} deleteTodo={this.deleteTodo} toggleDone={this.toggleDone} updateTodo={this.updateTodo} /&gt;
        &lt;/div&gt;
    );
  }
  </code></pre>
  
  <p>So, now the important stuff. I update the return of this render function, which should trigger the HMR to kick in. I change the render function to this.</p>
  
  <pre><code>render() {
    console.log('test');
    return(
        &lt;div styleName="TodoApp"&gt;
          &lt;p&gt;Hi Stackoverflow&lt;/p&gt;
          &lt;TodoForm addTodo={this.addTodo} /&gt;
          &lt;TodoList todos={this.state.todos} deleteTodo={this.deleteTodo} toggleDone={this.toggleDone} updateTodo={this.updateTodo} /&gt;
        &lt;/div&gt;
    );
  }
  </code></pre>
  
  <p>This is the output I get in the console:</p>
  
  <pre><code>client?344c:41 [WDS] App updated. Recompiling...
  client?344c:41 [WDS] App hot update...
  dev-server.js:45 [HMR] Checking for updates on the server...
  TodoApp.js:102 test
  log-apply-result.js:20 [HMR] Updated modules:
  log-apply-result.js:22 [HMR]  - ./components/TodoApp.js
  dev-server.js:27 [HMR] App is up to date.
  </code></pre>
  
  <p>You would say this is good. <strong>But my site doesn't update ANYTHING.</strong></p>
  
  <p>Then I change the the HMR code in my <code>index.js</code> to this:</p>
  
  <pre><code>// Hot Module Replacement API
  if (module.hot) {
    module.hot.accept();
  }
  </code></pre>
  
  <p>And it works. I just don't get it. Why doesn't it work if this is my HMR code:</p>
  
  <pre><code>// Hot Module Replacement API
  if (module.hot) {
    module.hot.accept('./components/TodoApp', () =&gt; {
      render(TodoApp)
    });
  }
  </code></pre>
  
  <p>BTW this setup is based on the setup from <a href="https://webpack.js.org/guides/hmr-react/" rel="nofollow noreferrer">https://webpack.js.org/guides/hmr-react/</a></p>
  
  <p>I hope that anyone can help me. If someone needs more information don't hesitate to ask. Thanks in advance!</p>
  
  <p><strong>UPDATE</strong></p>
  
  <p>Forgot to post my <code>.babelrc</code> file. This is it:</p>
  
  <pre><code>{
    "presets": [
      ["es2015", {"modules": false}],
      // webpack understands the native import syntax, and uses it for tree shaking
  
      "react"
      // Transpile React components to JavaScript
    ],
    "plugins": [
      "react-hot-loader/babel"
      // EnablesReact code to work with HMR.
    ]
  }
  </code></pre>