CSS Modules

也许 CSS 最重要的挑战是所有规则都存在于全局范围内,这意味着两个具有相同名称的 class 将发生冲突。CSS 本身拥有一些限制办法,但对于一个项目来说,还可以有其他的办法。CSS Modules 为每一个模块都启用了局部作用域,其做法是为每一个声明的 class 名称加上全局唯一的哈希值。

通过 css-loader 使用 CSS Modules

Webpack 的 css-loader 支持 CSS Modules。您可以通过 loader 定义来启用它:

{
  use: {
    loader: "css-loader",
    options: {
      modules: true,
    },
  },
},

完成此更改后,您的 class 定义将拥有局部作用域。如果您需要定义全局 class,则需要将它们包含在类似 :global(.redButton) { ... } 的声明类型中。

现在,使用 import 语句导入样式并在组件上应用局部 class。假设你有 CSS 如下:

app/main.css

body {
  background: cornsilk;
}

.redButton {
  background: red;
}

然后,您可以在组件中使用 class:

app/component.js

import styles from "./main.css";

...

// 使用 class
element.className = styles.redButton;

body 依然具备全局作用域,这就是 redButton 的不同之处。您可以构建特定于组件的样式,这些样式不会以其他方式泄漏。

CSS Modules 提供了诸如组合之类的附加功能,以便更轻松地使用您的样式。只要在 css-loader 之前应用它们,您也可以将它与其他 loader 结合使用。

可以按照官方文档中的说明修改 CSS 模块的行为。例如,您可以控制它生成的名称。

eslint-plugin-css-modules 可以方便地跟踪 CSS 模块相关的问题。

将 CSS Module 与第三方库以及标准 CSS 一起使用

如果您在项目中使用 CSS 模块,则应该通过单独的 loader 来处理标准 CSS,而不启用_css-loader_ modules 选项。否则,所有的 class 都将启用局部作用域。对于第三方库来说,这几乎肯定不是您想要的。

您可以针对 node_modules 目录来设定 include 规则,以不同方式处理第三方 CSS,从而解决这个问题。或者,您可以针对 css 模块启用特定的文件扩展名(.mcss),然后通过 test 匹配 css 模块,再通过 loader 对此进行处理。

总结

CSS 模块通过默认为每个文件的提供局部作用域来解决 CSS 的全局作用域问题。您仍然可以拥有全局样式,但需要额外的努力。如上所示,可以轻松地设置 Webpack 以支持 CSS 模块。

用户头像
登录后发表评论