medBouzid
medBouzid

Reputation: 8442

webpack hot module replacement not working

Am trying to use HRM (Hot Module Replacement) in my webpack config, first I have set the --hot option within my package.jsong:

"scripts": {
    "start": "webpack-dev-server --hot"
}

Also note that am using the HtmlWebpackPlugin in order to create an index.html file for me and put it in a "build" directory, here is my full webpack.config.js file:

const path = require('path');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const TerserJSPlugin = require('terser-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const WebpackManifestPlugin = require('webpack-manifest-plugin');
var HtmlWebpackPlugin = require('html-webpack-plugin');
// const webpack = require('webpack');
const mode = "development";

module.exports = {
  mode: mode,
  // watch: true,
  devtool: "cheap-module-eval-source-map",
  devServer: {
    port: 9000,
    // contentBase: path.resolve(__dirname, 'build')
  },
  entry: {
    application: "./src/javascripts/index.js",
    admin: "./src/javascripts/admin.js"
  },
  output: {
    filename: mode === 'production' ? "[name]-[contenthash].js" : '[name].[hash].js',
    path: path.resolve(__dirname, 'build'),
    // publicPath: '/'
  },
  optimization: {
    minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],
  },
  plugins: [
    new MiniCssExtractPlugin({
        filename: mode === 'production' ? "[name]-[contenthash].css" : "[name]-[hash].css",
        hmr: mode === 'production' ? false : true
    }),
    new CleanWebpackPlugin(),
    new WebpackManifestPlugin(),
    new HtmlWebpackPlugin({
      template: './src/template.html',
      // filename: '../index.html'
    })
    // new webpack.HotModuleReplacementPlugin()
  ],
  module: {
    rules: [
      {
        test: /\.m?js$/,
        exclude: /(node_modules|bower_components)/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env']
          }
        }
      },
      {
        test: /\.css$/i,
        use: [
          MiniCssExtractPlugin.loader,
          { loader: 'css-loader', options: { importLoaders: 1 } },
          {
            loader: 'postcss-loader',
            options: {
              plugins: [
                require('autoprefixer')({
                  overrideBrowserslist: ['last 3 versions', 'ie > 9']
                })
              ]
            }
          },
        ],
      },
      {
        test: /\.scss$/i,
        use: [
          MiniCssExtractPlugin.loader,
          { loader: 'css-loader', options: { importLoaders: 1 } },
          {
            loader: 'postcss-loader',
            options: {
              plugins: [
                require('autoprefixer')({
                  overrideBrowserslist: ['last 3 versions', 'ie > 9']
                })
              ]
            }
          },
          'sass-loader'
        ],
      },
      {
        test: /\.(png|jpg|gif|svg)$/i,
        use: [
          {
            loader: 'file-loader',
            options: {
              limit: 8192,
              name: '[name].[hash:7].[ext]'
            },
          },
          {
            loader: 'image-webpack-loader'
          }
        ],
      }
    ]
  }

}

As you see the entry I use mainly is ./src/javascripts/index.js where am importing a file called application.scss:

import application from "../stylesheets/application.scss"

the application.scss contains:

span{
  background-color: blue;
}

So I want to hot reload the page whenever I change the background color of the span located in my html page.

when I run npm run start then I change the background color of the span the update works the first time (BUT IT DOES A FULL PAGE RELOAD) then if I try to change the background color again nothing get updated and all I see in the console is this:

[HMR] Nothing hot updated. log.js:24
[HMR] App is up to date.

Am not sure what am missing here, but someone can see what am doing wrong?

Upvotes: 6

Views: 11551

Answers (1)

Cody Geisler
Cody Geisler

Reputation: 8617

From the documentation,

it tries to update with HMR before trying to reload the whole page

So, presumably, if that fails, it will just reload the entire page, which is what you're seeing.

Have you tried including this at the end of your primary entry file?

if (module.hot) {
  module.hot.accept(function (err) {
    console.log('An error occurred while accepting new version');
  });
}

Also, inspect the -hot.js file requests of network tab of Chrome's developer tools --- are they status 200, 404, 500? Maybe your server is crashing or not serving them correctly.

Ensure in your webpack that you also have

devServer: {
  // contentBase: './dist', // this watches for html changes, apparently?
  contentBase: path.resolve(__dirname, 'build') // in your specific case maybe?
  hot: true,
},

Upvotes: 2

Related Questions