Vite 静态资源处理

八、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.cssindex.csslink.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.cssvite/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.cssbasic.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.jsonbrowserslist字段中配置,如下:

{
  "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面板输出入下内容

在这里插入图片描述

### 实现静态资源预加载 在 Vue3 和 Vite 构建的项目中,虽然 Vite 不提供 Webpack 那样的魔法注释用于直接实现 `prefetch` 加载,但是可以通过特定的方法来模拟这一行为。对于大型路由组件,在首次访问时可能会因为资源加载而延迟显示,影响用户体验。 #### 方法一:通过 Link 标签手动设置 Prefetch 可以在 HTML 文件头部添加 `<link rel="preload">` 或者 `<link rel="prefetch">` 来指示浏览器预先下载指定文件。这种方式适用于已知未来可能使用的资源链接[^1]。 ```html <link rel="prefetch" href="/path/to/large-component.js"> ``` 这种方法简单易行,但对于动态生成的内容不太灵活。 #### 方法二:利用 Vite 插件自动处理 Public 资源 考虑到公共目录中的大量图片静态资源占用较多空间和带宽,可以借助于 Vite 的插件功能,在应用启动之初便发起这些资源的请求。这不仅限于图片,也可以扩展到其他类型的静态资产上[^2]。 创建自定义插件或寻找社区内已经存在的解决方案,比如 `vite-plugin-imagemin` 可以帮助压缩并提前获取图像数据;或是编写脚本遍历 public 文件夹内的所有项,并将其加入到构建流程之中作为待预取的目标列表。 #### 方法三:依赖预加载机制 类似于 lodash 这样第三方库被放置到了 `.vite/deps/` 下面经过特殊编译后的版本,表明 Vite 对某些模块做了额外优化以便更快地响应初次导入的需求。因此如果存在一些经常用到却相对独立的小型工具函数集合,则可以让它们也享受到类似的待遇——即成为全局共享的一部分从而减少重复传输量[^3]。 为了更高效地管理整个项目的静态资源以及确保最佳性能表现: - 定期审查哪些资源真正有必要做前置加载; - 结合实际场景调整策略(如按需懒加载较大尺寸媒体素材); - 利用服务端渲染 SSR 技术进一步缩短首屏呈现时间。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值