1. vite中对css以及css模块化的简单处理.
vite 天生就支持对css文件的直接处理:
- vite在读取到main.js 中引用到了index.css;
- 直接去使用fs模块去读取index.css中文件内容;
- 直接创建一个style标签, 将index.css中文件内容直接copy进style标签里.
- 将style标签插入到index.html中的head中.
- 将该css文件中的内容直接替换为js脚本(方便热更新或者css模块化),同时设置Content-Type为js, 从而让浏览器以JS脚本的形式来执行该css后缀的文件.
场景:
- 一个组件最外层的元素类名一般取名为: wrapper.
- 一个组件最底层的元素类名一般取名: .footer.
你取了footer这个名字,别人因为没有看过你这个组件的源代码,也可能去去取名footer这个类名.
最终可能会导致样式被覆盖(因为类名重复),这就是我们在协同开发的时候很容易出现的问题.
cssmodule就是来解决这个问题的.
大概说一下原理:
全部都是基于node:
- module.css(module是一种约定,表示需要开启css模块化).
- 他会将你的所有类名进行一定规则的替换(将footer 替换成 _footer_i22st_1)
- 同时创建一个映像对象{ footer: “_footer_i22st_1” }.
- 将替换过后的内容塞进style标签里然后放入到head标签中.
- 将componentA.moudle.css内容进行全部抹除,替换成JS脚本.
- 将创建的映射对象在脚本中进行默认导出.
less(预处理器): less给我们提供了一些方便且非常实用的方法.
二. vite配置文件中css配置流程(modules篇).
在vite.config.js 中我们通过css属性去控制整个vite对于css的处理行为.
- localConvention: 修改生成的配置对象的key的展示形式(驼峰还是中划线形式).
- scopeBehaviour: 配置当前的模块化行为是模块化还是全局化,(有hash 就是开启了模块化的一个标志,因为他可以保证产生不同的hash值来控制我们的样式类名不被覆盖).
- generateScopedName: 生成的类名的规则(可以配置为函数,也可以配置成字符串规则: https://github.com/webpack/loader-utils#interploatename).
- hashPrefix: 生成hash会根据你的类名 + 一些其他字符串(文件名 + 他内部随机生成一个字符串)去进行生成, 如果你想要生成hash 更加的独特一点,你可以配置hashPrefix, 你配置的这个字符串会参与到最终的hash生成, (hash: 只要你的字符串有一个字不一样,那么生成的hash就完全不一样,但是只要你的字符串完全一样,生成的hash就会一样).
- globalModulePaths: [ ] , // 数组中写不想参与模块化的文件的路径.
import { defineConfig } from 'vite';
export default defineConfig({
optimizeDeps: [],
envPrefix: 'ENV_',
css: { // 对css的行为进行配置
// modules配置最终会丢给postcss modules
modules: { // 是对css模块化的默认行为进行配置
localsConvention: "camelCaseOnly", // 修改生成的配置对象的key的展示形式(驼峰还是中划线形式).
scopeBehaviour: 'local',// 配置当前的模块化行为是模块化还是全局化(有hash就是开启了模块化的一个标志,因为他可以保证产生不同的hash值来控制我们的样式类名不被覆盖)
generateScopedName: "[name]_[local]_[hash:5]",
// generateScopedName: (name, filename, css) => {
// // name -> 代表的是你此刻css文件中的类名
// // filename -> 是你当前css文件的绝对路径
// // css -> 给的就是你当前样式
// // 配置成函数以后,返回值就决定了他最终显示的类型.
// // return `${name}_${Math.random}.toString(36).substr(3, 8)`;
// }
hashPrefix: 'hello',
globalModulePaths: ['./xxxxxxx.module.css'], //代表你不想参与到css模块化的路径
}
}
})
三. vite配置文件中css配置流程(preprocessorOptions)
主要是用来配置css预处理的一些全局参数.
假设没有使用构建工具,我们又想去编译less文件的话.
yarn add less # lessc的编译器
你只要安装了node, 你就可以使用node index.js
你只要安装了less, 你就可以使用lessc去编译less文件.
less是可以定义变量的.
sourceMap
文件之间的索引:
假设我们的代码被压缩或者被编译过了, 这个时候假设程序出错, 他将不会产生正确的错误位置信息, 如果设置了sourceMap: true, 他就会有一个索引文件map.
eg:
import { defineConfig } from 'vite';
export default defineConfig({
optimizeDeps: [],
envPrefix: 'ENV_',
css: { // 对css的行为进行配置
// modules配置最终会丢给postcss modules
modules: { // 是对css模块化的默认行为进行配置
localsConvention: "camelCaseOnly", // 修改生成的配置对象的key的展示形式(驼峰还是中划线形式).
scopeBehaviour: 'local',// 配置当前的模块化行为是模块化还是全局化(有hash就是开启了模块化的一个标志,因为他可以保证产生不同的hash值来控制我们的样式类名不被覆盖)
generateScopedName: "[name]_[local]_[hash:5]",
// generateScopedName: (name, filename, css) => {
// // name -> 代表的是你此刻css文件中的类名
// // filename -> 是你当前css文件的绝对路径
// // css -> 给的就是你当前样式
// // 配置成函数以后,返回值就决定了他最终显示的类型.
// // return `${name}_${Math.random}.toString(36).substr(3, 8)`;
// }
hashPrefix: 'hello',
globalModulePaths: ['./xxxxxxx.module.css'], //代表你不想参与到css模块化的路径
},
preprocessorOptions: { // key + config key代表预处理器的名
less: { // 整个的配置对象都会最终给到less的执行参数(全局参数)中去
// 在webpack 里就给less-loader去配置就好了.
math: 'always',
globalVars: { // 全局变量
mainColor: 'red',
},
}
},
devSourcemap: true, // 开启css的sourceMap(文件索引).
}
})
三. postcss的前世今生
postcss 他的工作基本和全屋净水系统一致: 保证css在执行起来是万无一失的.
都对postcss有一个误区: 他们认为postcss和less sass是差不多的.
我们写的css代码(怎么爽怎么来)—> postcss —> 【去将语法进行编译(嵌套语法,函数,变量)成原生css】less sass 等预处理器都可以做 —> 再次对未来的高级css语法进行降级 —> 前缀补全 —> 浏览器客户端.
目前来说, less 和 sass 等一系列预处理器的postcss插件已经停止维护了 , less插件 需要我们自己去用less和sass编译完了,然后把编译结果交给postcss.
所以业内就产生了一个新的说法: postcss是后处理器 : less的postcss的插件就ok了.
babel --> 帮助我们让js 执行起来万无一失.
我们写的js代码(怎么爽怎么来) --> babel --> 将最新的ts语法进行转换js语法 --> 做一次语法降级 --> 浏览器客户端去执行.
使用postcss
- 安装依赖
yarn add postcss-cli postcss -D
- 书写描述文件:
- postcss.config.js
// 就类似于全屋净水系统的加插槽.
// 预设环境里面会包含很多的插件
// 语法降级 --> postcss-low-level
// 编译插件 --> postcss-compiler
const postcssPresetEnv = require('postcss-preset-env');
// 预设就是帮你一次性的帮你把这些必要的插件都给你安装上.
// 做语法的编译 less语法 sass语法 (语法嵌套 函数 变量) postcss的插件 -->
module.exports = {
plugins: [postcssPresetEnv(/*pluginOptions*/)]
}
四. vite配置文件中css配置流程(postcss篇)
直接在css.postcss 中进行配置,该属性直接配置就是postcss的配置.
- postcss-preset-env: 支持css变量和一些未来css语法 自动补全(autoprefixer).
import { defineConfig } from 'vite';
const postcssPresetEnv = require('postcss-preset-env'); // 引入预设
export default defineConfig({
optimizeDeps: [],
envPrefix: 'ENV_',
css: { // 对css的行为进行配置
// modules配置最终会丢给postcss modules
modules: { // 是对css模块化的默认行为进行配置
localsConvention: "camelCaseOnly", // 修改生成的配置对象的key的展示形式(驼峰还是中划线形式).
scopeBehaviour: 'local',// 配置当前的模块化行为是模块化还是全局化(有hash就是开启了模块化的一个标志,因为他可以保证产生不同的hash值来控制我们的样式类名不被覆盖)
generateScopedName: "[name]_[local]_[hash:5]",
// generateScopedName: (name, filename, css) => {
// // name -> 代表的是你此刻css文件中的类名
// // filename -> 是你当前css文件的绝对路径
// // css -> 给的就是你当前样式
// // 配置成函数以后,返回值就决定了他最终显示的类型.
// // return `${name}_${Math.random}.toString(36).substr(3, 8)`;
// }
hashPrefix: 'hello',
globalModulePaths: ['./xxxxxxx.module.css'], //代表你不想参与到css模块化的路径
},
preprocessorOptions: { // key + config key代表预处理器的名
less: { // 整个的配置对象都会最终给到less的执行参数(全局参数)中去
// 在webpack 里就给less-loader去配置就好了.
math: 'always',
globalVars: { // 全局变量
mainColor: 'red',
},
}
},
devSourcemap: true, // 开启css的sourceMap(文件索引).
postcss: { // 书写postcss规范
plugins: [postcssPresetEnv()]
}
}
})