How does webpack4 use MiniCssExtractPlugin to extract css to one file instead of multiple files?

I"m building a multi-page scaffolding, the kind of webpack4 that traditional jquery uses to write static pages.

here"s how I deal with page styles: all pages share a style.less (the project is small, I don"t want a css file per page), and then the entry file for each page is import ". / less/style.less"; .

then I use MiniCssExtractPlugin to extract the styles into the css file, and my plug-in configuration goes like this:

new MiniCssExtractPlugin({
    filename: "./css/[name].[hash:7].css",
    chunkFilename: "[id].css"
}),
The result of

compilation is: for example, if there are two pages index and about, index.css and about.css are generated, but the contents of the two css files are the same . I also know why, because I import the same file for each entry file, and the compiled file is naturally the same.

what I want now is that generates only one style.css, and then all generated pages introduce style.css . I tried the following configuration:

new MiniCssExtractPlugin({
    filename: "./css/style.[hash:7].css",
}),

as a result, the compilation failed. seems to be because I used htmlWebpackPlugin to generate different pages, each page introduces a chunk of the same name, and then style.css cannot correspond to those chunk .

how should I configure to complete the function I want: generate only one style.css, and then all generated pages introduce style.css ?

< hr >

paste my profile

const path = require("path");
const webpack = require("webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
// npm scriptscross-env
const devMode = process.env.NODE_ENV !== "production";

module.exports = {
  entry: {
    index: "./src/index.js",
    about: "./src/about.js"
  },
  output: {
    filename: "js/[name].bundle.js",
    path: path.resolve(__dirname, "dist"),
  },
  module: {
    rules: [{
        test: /\.(less|css)$/,
        use: [{
            // css
            loader: devMode ? "style-loader" : MiniCssExtractPlugin.loader,
          },
          {
            loader: "css-loader"
          },
          {
            loader: "postcss-loader"
          },
          {
            loader: "less-loader"
          }
        ]
      },
      {
        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
        use: [{
          loader: "url-loader",
          options: {
            limit: 1000,
            name: "./img/[hash:7].[ext]",
          }
        }]
      },
      {
        test: /\.(htm|html)$/i,
        use: [{
          loader: "html-withimg-loader"
        }]
      },
      {
        test: require.resolve("jquery"),
        use: [{
          loader: "expose-loader",
          options: "jQuery"
        }, {
          loader: "expose-loader",
          options: "$"
        }]
      },
      {
        test: /\.js$/,
        include: "./src/",
        exclude: ["./src/vendor", "./node_modules"],
        use: ["babel-loader"]
      }
    ]
  },
  optimization: {
    minimize: true,
    minimizer: [
      new UglifyJsPlugin({
        cache: true,
        parallel: true,
        sourceMap: true
      }),
      new OptimizeCSSAssetsPlugin({})
    ],
    splitChunks: {
      cacheGroups: {
        vendor: {
          // test: /\.js$/,
          test: /[\\/]node_modules[\\/]/,
          chunks: "all", 
          name: "vendor",
          enforce: true,
        }
      }
    }
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: path.resolve("./src/pages", "./index.html"),
      filename: "index.html",
      chunks: ["vendor", "index"],
      hash: true,
      minify: {
        removeComments: false,
        collapseWhitespace: false
      }
    }),
    new HtmlWebpackPlugin({
      template: path.resolve("./src/pages", "./about.html"),
      filename: "about.html",
      chunks: ["vendor", "about"],
      hash: true,
      minify: {
        removeComments: false,
        collapseWhitespace: false
      }
    }),
    new webpack.NamedModulesPlugin(),
    new webpack.HotModuleReplacementPlugin(),
    new CleanWebpackPlugin(["dist"]),
    new webpack.ProvidePlugin({
      $: "jquery",
      jQuery: "jquery",
      "window.jQuery": "jquery",
      "window.$": "jquery",
    }),
    new MiniCssExtractPlugin({
      filename: "./css/[name].[hash:7].css",
      chunkFilename: "[id].css"
    }),
  ]
}
May.15,2022

you can configure optimization to extract the css,js or even public images you want to extract, for example:

optimization: {
    runtimeChunk: {
      name: 'manifest'
    },
    splitChunks: {
      maxInitialRequests: 10,
      cacheGroups: {       
        vendor: {
          test: /(jquery|fastclick|vue.esm.js)/,
          name: 'vendor',
          chunks: 'all'
        },        
        common: {
          test: /(\.(png|jpe?g|gif|svg))/,
          name: 'app',
          chunks: 'initial',
          minChunks: 10
        },
        app: {
          test: /(css[\\/]style.css)/,
          name: 'app',
          chunks: 'initial',
          minChunks: 1
        }
      }
    }
  },
Menu