webpack5中css module开启失败的可能原因

webpack5中css module开启失败的可能原因

在最近的一个项目中,我使用了 Webpack 5 来构建一个包含 CSS Modules 的简单项目。然而,在开发过程中,我遇到了一个问题:导入的 CSS 模块类名在 JavaScript 文件中为 undefined。在经过一番排查之后,我找到了问题的根源,并解决了它。总结一下这个问题的发生原因以及解决方法,以帮助我自己和其他开发者避免类似的陷阱。

1、代码及层次

在这里插入图片描述

webpack.config.js文件内容

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
  entry: "./src/index.js", // 入口文件
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, "dist"),
    clean: true, // 清理 /dist 文件夹
  },
  mode: "development",
  devServer: {
    static: "./dist",
  },
  module: {
    rules: [
      {
        test: /\.css$/, // 匹配所有 CSS 文件
        use: [
          "style-loader", // 将 CSS 注入到 DOM 中
          {
            loader: "css-loader",
            options: {
              modules:true, // 开启 CSS Modules
            },
          },
        ],
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: "./src/index.html", // 模板 HTML 文件
    }),
  ],
};

index.js内容
在我的 index.js 文件中,通过 import styles from ‘./index.css’; 的方式导入 CSS 文件,并试图通过 styles.container 来应用 CSS 类:

import styles from "./index.css";

console.log(styles); // 打印 styles 对象,检查是否有 container 属性

const element = document.createElement("div");
element.className =styles.container;
element.textContent = "Hello, Webpack with CSS Modules!";

document.body.appendChild(element);

index.css

.container {
  color: blue;
  font-size: 20px;
  text-align: center;
  margin-top: 50px;
}

2、发现问题

不开启css module加载成功。开启后,样式就失效了,打印styles值,结果直接为undefined。
很显然,导入失败

3、排查问题

这个问题的核心是,CSS 模块类名没有正确导出,导致 JavaScript 文件无法访问到它们。
这么少的代码,问题肯定与 css-loader 的 modules 配置有关。但是我查找网上的资料基本都是这么写的,官网的案例也是这么写的。
在这里插入图片描述
打印styles值,结果直接为undefined,说明导入失败,产看css-loader的参数,发现了一个属性namedExport来决定导入的具体方式

4、解决问题

将namedExport改为false,即可成功

module: {
    rules: [
      {
        test: /\.css$/, // 匹配所有 CSS 文件
        use: [
          "style-loader", // 将 CSS 注入到 DOM 中
          {
            loader: "css-loader",
            options: {
              modules: { namedExport: false }, // 开启 CSS Modules
            },
          },
        ],
      },
    ],
  },

5、分析问题

css-loader 提供了 modules.namedExport 选项,当它被设置为 true 时,CSS Modules 会使用 named exports 的方式导出类名,而不是 default exports。

Named Export (命名导出): 每个 CSS 类会作为一个具名导出,例如 export const container = “unique-hash-class-name”。
Default Export (默认导出): 所有 CSS 类会作为一个对象被默认导出,例如 export default { container: “unique-hash-class-name” }。

问题的原因
默认导出 vs 命名导出: 在未配置 namedExport: false 的情况下,可能 css-loader 默认启用了 named exports,因此 import styles from ‘./index.css’ 的方式无法正确导入 CSS 类,因为这种导入方式期望的是一个默认导出对象(而不是命名导出)。

解决方案:
1、设置 modules: { namedExport: false } 明确告诉 css-loader 使用默认导出方式,这样代码可以继续通过 styles.container 来访问 CSS 类名。
2、命名导出,将里面的样式解构出来,再使用,也可以,代码修改如下

import { container } from "./index.css";

console.log(container); // 打印 styles 对象,检查是否有 container 属性

const element = document.createElement("div");
element.className = container;
element.textContent = "Hello, Webpack with CSS Modules!";

document.body.appendChild(element);

6、问题疑惑

令我疑惑的是官网给的默认值就是false啊QAQ
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值