Correct way to configure babel-loader in webpack for HMR

1k Views Asked by At

About a week ago I ran into a problem while adding HMR to my project, the problem was that it just didn't work, the console showed HMR Enabled and also detected changes on the files, but it didn't re-render the view, the console would log:

[HMR] Updated modules:
[HMR]  - ./app/src/components/app.jsx
[HMR] App is up to date.

but nothing would change visually, neither in the code inspector.

After lots of experimenting I found out that the problem was being caused by the babel-loader, it somehow interfered with webpacks HMR motor or something like that. I solved it by excluding the index file in the babel loader, however I don't think that's the best approach since now I can't use some js features in my index.jsx file. I want to know if theres a better way to solve this issue, perhaps something in my configuration or in the way of setting up webpacks hot middleware.

This is my webpack configuration:

module.exports = {
  resolve: {
    extensions: ['*', '.js', '.jsx']
  },
  entry: [
    'webpack-hot-middleware/client', './app/src/index.jsx'
  ],
  output: {
    path: path.resolve(__dirname, 'build/js'),
    filename: 'bundle.js',
    publicPath: '/public'
  },
  devtool: 'cheap-module-source-map',
  module: {
    rules: [{
      test: /\.jsx?$/,
      exclude: /node_modules/,
      include: path.resolve(__dirname, 'app/src/'),
      exclude: path.resolve(__dirname, 'app/src/index.jsx'),
      use: [{
        loader: 'babel-loader',
        options: {
          presets: [
            'react-hmre'
          ],
          plugins: [
            'transform-object-rest-spread'
          ]
        }
      }],
    }]
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NoEmitOnErrorsPlugin()
  ]
}

And this is how I setup the hot middleware and react-hot-loader in my server:

const webpack = require('webpack')
const webpackDevMiddleware = require('webpack-dev-middleware')
const webpackHotMiddleware = require('webpack-hot-middleware')

const webpackConfig = require('./webpack.dev.config')
const compiler = webpack(webpackConfig)

app.use(webpackDevMiddleware(compiler, {
  noInfo: true,
  publicPath: webpackConfig.output.publicPath
}))

app.use(webpackHotMiddleware(compiler))

Thanks in advance.

1

There are 1 best solutions below

0
On BEST ANSWER

So it was the babel configuration as I thought, you need the option modules: false in the env preset so it lets webpack handle the modules, it is a noob mistake but man, it drove me crazy for days.

The correct config for the env preset its like so:

['env', {modules: false}]