Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Webpack 5 HMR issue - Cannot read property 'updatedChunkIds' of undefined

I've tried to add a HMR into my webpack 5 config and got a nasty error. First time it compiles properly, but when it comes to recompiling after code changes - it breaks with HookWebpackError: Cannot read property 'updatedChunkIds' of undefined. If I remove hot: true option - everything works properly.

My config:

const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CopyPlugin = require("copy-webpack-plugin");
const ImageminPlugin = require("imagemin-webpack-plugin").default;
const SVGSpritemapPlugin = require("svg-spritemap-webpack-plugin");

const path = require("path");
const fs = require("fs");

const PATHS = {
  src: path.join(__dirname, "./src"),
  dist: path.join(__dirname, "./dist"),
  icons: path.join(__dirname, "./src/assets/icons")
};

const PAGES_PUG = `${PATHS.src}/pug/`;
const PAGES_TO_CONVERT = fs
  .readdirSync(PAGES_PUG)
  .filter(filename => filename.endsWith(".pug"));

module.exports = (env, argv) => {
  const isEnvDevelopment = argv.mode === "development";
  const isEnvProduction = argv.mode === "production";

  return {
    entry: {
      app: [`${PATHS.src}/scripts/app.js`, `${PATHS.src}/scss/styles.scss`]
    },
    output: {
      path: `${PATHS.dist}`,
      filename: "./scripts/[name].[fullhash].min.js"
    },
    target: "web",
    devServer: {
      contentBase: path.join(__dirname, "dist"),
      publicPath: "/",
      open: true,
      watchContentBase: true,
      port: 8080,
      overlay: true,
      compress: true,
      hot: true
    },
    optimization: {
      splitChunks: {
        cacheGroups: {
          vendor: {
            name: "vendor",
            test: /node_modules/,
            chunks: "all",
            enforce: true
          }
        }
      }
    },
    resolve: {
      extensions: [".ts", ".js"]
    },
    devtool: isEnvDevelopment ? "eval-cheap-module-source-map" : "source-map",
    module: {
      rules: [
        {
          test: /\.pug$/,
          loader: "pug-loader",
          exclude: "/node_modules"
        },
        {
          test: /\.(scss|css)$/,
          use: [
            {
              loader: MiniCssExtractPlugin.loader
            },
            {
              loader: "css-loader",
              options: { sourceMap: true }
            },
            {
              loader: "postcss-loader",
              options: { sourceMap: true }
            },
            {
              loader: "resolve-url-loader"
            },
            {
              loader: "sass-loader",
              options: { sourceMap: true }
            }
          ],
          exclude: "/node_modules"
        },
        {
          test: /\.js$/,
          loader: "babel-loader",
          exclude: "/node_modules"
        },
        {
          test: /\.ts$/,
          loader: "ts-loader",
          exclude: "/node_modules"
        },
        {
          test: /.(jpg|jpeg|png|svg)$/,
          type: "asset/inline"
        },
        {
          test: /\.(woff(2)?|eot|ttf|otf)$/,
          type: "asset/inline"
        }
      ]
    },
    plugins: [
      new CleanWebpackPlugin(),
      ...PAGES_TO_CONVERT.map(
        page =>
          new HtmlWebpackPlugin({
            template: `${PAGES_PUG}/${page}`,
            filename: `./${page.replace(/\.pug/, ".html")}`
          })
      ),
      new MiniCssExtractPlugin({
        filename: `styles/styles.[hash].min.css`
      }),
      new CopyPlugin({
        patterns: [
          {
            from: "./src/assets/favicon",
            to: "assets/favicon",
            noErrorOnMissing: true
          },
          {
            from: "./src/assets/img",
            to: "assets/img",
            noErrorOnMissing: true
          },
          {
            from: "./src/assets/fonts",
            to: "assets/fonts",
            noErrorOnMissing: true
          }
        ]
      }),
      new SVGSpritemapPlugin("./src/assets/icons/icons-colored/**/*.svg", {
        output: {
          filename: "assets/sprites/sprites-colored/sprites.svg",
          svg4everybody: true,
          svgo: {
            plugins: [
              { inlineStyles: { onlyMatchedOnce: false } },
              { minifyStyles: true }
            ]
          }
        },
        sprite: {
          prefix: false
        }
      }),
      new SVGSpritemapPlugin(`./src/assets/icons/icons-solid/**/*.svg`, {
        output: {
          filename: "assets/sprites/sprites-solid/sprites.svg",
          svg4everybody: {
            polyfill: true
          },
          svgo: {
            plugins: [{ removeAttrs: { attrs: "(stroke|fill|style)" } }]
          }
        },
        sprite: {
          prefix: false
        }
      }),
      new ImageminPlugin({
        test: /\.(jpe?g|png|gif)$/i
      })
    ]
  };
};

I've tried to remove target option or change it to 'browserlist' - no effect. Also I've tried to remove hot option and init HMR like that in the plugin section:

isEnvDevelopment && new webpack.HotModuleReplacementPlugin()

and still the same error exists.

You could check all the build (dev branch) if you want to reproduce the bug.

like image 804
Natalia Davydova Avatar asked Jan 10 '21 13:01

Natalia Davydova


1 Answers

This bug appears to be fixed in webpack release 5.27.2: https://github.com/webpack/webpack/releases/tag/v5.27.2

like image 109
Mario Varchmin Avatar answered Nov 03 '22 18:11

Mario Varchmin