如何从 html-webpack-plugin 生成中排除 link 标签(或更具体地说,由 mini-css-extract-plugin 提取的 .css 文件)?

How to exclude link tags (or more specifically .css files extracted by the mini-css-extract-plugin) from being generated by html-webpack-plugin?

由于(遗留)项目当前的设置方式,我无法以标准方式从 webpack 的缓存功能中受益,而是必须在空文件中生成脚本(如 main.html5 示例)并将它们包含在项目的头部或正文中。

这与我目前的配置工作得很好,但我发现自己缺乏引用 main.[hash].js 和 main.[hash].css 的能力,由 [=34= 提取]mini-css-extract-plugin 在单独的 ejs 文件中,以便我可以将每个生成的 html5 包含在我的 html5 模板的不同位置(link 标签在头部和脚本中正文)。

webpack.common.js :

module.exports = {
  entry: {
    main: path.resolve(__dirname, "./react/src/Index.js"),
    styles: path.resolve(__dirname, "./react/src/Styles.js"),
    vendor: path.resolve(__dirname, "./react/src/Vendor.js"),
  },
  output: {
    path: path.resolve(__dirname, "./dist"),
    filename: "[name].[contenthash].js",
    assetModuleFilename: "images/[hash][ext][query]",
  },
  plugins: [
    new CleanWebpackPlugin(),
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, "./react/main.ejs"),
      filename: "main.html5",
      inject: false,
      publicPath: "/dist/",
      chunks: ["main"], // would be great to only reference .js here, then create another instance for .css
    }),
    new MiniCssExtractPlugin({
      filename: "[name].[contenthash].css",
    }),
  ],

main.ejs 只有 :

<%= htmlWebpackPlugin.tags.headTags %>

生成main.html5文件:

<script defer="" src="/dist/main.534ca9564003f8d93251.js"></script><link href="/dist/main.0864e3dfa0f6edc21e68.css" rel="stylesheet">

然后我将 main.html5 包含到我的项目模板中,如下所示:

<body>
// ---- html code goes here
        <?php include_once 'dist/main.html5'; ?> 
</body>

问题是这会在 body 标签的末尾加载两个标签,而我想在头部包含 css tags.So 理想情况下,我会有 2 html5 文件生成。一个包含 script 标签,另一个包含 link 标签。我已经阅读了 webpack 的文档,但没有看到任何适用于我的案例的可能解决方案。如果我可以从 ejs 文件中排除可能是解决方案的标签,但我无法在 HtmlWebpackPlugin 文档中找到任何相关信息。

所以,我发现了 html-webpack-exclude-assets-plugin 这正是我想要的,但不幸的是它没有工作并且大约 5 年没有更新。值得庆幸的是,html-webpack-skip-assets-plugin 有一个替代方案。这是我的使用方法:

webpack.common.js :

const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const HtmlWebpackSkipAssetsPlugin =
  require("html-webpack-skip-assets-plugin").HtmlWebpackSkipAssetsPlugin;

    module.exports = {
      entry: {
        main: path.resolve(__dirname, "./react/src/Index.js"),
      },
      output: {
        path: path.resolve(__dirname, "./dist"),
        filename: "[name].[contenthash].js",
        assetModuleFilename: "images/[hash][ext][query]",
      },
  optimization: {
    minimizer: [`...`, new CssMinimizerPlugin()],
    splitChunks: {
      cacheGroups: {
        styles: {
          name: "styles",
          type: "css/mini-extract",
          chunks: "all",
          enforce: true,
        },
      },
    },
  },
      plugins: [
        new CleanWebpackPlugin(),
        new HtmlWebpackPlugin({
          template: path.resolve(__dirname, "./react/vendor.ejs"),
          filename: "vendor.html5",
          inject: false,
          publicPath: "/dist/",
          chunks: ["vendor"],
          excludeAssets: [
            /\/dist\/styles.*.css/,
            (asset) => asset.attributes && asset.attributes["x-skip"],
          ],
        }),
        new HtmlWebpackPlugin({
          template: path.resolve(__dirname, "./react/styles.ejs"),
          filename: "styles.html5",
          inject: false,
          publicPath: "/dist/",
          chunks: ["main"],
          // excludeAssets: [/\.css$/i]
          excludeAssets: [
            /\/dist\/main.*.js/,
            (asset) => asset.attributes && asset.attributes["x-skip"],
          ],
        }),
        new MiniCssExtractPlugin({
          filename: "[name].[contenthash].css",
        }),    
        new HtmlWebpackSkipAssetsPlugin(),

      ],
module: {
rules: [
  {
    test: /\.js$/,
    exclude: /node_modules/,
    use: ["babel-loader"],
  },
  {
    test: /\.css$/i,
    exclude: /node_modules/,
    use: [MiniCssExtractPlugin.loader, "css-loader"],
  },
  {
    test: /\.(?:ico|gif|png|jpg|jpeg)$/i,
    type: "asset/resource", //* less performance heavy than asset/inline
  },
  {
    test: /\.(woff(2)?|eot|ttf|otf|svg)$/i,
    type: "asset/inline", //* only for small assets. if webpack complains about asset size limit, change to asset/ressource type or asset. Had these as inline before (woff(2)?|eot|ttf|otf|svg),
  },
],
  },

好了,我们现在可以在自己的 html 文件中生成 css link 标签,并将其包含在我们项目的 .html 文件中任何需要的地方5 个模板。