webpack devServer не срабатывает при изменении sass файла

При внесении изменений в любой файл sass, не происходит перезагрузка страницы или же HMR.

Если закомментировать строки в splitChunks, то все работает.

styles: {
  chunks: "all",
  enforce: true,
  test: /\.(css|sass|scss)$/,
},

webpack.config.js

"use strict";

const path = require("path");
const webpack = require("webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const HtmlWebpackExcludeAssetsPlugin = require("html-webpack-exclude-assets-plugin");


const NODE_ENV = process.env.NODE_ENV;

const PATH = {
  src: path.resolve(__dirname, "src"),
  build: path.resolve(__dirname, "build"),
  js: path.join(__dirname, "src/js/"),
  outputJs: "./js/",
};

module.exports = {
  context: PATH.js,
  entry: {
    index: `./pages/index.js`,
    first: `./pages/first.js`,
    second: `./pages/second.js`,
  },
  output: {
    path: PATH.build,
    filename: `${PATH.outputJs}[name]~[hash].js`,
    chunkFilename: `${PATH.outputJs}[name]~[hash].js`,
    library: "[name]",
  },
  optimization: {
    minimizer: [
      new UglifyJsPlugin({
        parallel: 4,
        uglifyOptions: {
          compress: {
            // drop_console: true
          },
        },
      }),
    ],
    splitChunks: {
      // chunks: 'all',
      cacheGroups: {
        vendors: {
          chunks: "all",
          enforce: true,
          test: /[\\/]node_modules[\\/]/,
        },
        commons: {
          chunks: "all",
          enforce: true,
          test: /[\\/]js[\\/]/,
        },
        styles: {
          chunks: "all",
          enforce: true,
          test: /\.(css|sass|scss)$/,
        },
      },
    },
  },
  devServer: {
    overlay: true,
    contentBase: PATH.src,
    host: "0.0.0.0",
    public: "***********", //тут мой ip
    port: "3000",
    // hot: true
    // watchContentBase: true,
    // hot: true,
    // watchOptions: {
    //   poll: true
    // }
  },
  resolve: {
    modules: ["node_modules"],
    alias: {
      // mdl: path.resolve(__dirname, 'src/js/modules')
    },
    extensions: [".js"],
  },
  resolveLoader: {
    modules: ["node_modules"],
    extensions: [".js", ".css", ".sass"],
  },
  module: {
    rules: [
      //Babel START
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
          options: {
            presets: ["@babel/preset-env"],
            plugins: ["@babel/plugin-transform-runtime"],
          },
        },
      },
      //Babel END
      //Sass START
      {
        test: /\.(sa|sc|c)ss$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
            // options: {
            //   hmr: NODE_ENV === "development",
            //   reloadAll: true,
            // },
          },
          // {
          //   loader: 'style-loader',
          // },
          "css-loader",
          "sass-loader",
        ],
      },
      //Sass END
    ],
  },
  plugins: [
    // new CleanWebpackPlugin(),
    new MiniCssExtractPlugin({
      // Options similar to the same options in webpackOptions.output
      // both options are optional
      filename: "css/[name]~[hash].css",
      chunkFilename: "css/[name]~[hash].css",
    }),
    new HtmlWebpackExcludeAssetsPlugin(),
    new HtmlWebpackPlugin({
      filename: "index.html",
      template: PATH.src + "/index.html",
      // hash: true,
      excludeAssets: [/style.*.js/],
      chunks: ["index"],
    }),
    new HtmlWebpackPlugin({
      filename: "first.html",
      template: PATH.src + "/first.html",
      // hash: true,
      excludeAssets: [/style.*.js/],
      chunks: ["first"],
    }),
    new HtmlWebpackPlugin({
      filename: "second.html",
      template: PATH.src + "/second.html",
      // hash: true,
      excludeAssets: [/style.*.js/],
      chunks: ["second"],
    }),
    {
      apply(compiler) {
        compiler.hooks.shouldEmit.tap(
          "Remove styles from output",
          (compilation) => {
            // delete compilation.assets['styles.js'];  // Remove asset. Name of file depends of your entries and
            for (let key in compilation.assets) {
              let a = !key.match(/^.+?styles.+?\.js$/);
              // a ? null : console.log(key);
              a ? null : delete compilation.assets[key];
            }
            return true;
          }
        );
      },
    },
  ],
};

Структура проекта

Файловая структура

P.S: Напишите в коментарии что необходимо еще добавить, что бы раскрыть проблему.


Ответы (1 шт):

Автор решения: NocteFury

Webpack производит пересборку проекта, если чанк был модифицирован.

Каждый раз, когда вы собираете проект, webpack строит дерево зависимостей от entry файлов. Если какой-то из них меняется, модифицируется дерево и пересобирается изменившаяся часть.

Возможно при делении чанков у вас чанк с sass файлами просто не импортируется в entry файл и потому их изменение не обновляет всю сборку.

→ Ссылка