八、Vite 静态资源处理
Vite 作为一个开箱即用的前端构建工具,默认支持 JS、CSS、Sass、Less、JSON、图片、HTML 等静态资源的处理。
但有些情况下还是需要做额外的配置,我挑了一些比较常用的功能来做讲解:
- CSS 的默认处理行为
- CSS 模块化处理
- CSS 预处理器
- CSS 兼容性处理
- 限定大小的图片转为 Base64 编码
- JSON 的导入
- JSON 支持具名导入
1、CSS 的默认处理行为
css 文件中通过@import
导入的其它 CSS,能自动识别,被打包到当前 CSS 中。
开发环境下
- JS 文件中以
import
导入的.css
文件内容最终处理后,会插入到index.html
文件的<style>
标签中,同时自带 HMR 支持。 - 对于
<link>
标签引入的 CSS 不做处理。
生产环境下
- 通过
<link>
标签引入的 CSS 和import
导入的 CSS 打包到一个 CSS 文件中,输出在项目的dist/assets
目录下。
1.1、创建项目
项目目录结构如下
vite
├─ basic.css
├─ index.css
├─ index.html
├─ link.css
├─ main.js
├─ package-lock.json
├─ package.json
vite/index.html
文件内容
<!--
link标签引入的CSS
开发环境下不做处理
生产环境下与JS中通过import导入的css最终打包到一个CSS文件中
-->
<link rel="stylesheet" href="./link.css" />
<div class="box">box</div>
<script type="module" src="./main.js"></script>
main.js
内容
/**
* import 导入的CSS
* 开发环境下打包到index.html文件的<style>标签中,并带有HRM模块热更新
* 生产环境下与 其它CSS打包到一个CSS文件中
*/
import "./index.css";
basic.css
、index.css
、link.css
内容如下
/* index.css */
@import url("./basic.css");
.box {
width: 100px;
height: 100px;
background-color: blue;
}
/* baisc.css */
.box {
border: 10px solid yellow;
}
/* link.css */
.box {
font-size: 30px;
}
1.2、启动开发服务
执行
npx vite
启动开发服务,在浏览器查看 Elements 选项,如下:
注:
观察上图,我可以看到
<link>
标签引入的 CSS 并没有做处理- JS 文件中以
import
导入的.css
文件及内部通过@import
导入的 CSS 都被打包到一起,最终插入到index.html
文件的<style>
标签中。 - 打包后的 CSS,以持 HMR 模块热更新。如果修改任意一个 css 文件中样多,当保存时,页面也会动态更新,这就是启用了 HRM 功能。
1.3、生产打包
执行以下命令,对项目生产环境打包
npx vite build
打包后,在dist/assets
目录只生成了一个 css 文件,内容如下
.box {
font-size: 30px;
}
.box {
border: 10px solid yellow;
}
.box {
width: 100px;
height: 100px;
background-color: #00f;
}
可以看到,三个 css 文件中的内容,都打包到一个 css 文件了。
2、CSS 模块化处理
- Vite 允许我对 CSS 进行模块化处理,也就对 CSS 类名和选择器的作用域进行限定的一种方式。
- Vite 会把任何以
.module.css
为的缀名的 CSS 文件看成一个模块,并采用 CSS module 的方式来处理。
2.1、创建项目
项目目录结构如下
vite
├─ index.html
├─ basic.js
├─ basic.module.css
├─ index.js
├─ index.module.css
├─ package-lock.json
└─ package.json
vite/index.module.css
和vite/basic.module.css
文件内容如下:
/* vite/index.module.css */
.box {
width: 100px;
height: 100px;
background-color: red;
}
.item {
font-size: 20px;
}
/* vite/basic.module.css */
.box {
width: 100px;
height: 100px;
background-color: blue;
}
.wrap {
font-size: 30px;
}
vite/index.js
文件内容如下:
// 模块化加载 css
import indexModule from "./index.module.css";
// indexModule 为一个 JS 对象如:{box: '_box_m554n_1'}
console.log(indexModule);
// 创建 div元素
const div = document.createElement("div");
// 为div添加className,相当于div.className="_box_m554n_1"
div.className = indexModule.box;
// 将div插入到页面
document.body.appendChild(div);
vite/basic.js
文件内容如下:
// 模块化加载 css
import basicModule from "./basic.module.css";
//basicModule 一个JS对象如:{box: '_box_vp3a0_1'}
console.log(basicModule);
// 创建 div元素
const div = document.createElement("div");
// 相当于div.className="_box_vp3a0_1"
div.className = basicModule.box;
// 创建 div元素
document.body.appendChild(div);
vite/index.html
文件内容如下:
<div class="box">box</div>
<script type="module" src="./index.js"></script>
<script type="module" src="./basic.js"></script>
2.2、启动开发服务
TIP
执行npx vite
启动开发服务,在浏览器中打开。
最终显示如下效果
注:
观察以上截图,我可以看到,最终index.module.css
和basic.module.css
文件中的 CSS 选择器上都加上了一串 hash 值,用来表示当前选择器的唯一性,这样就避免了相同的样式发生覆盖
生产环境下打包,最终所有 CSS 样式会打包成一个 CSS 文件,内容如下
._box_1vf94_1 {
width: 100px;
height: 100px;
background-color: red;
}
._item_1vf94_11 {
font-size: 20px;
}
._box_1nhxq_1 {
width: 100px;
height: 100px;
background-color: #00f;
}
._wrap_1nhxq_11 {
font-size: 30px;
}
温馨提示
Vue 的单文件组件中,只需要在<style>
标签上写上scoped
,Vite 就会自动把 Syle 标签中的样式当成模块处理。
<script></script>
<template></template>
<style scoped>
.box {
}
</style>
3、CSS 预处理器
Vite 默认是支持.scss
、.sass
、.less
、.stylus
结尾的文件,但必需要安装相应的预处理器依赖。
.scss
和.sass
对应的预处理器依赖包为 sass.less
对应的的预处理器依赖包为 less 包.stylus
对应的的预处理器依赖包为 stylus 包
项目目录结构如下:
vite
├─ index.html
├─ index.scss
├─ package-lock.json
└─ package.json
vite/index.html
文件内容
<link rel="stylesheet" href="./index.scss" />
<div class="box">
<p>box h3</p>
</div>
vite/index.scss
文件内容
.box {
p {
background-color: skyblue;
font-size: 30px;
}
}
- 执行以下命令,安装预处理器依赖的 sass 包
npm i sass -D
执行npx vite
命令,在浏览器查看对的效果,并观察控 NetWork 面板,如下
npx vite build
命令后,在dist/assets
目录下生成了对应的 css 文件,内容如下:
.box p {
background-color: #87ceeb;
font-size: 30px;
}
4、CSS 兼容性处理
如果我想要 CSS 能兼容不同的浏览器,那我就需要为相关的 CSS 属性添加兼容性前缀。我自己去书写每个 CSS 前缀太麻烦了,所以我可以利用 PostCSS 来帮我处理。
- Vite 内置了 PostCSS,我只需要安装相关的 PostCSS 插件,并做好相关的 PostCSS 配置就可以了。
- autoprefixer 插件 (opens new window),是专门用来处理 CSS 兼容性的插件。我只需要安装这个插件,并配置好就可以。
代码演示
在上面项目的基础上,修改vite/index.scss
文件内容如下
.box {
display: flex;
width: 100px;
height: 100px;
background-color: red;
p {
background-color: skyblue;
font-size: 30px;
}
}
执行以下命令,安装autoprefixer
插件
npm i autoprefixer@10.4.14 --save-dev
在vite.config.js
文件的css.postcss
选项中来配置这个插件
// 导入插件
import autoprefixer from "autoprefixer";
export default {
css: {
postcss: {
// 配置postcss插件
plugins: [
autoprefixer({
// 指定兼容 99.5%的浏览器。
browsers: ["cover 99.5%"],
}),
],
},
},
};
执行
npx vite
启动开发服务,在浏览器中看到如下效果,最终 css 中的 display 属性值被加上了浏览器兼容型前缀
执行
npx vite build
,在dist/assets
目录输出了对应的 css 文件内容下,css 代码添加了浏览器兼容性前缀处理。
.box {
display: -webkit-box;
display: -webkit-flex;
display: -moz-box;
display: -ms-flexbox;
display: flex;
width: 100px;
height: 100px;
background-color: red;
}
为了与 JS 保持相同的浏览器兼容处理,最好把对浏览器支持的 browsers 配置,从 postcss 的插件配置中去掉,改写在
package.json
的browserslist
字段中配置,如下:
{
"devDependencies": {},
"browserslist": ["cover 99.5%"]
}
5、图片转为 base64 编码
如果想要在生产环境下打包时,针对一定大小的图片转成 Base64 编码,只需要在vite.config.js
中添加如下配置即可
import { defineConfig } from "vite";
export default defineConfig({
build: {
// 10kb以下,转Base64
assetsInlineLimit: 1024 * 10,
},
});
代码演示
index.html
文件内容
<!--以下图片为15kb大小-->
<img src="./app.jpg" alt="" />
<!-- 以下图片大小为9kb-->
<img src="./logo.png" alt="" />
- 配置文件内容同上,然后执行
npx vite build
打包,在dist/assets
目录下只生成了app-8cce9ece.jpg
这一个图片。 - 查看打包后生成的
index.html
文件,发现logo.png
被转成了Base64
编码。 - 浏览器中查看效果如下:
6、JSON 文件处理
JSON 可以被直接导入 —— 同样支持具名导入
- 新建
index.js
文件内容如下
// 导入整个JSON,最终json为JSON对象
import json from "./data.json";
console.log(json);
// 对一个根字段使用具名导入 —— 有效帮助 treeshaking!
import { data } from "./data.json";
console.log(data);
- 新建
data.json
文件,内容如下
{
"code": "0000",
"data": [
{
"category_id": 1001,
"title": "人气 TOP"
},
{
"category_id": 1002,
"title": "爆款套餐"
},
{
"category_id": 1003,
"title": "咖啡"
},
{
"category_id": 1004,
"title": "奶茶"
},
{
"category_id": 1005,
"title": "甜品小点"
}
],
"message": "成功"
}
- 新建
index.html
内容如下
<script type="module" src="./index.js"></script>
- 执行
npx vite
启动应用,在浏览器中打开服务,Console
面板输出入下内容