vite自带对css的直接处理,他的大概处理方法如下:

import './a.css';   // 比如这样直接引入了一个css文件。
  1. 通过Nodefs模块读取css文件,并创建一个<style></style>标签,把css文件写入标签。
  2. 将写入完成的标签插入到html<head></head>里。
  3. 将原本css里的内容替换为js脚本,以方便热更新模块化,同时设置content-typejs,从而让浏览器以js的处理方式处理文件。

但是这样的直接处理方式也会有一定的问题,比如:

  • 协同开发时,a用户导入了一个css文件,里面写了对.footer的样式,b用户呢,因为里面也有.footer选择器,导入的css文件里也有一个.footer,至此,会出现两个<style></style>标签,上面的标签部分样式就被覆盖了。

解决办法:使用cssmodule来解决。

  1. .css文件改为.module.css文件,表示开启了cssmodule来处理。
  2. 通过变量接收引入的.module.css文件
  3. 通过变量.你的css类名来调用。
import componentACss from './a.module.css'
const div = document.createElement('div');

console.log(componentACss); // componentACss是一个对象,里面是{你的原始类名:vite修改后的类名}这样的映射结构
div.setAttribute('class', componentACss.top);
document.body.appendChild(div);

原理思路

  1. 约定对.module.css类的文件进行处理
  2. 将你的所有类名进行一定规则的替换
  3. 创建一个映射对象,保存你的替换前类名和替换后类名
  4. 将替换后的内容插入到<style></style>里,然后插入到<head></head>里面。
  5. .module.css文件里的内容清除,替换js脚本。
  6. 将创建的映射对象默认导出

当然,Vite也能处理less类的预处理器文件,原理是利用less等预处理器去编译成css

Vite里的postcss是什么?

  1. vite内置了postcss来对css做处理,PostCSS 是一个使用 JS 插件转换样式的工具。这些插件可以调整您的CSS、支持变量和mixins、转译未来的 CSS语法、内联图像等等
  2. 通俗地来说,postcss可以让你最初写的css经过配置的插件一系列处理,转换为你想要的css格式。
  3. vite.config.js中的配置如下:
import { defineConfig } from "vite";
const postcssPresetEnv = require('postcss-preset-env');

export default defineConfig({           
  css: {
    postcss: {              // 配置postcss,具体配置可查postcss库
      plugins: [postcssPresetEnv()]
    }
  }
})

其中postcss-preset-env是一个postcss的官方插件库,提供了一些列插件,主要的功能就是将现代 CSS 转换为大多数浏览器可以理解的内容。

但是,当使用如上配置时,若使用是模块化CSS,且有globalstyle.css设置了自定义全局属性,以供其他模块化CSS使用时,就会出现自定义属性没有被解析的问题。这里就和postcss-custom-properites这个库有关了,这个库就是postcss-preset-env插件库中的一个,负责解析自定义属性的解析功能(将自定义变量解析成为浏览器可知的具体颜色)。根据官方文档说明:模块化css自定义属性没有被解析的原因是因为每个文件都是单独处理的,因此除非在每个文件中导入自定义属性定义,否则不会解析它们。同时给出了我们解决方案:使用 PostCSS Global Data插件,他的功能是根据配置的文件列表,提供一个可以使其他的CSS模块能够访问到该文件列表的全局自定义属性的上下文。但是,这个插件却不在postcss-preset-env官方插件库里。那么怎么配置呢?

下面是在vite.config.js的配置。

// 1. 下载插件: yarn add @csstools/postcss-global-data -D
import { defineConfig } from "vite";
import path from 'path';
const postcssPresetEnv = require('postcss-preset-env');
const postcssGlobalData = require('@csstools/postcss-global-data');     // 2.引入插件

export default defineConfig({
    postcss: {            // 配置postcss,具体配置可查postcss库
      plugins: [
        postcssGlobalData({                         // 3.配置插件(一定要在postcssPresetEnv上面)
          files: [path.resolve(__dirname, 'globalstyle.css')]
        }),
        postcssPresetEnv(),
      ],
    }
  },
})

总之,Vite依托于postcss可以干很多事,有不知道的就去参考一下postcess就可以了。

参考资料汇总:

  1. 付金权的前端课
  2. postcss库
  3. postcss-custom-properties库
  4. postcss-global-data库
  5. postcss-preset-env库