vite 对 css 文件的处理
vite 天生支持对 css 文件的直接处理。vite 对 css 文件的处理流程如下:
- 当 vite 发现 JavaScript 中引用了 css 文件之后,会通过 fs 模块读取对应 css 中的内容;
- 创建一个 style 标签,将 css 文件中的内容直接 copy 到 style 标签中,并将创建的 style 标签插入到 html 文件的 head 中;
- 将 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 为后缀的文件时的流程为:
- 将所有的类名进行一定规则的替换,例如:footer 替换为 _footer_1nr35_1;
- 同时创建一个映射对象 { footer: "_footer_1nr35_1" }
- 创建一个 style 标签,将替换后的内容塞进 style 标签里,并将创建的 style 标签插入到 html 文件的 head 中;
- 将 .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 的模块化。