如何为Webpack配置CSS模块

228 阅读3分钟

随着你的应用程序或网站越来越大,只用一个CSS文件来工作变得越来越困难。大小的增加会导致大量的问题,比如试图拥有不同的选择器名称,以及在一个巨大的文件中上下滚动来寻找和编辑一个选择器。

有了CSS模块,你可以按照传统方式编写你的CSS规则,但样式是用JavaScript来消耗的,并在本地进行范围划分,以避免在其他地方产生意外的副作用。这是通过为CSS选择器创建一个独特的类名来实现的,允许你在不同的文件中使用相同的CSS类名,而不必担心名称冲突。另外,你不需要想出不同的选择器名称,使你在组件中的CSS具有完全的灵活性和可重复使用性。

简而言之,CSS模块是基于组件的样式表,它允许我们通过创建独特的类和范围选择器来创建包含的、模块化的CSS。

在这篇文章中,我们将通过一个Webpack演示项目来练习使用CSS模块,以学习如何配置一个应用程序来摆脱CSS众所周知的棘手的全局范围问题。

设置Webpack

让我们从设置Webpack开始。我们的演示应用程序有一个src 文件夹,其中包含index.htmlstyle.cssindex.js

src 文件夹外,我们有我们的webpack.config.js,babel.config.js,package.json, 和package-lock.json 文件。

Screenshot of CSS module file tree

你可以使用npm run build 命令来构建项目,使用npm run dev 来启动本地主机8080的应用程序。

现在,在package.json 文件中,我们应该有webpack,webpack-cli,webpack-dev-server,html-webpack-plugin 的安装。

babel-相关的模块是用来将现代的JavaScript转换为旧的语法,而CleanWebpackPlugin 将在每次构建项目时删除dist 文件夹中的内容。

对于webpack.config.js 文件,我们有一些配置是这样写的。

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");

module.exports = {
  entry: {
    main: "./src/index.js",
  },
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "main.js",
    publicPath: "",
  },
  target: ["web", "es5"],
  stats: { children: true },
  mode: "development",
  devServer: {
    static: path.resolve(__dirname, "./dist"),
    compress: true,
    port: 8080,
    open: true,
  },
  devtool: "inline-source-map",
  module: {
    rules: [
      {
        test: /\\.js$/,
        loader: "babel-loader",
        exclude: "/node_modules/",
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: "./src/index.html",
    }),
    new CleanWebpackPlugin(),
  ],
}; 

为了使用CSS模块,我们需要安装style-loadercss-loader

npm i css-loader --save-dev
npm i style-loader --save-dev

我们需要css-loader 模块来解释@importurl() ,就像import/require() ,并解决它们,同时需要style-loader 模块来将我们的CSS注入DOM。

设置style-loadercss-loader

我们已经在我们的rules 数组中设置了babel-loader ;这是在Webpack中添加加载器的地方。

加载器告诉Webpack如何在文件被添加到依赖关系图之前对它们进行修改。rules 数组由我们的加载器组成,并帮助我们对文件进行转换。这些都有助于文件和图像的加载。

请注意,我们可以将多个加载器连在一起。在下面的代码块中,css-loaderstyle-loader 被一起使用。

babel-loader 相似,我们可以加载CSS文件,以使我们的页面具有这样的风格。

module: {
    rules: [
      {
        test: /\\.js$/,
        loader: "babel-loader",
        exclude: "/node_modules/",
      },
     // CSS rules
      {
        test: /\\.css$/,
        use: [
          "style-loader",
          {
            loader: "css-loader",
            options: {
              importLoaders: 1,
              modules: true,
            },
          },
        ],
      },
    ],
  },

babel-loader 之后,我们还有其他几个对象,它们将寻找任何CSS文件并对其进行转换。

  • test 关键告诉Webpack将此规则应用于任何以.css 为扩展名的文件。
  • importLoaders 选项的值是1 ,它设定了在CSS模块和@import at-rule之前应用的加载器的数量。
  • 最后,modules:true 选项启用了CSS Modules

创建一个HTML文件

在HTML中,我们有一个div ,类名是element 。我们将在我们的JavaScript文件中访问这个元素。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>CSS Modules Webpack</title>
  </head>
  <body>
    <div class="element"></div>
  </body>
</html>

创建一个CSS文件

src 文件夹中,我们有style.css 文件。让我们在其中添加一些CSS。

:global body {
  margin: 0;
  padding: 0;
}

.page {
  background-color: purple;
  width: 100vw;
  height: 100vh;
  font-family: "Helvetica Neue", Arial, sans-serif;
  display: flex;
  align-items: center;
  justify-content: center;
}

.text {
  text-transoform: capitalize;
  color: #fff;
  font-weight: bold;
  font-size: 4em;
}

正如你所看到的,我们有body 选择器的样式和另外两个类名。

你可能认识到,我们在body选择器之前有:global 。这将使我们能够为body 选择器编写全局样式。

link 我们不需要在index.html ;相反,我们将在JavaScript文件中导入我们的style.css

// index.js

import styles from "./style.css";

console.log(styles);

如果没有Webpack,在JavaScript中导入CSS文件是不可能的。一旦我们连接了css-loader ,Webpack就能与这个导入一起工作,并将我们的CSS文件带入捆绑中。

因此,为了开始了解CSS模块,让我们首先看一下这个import 声明:import styles from './style.css';

让我们通过控制台记录来看看我们从styles 对象中得到什么。

The styles object in index.js

我们的pagetext 类名将被编译成字母、数字和字符的随机字符串。基于此,我们可以用styles.pagestyles.text 来引用我们的类。

这样,我们就可以获得引用简单类的易用性,同时保持非全局CSS的优点。这将把生成的类名添加到我们的import 语句中,然后我们就可以利用style 对象,它引用了生成的classNames

const element = document.querySelector(".element");

element.innerHTML = `<div class="${styles.page}">
     <p class="${styles.text}">CSS Modules Webpack</p>
   </div>`;

现在,npm run build 命令在dist 文件夹中建立了我们项目的捆绑版本。

运行npm run dev ,将显示我们应用于页面的样式。

Basic app with CSS Modules Webpack written in white on a purple background

我们可以在DOM树中看到生成的类名。

Screenshot of DOM tree

总结

在这篇文章中,我们学习了如何使用Webpack的CSS模块。我使用了vanilla JS,但你也可以在Gatsby、React和Next.js中使用CSS Modules。

编写模块化样式在Web开发社区中得到了重视,出现了类似于CSS Modules的不同方法。其中之一是CSS-in-JS,或者说是styled-components。有了它,你可以直接在你的JavaScript文件中编写CSS。

你可以在Github上找到这个演示项目!

The postHow to configure CSS Modules for Webpackappeared first onLogRocket Blog.