Skip to content
On this page

处理样式

普通CSS

TIP

vite支持直接处理css

main.js

javascript
import './common.css'
console.log('handle style')

common.css

css
html {
    background-color: #f5f5f5;
}

处理css的流程如下

  • vite解析文件时,读取到main.js中引用到了common.css

  • 使用fs模块读取common.css的文件内容

  • 创建style标签,将common.css中的文件内容复制到style标签中,并将style标签插入到index.htmlhead标签中

  • common.css的内容替换为js脚本(方便热更新/css模块化),同时设置Content-Type为application/javascript,让浏览器以js脚本的形式来执行该css后缀的文件

经过vite处理后,最终加载请求到的common.css内容如下:

请求common.css的响应头如下:

CSS Module

TIP

  • vite默认支持css模块化

  • css文件以.module.css结尾,表明要开启css模块化

css文件命名为xxx.module.css,引入js文件中,处理CSS Module流程如下

  • vite会将xxx.module.css文件中所有类名进行替换(例如将countWrapper替换为_countWrapper_xxx)
  • 将替换过后的内容放进style标签中然后插入到index.htmlhead标签中
  • 同时会创建一个映射对象{countWrapper: '_countWrapper_xxx'}
  • xxx.module.css内容替换成js脚本,将创建的映射对象在脚本中导出

src/Count/index.js

javascript
export const num = 100;

import styles from './count.module.css'

const countDiv = document.createElement('div');
countDiv.classList.add(styles.countWrapper)

document.body.appendChild(countDiv);

// {countWrapper: '_countWrapper_2td7t_1'} 'count styles'
console.log(styles, 'count styles');

count.module.css

css
.countWrapper {
    width: 200px;
    height: 200px;
    background-color: aqua;
    font-size: 22px;
}

经过vite处理后,最终加载请求到的count.module.css内容如下:

CSS Module配置

modules中的配置最终会传给postcss-modules

typescript
interface CSSModulesOptions {
  scopeBehaviour?: 'global' | 'local'
  globalModulePaths?: RegExp[]
  generateScopedName?:
    | string
    | ((name: string, filename: string, css: string) => string)
  hashPrefix?: string
  /**
   * default: null
   */
  localsConvention?:
    | 'camelCase'
    | 'camelCaseOnly'
    | 'dashes'
    | 'dashesOnly'
    | null
}

vite.config.js

js
/**
 * @type {import('vite').UserConfig}
 */

const config = {
        css: {
            modules: {
                localsConvention: 'camelCase',
                scopeBehaviour: 'local',
                generateScopedName: "[name]__[local]___[hash:base64]",
                hashPrefix: undefined,
                globalModulePaths:  undefined
            }
        }
    }

export default config;
  • scopeBehaviour: 配置当前的模块化行为是模块化还是全局,配置成全局global后,css模块化会失效,默认是local

  • globalModulePaths: 不参与css模块化的文件名称路径

  • generateScopedName: 自定义CSS Module生成类名的规则,具体可以看这里

  • hashPrefix: 此字段会参与生成hash字符串,在generateScopedName选项中可用到此hash

  • localsConvention: 修改生成的映射对象中的key的形式,是驼峰还是中划线

Sass/Less

  • Vite本身对CSS各种预处理器语言(Sass/Scss、Less)等做了内置支持

  • 只需要安装Sass/Less,然后就可以使用Sass/Less编写样式了

shell
pnpm install -D sass
# 或者
pnpm install -D less

预处理器编译选项

  • 通过配置preprocessorOptions选项来设置sass/less编译时的配置

例如

vite.config.js

javascript
import path from "node:path";
/**
 * @type {import('vite').UserConfig}
 */

const config = {
    resolve: {
        alias: {
            '@src': path.resolve(__dirname, 'src')
        }
    },
    css: {
        modules: {
            localsConvention: 'camelCase',
            scopeBehaviour: 'local',
            // generateScopedName: "[name]__[local]___[hash:base64]",
            // hashPrefix: 'custom_prefix',
            // globalModulePaths:  null
        },
        preprocessorOptions: {
            scss: {
                //define global scss variable
                additionalData: `@import '@src/variable.scss';`
            },
            less: {
                // xxx
            }
        }
    }
}

export default config;

开启sourceMap

  • 通过配置devSourcemap选项来开启CSS sourceMap

  • 开发环境都是通过创建style标签,将处理过后css内容放入style标签然后将style标签插入到index.htmlhead标签中,当想要去调试时,很不方便,可以通过开启CSS sourceMap来方便调试

javascript
import path from "node:path";
/**
 * @type {import('vite').UserConfig}
 */

const config = {
    resolve: {
        alias: {
            '@src': path.resolve(__dirname, 'src')
        }
    },
    css: {
        modules: {
            localsConvention: 'camelCase',
            scopeBehaviour: 'local',
            // generateScopedName: "[name]__[local]___[hash:base64]",
            // hashPrefix: 'custom_prefix',
            // globalModulePaths:  null
        },
        preprocessorOptions: {
            scss: {
                //define global scss variable
                additionalData: `@import '@src/variable.scss';`
            }
        },
        devSourcemap: true, // 开启css sourceMap
    }
}

export default config;

postcss配置

  • 针对postcss有两种不同的配置方式
    1. 内联配置,格式和postcss.config.js一致,但是对于plugins选项只支持数组格式,点击这里查看说明
    2. 使用postcss-load-config插件推荐的配置方法(vite内置了postcss-load-config插件)

WARNING

如果提供了内联配置Vite将不会搜索其他PostCSS配置源

示例

例如配置浏览器兼容前缀(该示例使用内联配置)

  • 下载autoprefixer
shell
pnpm install autoprefixer -D
  • 配置vite.config.js如下
javascript
import path from "node:path";
import autoprefixer from "autoprefixer";
/**
 * @type {import('vite').UserConfig}
 */

const config = {
    resolve: {
        alias: {
            '@src': path.resolve(__dirname, 'src')
        }
    },
    css: {
        modules: {
            localsConvention: 'camelCase',
            scopeBehaviour: 'local',
            // generateScopedName: "[name]__[local]___[hash:base64]",
            // hashPrefix: 'custom_prefix',
            // globalModulePaths:  null
        },
        preprocessorOptions: {
            scss: {
                //define global scss variable
                additionalData: `@import '@src/variable.scss';`
            }
        },
        devSourcemap: true,
        postcss: {
            plugins: [autoprefixer()]
        }
    }
}

export default config;

效果如下:

其他

相关代码可查看handle-style