vite 对 css 以及 css 模块化的简单处理

531 阅读3分钟

vite 对 css 文件的处理

vite 天生支持对 css 文件的直接处理。vite 对 css 文件的处理流程如下:

  1. 当 vite 发现 JavaScript 中引用了 css 文件之后,会通过 fs 模块读取对应 css 中的内容;
  2. 创建一个 style 标签,将 css 文件中的内容直接 copy 到 style 标签中,并将创建的 style 标签插入到 html 文件的 head 中;
  3. 将 css 文件中的内容,替换为 js 脚本(方面热更新和 css 模块化),同时设置 content-type 为 js,从而让浏览器以 js 脚本的形式来执行该 css 后缀的文件。

vite 对 css 模块化的处理

背景

在开发时,我们在对元素进行命名时,可能习惯于下面的规则:

  • 组件最外层元素的类名取名为 wrapper;
  • 组件最底层元素的类名取名为 footer。

协同开发过程中,在不同的组件中,多个人可能同时使用 footer 来对不同的元素进行命名。这可能会造成因为类名重复,导致样式被覆盖。

比如在 componentA.css文件中定义了一个 foot 的样式:

.footer {
  width: 100%;
  height: 200px;
  background-color: blue;
}

componentA.js文件中对 componentA.css进行了引用:

import "componentA.css"

const div = document.createElement("div");
document.body.appendChild(div);
div.className = "footer";

当其他模块中也使用了 footer 进行了命名,可能就会覆盖掉 moduleA.css 中的样式。

css module

css module 就是来解决这个问题的。在 vite 中想要启用 css module,需要将 .css 文件名修改为以 module.css结尾。module 是一种约定:如果 css 的文件名的是以 module.css 结尾的,表示需要开启 css 模块化。

修改为以 module.css 结尾的文件名之后,JavaScript 中使用 css 的样式需要做相应的修改:

import componentACss from "./componentA.module.css"

// 此时 componentACss 为一个对象:
// footer: "_footer_1nr35_1"
console.log(componentACss);

const div = document.createElement("div");
document.body.appendChild(div);
// 修改此处的类名
div.className = componentACss.footer;

vite 在处理以 module.css 为后缀的文件时的流程为:

  1. 将所有的类名进行一定规则的替换,例如:footer 替换为 _footer_1nr35_1;
  2. 同时创建一个映射对象 { footer: "_footer_1nr35_1" }
  3. 创建一个 style 标签,将替换后的内容塞进 style 标签里,并将创建的 style 标签插入到 html 文件的 head 中;
  4. 将 .module.css 文件中的内容全部抹除,替换成 js 脚本,并将创建的映射对象在脚本中进行默认导出。

less 预处理器

less 预处理器,给我提供了很多方便且实用的写法。less 也是先读取文件,获取文件中的内容,然后对文件中的内容进行修改。比如一个 less 文件的内容为

.content {
  .main {
    background-color: hotpink;
  }
}

经过 less 处理后,

.content .main {
   background-color: hotpink;
}

在 vite 也支持 less 的模块化。首先安装 less:

yarn add less

在未安装 less 时,会下面的错误提示:

[vite] Internal server error: Preprocessor dependency "less" not found. Did you install it? Try `npm install -D less`.

less 文件如果以 .module.less为结尾,则开启了 less 的模块化。

参考