You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Webpack HTML loader与CSS loader配合失效问题求助

问题场景

我使用Electron Forge和Webpack搭建项目,已添加public目录并引入html-loader处理HTML文件中的资源导入。Webpack配置规则如下:

export const rules: Required<ModuleOptions>["rules"] = 
[
    // Add support for native node modules
    {
        // We're specifying native_modules in the test because the asset relocator loader generates a
        // "fake" .node file which is really a cjs file.
        test: /native_modules[/\\].+\.node$/,
        use: "node-loader",
    },
    {
        test: /[/\\]node_modules[/\\].+\.(m?js|node)$/,
        parser: { amd: false },
        use: 
        {
            loader: "@vercel/webpack-asset-relocator-loader",
            options: 
            {
                outputAssetBase: "native_modules",
            },
        },
    },
    {
        test: /\.tsx?$/,
        exclude: /(node_modules|\.webpack)/,
        use: {
            loader: "ts-loader",
            options: 
            {
                transpileOnly: true,
            },
        },
    },

    {
        test: /\.(png|jpe?g|gif|svg|ico|woff|woff2|ttf|otf|eot|mp4|webm|mp3|wav|pdf|txt)$/,
        type: "asset/resource",
        generator:
        {
            filename: "assets/[hash][ext][query]",
        }
    },

    {
        test: /\.(htm|html)$/,
        use: 
        [{
            loader: "html-loader",
        }],
    },
];

export const alias =
{
    "source": path.resolve(__dirname, "source"),
    "public": path.resolve(__dirname, "public")
}

尝试在HTML中直接通过<link>标签引入CSS文件:

<head>
    <meta charset="UTF-8" />
    <title>Hello World!</title>
    <link rel="stylesheet" type="text/css" href="./index.css" />
</head>

但CSS样式并未生效。查看开发者工具发现,生成的HTML中CSS文件路径已被处理为/29125ef8bd79b19044b6.css,但访问该路径返回的不是CSS代码,而是包含style-loader相关导入的JS代码:

import API from "!../../../../node_modules/.pnpm/style-loader@3.3.4_webpack@5.94.0/node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js";
import domAPI from "!../../../../node_modules/.pnpm/style-loader@3.3.4_webpack@5.94.0/node_modules/style-loader/dist/runtime/styleDomAPI.js";
import insertFn from "!../../../../node_modules/.pnpm/style-loader@3.3.4_webpack@5.94.0/node_modules/style-loader/dist/runtime/insertBySelector.js";
import setAttributes from "!../../../../node_modules/.pnpm/style-loader@3.3.4_webpack@5.94.0/node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js";
import insertStyleElement from "!../../../../node_modules/.pnpm/style-loader@3.3.4_webpack@5.94.0/node_modules/style-loader/dist/runtime/insertStyleElement.js";
import styleTagTransformFn from "!../../../../node_modules/.pnpm/style-loader@3.3.4_webpack@5.94.0/node_modules/style-loader/dist/runtime/styleTagTransform.js";
import content, * as namedExport from "!!../../../../node_modules/.pnpm/css-loader@6.11.0_webpack@5.94.0/node_modules/css-loader/dist/cjs.js!./index.css";

var options = {};

options.styleTagTransform = styleTagTransformFn;
options.setAttributes = setAttributes;
options.insert = insertFn.bind(null, "head");
options.domAPI = domAPI;
options.insertStyleElement = insertStyleElement;

var update = API(content, options);

export * from "!!../../../../node_modules/.pnpm/css-loader@6.11.0_webpack@5.94.0/node_modules/css-loader/dist/cjs.js!./index.css";
export default content && content.locals ? content.locals : undefined;

原因分析

Webpack默认会将CSS文件视为模块,通过style-loader和css-loader处理后输出为JS代码(用于动态注入样式到DOM)。当html-loader解析HTML中的<link>标签时,Webpack并没有将CSS作为独立资源输出,而是按照模块处理,导致生成的路径指向JS文件而非纯CSS文件,浏览器无法正确解析为样式。

解决方案

方案一:使用mini-css-extract-plugin提取独立CSS文件

该插件可将CSS从模块中提取为独立文件,匹配HTML中<link>标签的加载需求。

操作步骤:

  1. 安装插件:
npm install mini-css-extract-plugin --save-dev
  1. 修改Webpack配置:
    • 导入插件:
      import MiniCssExtractPlugin from 'mini-css-extract-plugin';
      
    • 添加插件到plugins数组:
      export const plugins = [
        new MiniCssExtractPlugin({
          filename: 'assets/[hash].css'
        })
      ];
      
    • 添加CSS文件处理规则:
      {
        test: /\.css$/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader'
        ]
      }
      
    • 调整html-loader配置,确保正确识别CSS类型的<link>标签:
      {
        test: /\.(htm|html)$/,
        use: [{
          loader: "html-loader",
          options: {
            sources: {
              list: [
                '...', // 保留默认资源处理规则
                {
                  tag: 'link',
                  attribute: 'href',
                  type: 'src',
                  filter: (tag, attribute, attributes, resourcePath) => {
                    // 仅处理stylesheet类型的link标签
                    return attributes.rel === 'stylesheet';
                  }
                }
              ]
            }
          }
        }],
      }
      

方案二:直接将CSS作为静态资源输出

若无需对CSS进行模块化处理,可直接将CSS归类为asset/resource,让Webpack输出为静态资源:

{
  test: /\.css$/,
  type: 'asset/resource',
  generator: {
    filename: 'assets/[hash][ext][query]'
  }
}

此方式下,html-loader会将<link>的href替换为输出后的静态资源路径,浏览器加载到的就是纯CSS文件,样式即可正常生效。

验证修改

重新运行Electron Forge项目,查看开发者工具中的HTML,<link>标签的href应指向正确的CSS文件,访问该路径能看到纯CSS代码,样式会正常生效。

内容的提问来源于stack exchange,提问作者Yoojun Zhou

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 08:12:08