【问题标题】:How to exclude link tags (or more specifically .css files extracted by the mini-css-extract-plugin) from being generated by html-webpack-plugin?如何排除 html-webpack-plugin 生成的链接标签(或更具体地说是由 mini-css-extract-plugin 提取的 .css 文件)?
【发布时间】:2021-12-10 10:10:37
【问题描述】:

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

这适用于我目前拥有的配置,但我发现自己缺乏引用 mini-css-extract-plugin 提取的 main.[hash].js 和 main.[hash].css 的能力在单独的 ejs 文件中,以便我可以将每个生成的 html5 包含在我的 html5 模板的不同位置(头部中的链接标记和正文中的脚本)。

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",
    }),
  ],

ma​​in.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 标签的末尾加载两个标签,而我想在 head 标签中包含 css。所以理想情况下,我会生成 2 个 html5 文件。一个包含 script 标签,另一个包含 link 标签。我已经阅读了 webpack 的文档,但没有看到任何可能适用于我的情况的解决方案。如果我可以从 ejs 文件中排除标签,这可能是一个解决方案,但我在 HtmlWebpackPlugin 文档中找不到任何相关内容。

【问题讨论】:

    标签: javascript webpack legacy html-webpack-plugin mini-css-extract-plugin


    【解决方案1】:

    所以,我发现 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 链接标签,并将它包含在我们项目的 .html5 模板中的任何需要的地方。

    【讨论】:

      猜你喜欢
      • 2020-04-09
      • 2019-02-22
      • 2018-08-26
      • 2019-06-27
      • 2019-01-29
      • 2018-08-30
      • 2023-01-05
      • 2018-12-01
      • 2019-12-24
      相关资源
      最近更新 更多