Search code examples
javascriptreactjswebpackbabeljsreact-hot-loader

React Hot Loader seems to work but doesn't update. [babel-preset-env]


I tried to set up a minimal project which utilises the newest versions of Webpack, React, Babel and React Hot Loader. I have the same issue as described here. However the only difference is that I am using (beside solely the stuff mentioned above) babel-preset-env instead of babel-preset-es2015, thus the fix does not apply for me.

In short: Everything works, React Hot Loader detects changes but the components are not rerendered and the changes are not applied to the website.

You can find the complete project here. (yarn install/yarn start should get it started) You can reproduce the behaviour by changing the testString in /components/App.js and saving the file.

What am I doing wrong?

webpack.config.js

var webpack = require('webpack')

module.exports = {
    entry: [
      'react-hot-loader/patch',
      './src/index.js'
    ],
    output: {
        path: __dirname + '/dist',
        publicPath: '/',
        filename: 'bundle.js'
    },
    resolve: {
      extensions: ['*', '.js', '.jsx']
    },
    module: {
        rules: [
            {
              test: /\.js$/,
              exclude: /(node_modules)/,
              use: {
                loader: 'babel-loader',
              }
            }
          ]
    },
    devServer: {
      contentBase: './dist',
      hot: true
    },
    plugins: [
        new webpack.NamedModulesPlugin(),
        new webpack.HotModuleReplacementPlugin()
      ]

}

.babelrc

{
    "presets": [
      "react",
      [ "env", {
        "targets": {
          "browsers": "> 10%"
        }
      }]
    ],
    "plugins": ["react-hot-loader/babel"]
  }

index.js

import React from 'react'
import ReactDOM from 'react-dom'
import { AppContainer } from 'react-hot-loader'
import App from '../components/App'

const render = Component => {
    ReactDOM.render(
      <AppContainer>
        <Component />
      </AppContainer>,
      document.getElementById('app'),
    )
  }

render(App)

if (module.hot) {
const NextApp = require('../components/App').default
module.hot.accept('../components/App', () => { render(NextApp) })
}

package.json

{
  "name": "minimal-react",
  "version": "0.1.0",
  "description": "minimal react",
  "main": "index.js",
  "repository": "https://github.com/PeterKey/minimal-react.git",
  "dependencies": {
    "path": "^0.12.7",
    "react": "^16.1.1",
    "react-dom": "^16.1.1",
    "webpack": "^3.8.1",
    "webpack-dev-server": "^2.9.4"
  },
  "devDependencies": {
    "babel-core": "^6.26.0",
    "babel-loader": "^7.1.2",
    "babel-preset-env": "^1.6.1",
    "babel-preset-react": "^6.24.1",
    "react-hot-loader": "^3.1.3"
  },
  "scripts": {
    "start": "webpack-dev-server --progress --colors --config ./webpack.config.js"
  }
}

Solution

  • Okay I realised that I simply need to set the {"modules": false} property for the "env" preset the same way as for the "es2015" preset.

    .babelrc

    {
    "presets": [
      "react",
      [ "env", {
        "modules": false,
        "targets": {
          "browsers": "> 10%"
        }
      }]
    ],
    "plugins": ["react-hot-loader/babel"]
    

    }