webpackwebpack-dev-serverwebpack-5webpack-hmr

webpack-dev-server not reloading


I am using webpack 5 and I currently have the following setup:

The issue I am currently facing is that I am unable to get webpack dev server live reloading to work (this apply to all file types). I've been through the docs but no luck so far.

As far as I understand, when in development mode, webpack runs stuff in memory rather than in disk (which is supposed to be faster and that is great!). For some reason it appears that the watcher is not reacting to changes in the files specified in the devServer.watchFiles config. I was expecting webpack to detect changes on a typescript file, compile it and reload, but that's not happening.

You can find the contents of both files below.

webpack.prod.js:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const TerserPlugin = require('terser-webpack-plugin');
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
const CopyPlugin = require('copy-webpack-plugin');
const buildPath = path.resolve(__dirname, 'dist');

module.exports = {
  //devtool: 'source-map',
  entry: {
    index: "./src/index/index.ts",
    error: "./src/error/error.ts",
  },
  output: {
    filename: "js/[name].[contenthash].js",
    path: buildPath,
    clean: true,
  },
  module: {
    rules: [{
        test: /\.ts$/i,
        exclude: /node_modules/,
        use: "ts-loader",
      },
      {
        test: /\.html$/i,
        exclude: /node_modules/,
        use: "html-loader",
      },
      {
        test: /\.css$/i,
        exclude: /node_modules/,
        use: [
          MiniCssExtractPlugin.loader,
          "css-loader",
        ]
      },
      {
        test: /\.png$/i,
        exclude: /node_modules/,
        type: "asset/resource",
        generator: {
          filename: "img/[name].[contenthash][ext]",
        },
      },
      {
        test: /\.(woff|woff2|ttf)$/i,
        exclude: /node_modules/,
        type: "asset/resource",
        generator: {
          filename: "fonts/[name].[contenthash][ext]",
        },
      },
      {
        test: /\.mp3$/i,
        exclude: /node_modules/,
        type: "asset/resource",
        generator: {
          filename: "[name].[contenthash][ext]",
        },
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: "./src/index/index.ejs",
      inject: "body",
      chunks: ["index"],
      filename: "index.html",
      meta: {
        "robots": {
          name: "robots",
          content: "index,follow"
        },
      },
    }),
    new HtmlWebpackPlugin({
      template: "./src/error/error.html",
      inject: "body",
      chunks: ["error"],
      filename: "error.html",
    }),
    new MiniCssExtractPlugin({
      filename: "css/[name].[contenthash].css",
      chunkFilename: "css/[id].[contenthash].css",
    }),
    new CopyPlugin({
      patterns: [{
        from: "src/robots.txt",
        to: "robots.txt",
      }, ],
    }),
  ],
  optimization: {
    minimize: true,
    minimizer: [
      new TerserPlugin({
        parallel: true,
      }),
      new CssMinimizerPlugin(),
      new ImageMinimizerPlugin({
        minimizer: {
          implementation: ImageMinimizerPlugin.imageminMinify,
          options: {
            plugins: [
              ["imagemin-pngquant", {
                quality: [0.5, 0.9]
              }],
            ],
          },
        },
      }),
    ],
  },
};

webpack.dev.js:

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
    mode: "development",
    devtool: "eval-cheap-module-source-map",
    entry: {
        index: "./src/index/index.ts",
        error: "./src/error/error.ts",
    },
    devServer: {
        watchFiles: [path.resolve(__dirname, "src/**/*")],
        open: true,
    },
    module: {
        rules: [
            {
                test: /\.ts$/i,
                exclude: /node_modules/,
                use: "ts-loader",
            },
            {
                test: /\.html$/i,
                exclude: /node_modules/,
                use: "html-loader",
            },
            {
                test: /\.css$/i,
                exclude: /node_modules/,
                use: ["style-loader", "css-loader"]
            },
            {
                test: /\.png$/i,
                exclude: /node_modules/,
                type: "asset/resource",
                generator: {
                    filename: "img/[name].[contenthash][ext]",
                },
            },
            {
                test: /\.(woff|woff2|ttf)$/i,
                exclude: /node_modules/,
                type: "asset/resource",
                generator: {
                    filename: "fonts/[name].[contenthash][ext]",
                },
            },
            {
                test: /\.mp3$/i,
                exclude: /node_modules/,
                type: "asset/resource",
                generator: {
                    filename: "[name].[contenthash][ext]",
                },
            },
        ],
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: "./src/index/index.ejs",
            inject: "body",
            chunks: ["index"],
            filename: "index.html",
            meta: {
                "robots": { name: "robots", content: "noindex, nofollow" },
            },
        }),
        new HtmlWebpackPlugin({
            template: "./src/error/error.html",
            inject: "body",
            chunks: ["error"],
            filename: "error.html"
        }),
    ],
    optimization: {
        runtimeChunk: "single",
    },
};


Solution

  • The issue was related with WSL. More specifically running webpack in WSL on Windows file system (e.g. at /mnt/c/Users/MyUser/Documents/MyProject).

    After moving the project to WSL file system (e.g. at /home/MyUser/MyProject) I was able to get live reload to work.

    Even though this question mentions Parcel and Webpack, it is similar. I found the answer provides good context around the issue: https://stackoverflow.com/a/72786450/3685587