Vite 知识体系 | 青训营笔记

119 阅读5分钟

这是我参与【第四届青训营】笔记创作活动的第 13 天,今天学习了 Vite 的一些知识点

1. 浅谈构造工具

问题

为什么需要构建工具?

webpack 那篇文章中我讲到,前端工程的痛点就是难以管理资源文件,因此 webpack , vite 等工程化工具的出现,才有了 前端工程 这个概念。

1.1 前端构建工具的意义

  • 模块化
    • ESM、CommonJS、UMD
  • 资源编译
    • 高级语法的编译
  • 产物质量
    • 代码体积,代码性能
  • 提开发效率
    • 热更新 image.png

2. Vite 概要介绍

2.1 Vite 是什么?

🔔 定位:新一代前端构建工具

两大部分组成:

  1. No-bundle 开发服务,源文件无需打包
  2. 生产环境基于 Rollup 的 Bundler

核心特征 👉1. 高性能、dev 启动速度和热更新速度非常快! 👉2. 简单易用,开发者体验好 image.png

2.2 业界案例

  1. Rollup -> Vite

sveltejs

  • 启动时间:2分15秒 -> 1.7秒
  • 更新时间:23 秒 -> 1 秒以内
  1. Webpack -> Vite

Benchmarks

  • 启动时间:2分36秒 -> 6秒
  • 热更新从 13 秒 -> 1秒

2.3 当下问题

  • 缓慢的启动 => 项目编译等待成本高
  • 缓慢的热更新 => 代码修改后不能实时更新

瓶颈在哪里?

  • bundle 带来的性能开销
  • JavaScript 语言的性能瓶颈

2.4 两大行业趋势

2.4.1 浏览器原生 ESM 支持

全球浏览器对原生 ESM 的普遍支持(目前占比 92% 以上)

<body>
	<script type="module">
		import { foo } from './foo.js'
		console.log(foo)	
	</script>
</body>
  1. script 标签增加 type=module 属性

  2. 使用 ESM 模块导入导出语法

2.4.2 基于原生 ESM 的开发服务优势

  • 无需打包项目源代码
  • 天然的按需加载
  • 可以利用文件级的浏览器缓存 image.png
  1. Esbuild
  • 基于原生语言(Go、Rust)编写前端编译工具链
  • 如 Go 语言编写的 Esbuild,Rust 编写 SWC

来看下面这张图 image.png

非常非常明显:Esbuild 的速度非常快 Esbuild —— 基于 Golang 开发的前端工具,具有以下能力:

  1. 打包器 bundler
  2. 编译器 Transformer
  3. 压缩器 Minifier

性能极高,在 Vite 中被深度使用

2.4.3 内置的 Web 构建能力

Vite 开箱即用的功能等价于

  • webpack
  • webpack-dev-server
  • css-loader
  • style-loader
  • less-loader
  • sass-loader
  • postcss-loader
  • file-loader
  • MiniCssExtractPlugin
  • HTMLWebpackPlugin
  • ....

webpack.config.ts image.png

等价于 Vite.config.ts 中的

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

export default defineConfig({
	plugins: [react()]
})

3. Vite 上手实战

3.1 项目初始化

npm i -g pnpm

pnpm create vite

pnpm install

npm run dev

输入初始化参数

image.png

启动后的截图

image.png

可以看到,这个启动速度还是非常快的

3.2 使用 Sass / Scss & CSS Modules

项目目录

image.png

引入 Header 组件

image.png

3.3 使用静态资源

目录结构

image.png

以 svg 图片为例

image.png

除了常见的图片格式,Vite 也内置了对于 JSON、Worker、WASM 资源的加载支持

cn.vitejs.dev/guide/featu…

3.4 使用 HMR

无需额外配置,自动开启

3.5 生产环境 Tree Shaking

优化原理

  1. 基于 ESM 的 import/export 语句依赖关系,与运行时状态无关
  2. 在构建阶段将未使用到的代码进行删除 image.png

4. Vite 整体架构

4.1 预打包

image.png

为什么要进行预打包?

  1. 避免 node_modules 过多的文件请求
  2. CommonJS 格式转换成 ESM 格式

实现原理

  1. 服务启动前扫毛代码中用到的依赖
  2. ESbuild 对依赖代码进行预打包
  3. 改写 import 语句,指定依赖为预构建产物路径 image.png

image.png

4.2 单文件编译

用 Esbuild 编译 TS/JSX image.png

优势: 编译速度提供 10 - 100 X 局限性

  1. 不支持 类型检查
  2. 不支持语法降级到 ES5

4.3 代码压缩

image.png

压缩性能对比

image.png

Esbuild 作为默认压缩工具,替换传统的 Terser、Uglify.js 等压缩工具

4.4 插件机制

image.png

开发阶段: 模拟 Rollup 插件机制

生产阶段: 直接使用 Rollup

插件兼容性可以查阅:

vite-rollup-plugins.patak.dev/

5. Vite 进阶路线

5.1 深入双引擎

  1. esbuild

参考资料: esbuild 官方文档 rollup 官方文档

  1. rollup.js

5.2 插件开发

为什么需要插件机制?

  • 抽离核心逻辑
  • 易于扩展

image.png

通过上述的 Hook,我们可以在不同的构建阶段插入自定义的逻辑

示例 image.png

使用插件

image.png

  1. 开发 Vite 插件
  2. 配置文件引入插件

5.3 代码分隔(拆包)

image.png 问题:

  1. 无法进行并发请求
  2. 缓存复用率低

image.png

参考资料: cn.vitejs.dev/config/buil… rollupjs.org/guide/en/#o…

5.4 JS 编译工具 (Babel)

出现的原因:

  • JavaScript 语法标准繁多,浏览器支持程度不一
  • 开发者需要用到高级语法

原理图 image.png

babel 官方站点 babel 插件手册

5.5 语法安全降级

以 Promise 为例,IE11没有支持

image.png

image.png

image.png

参考资料: @babel/preset-env 文档

Vite 官方降级插件文档

5.6 服务端渲染(SSR)

一种常见的渲染模式,用于提升首屏性能和 SEO 优化

构建阶段 image.png

代码执行阶段 image.png

5.7 深入了解底层标准

image.png

参考资料

hacks.mozilla.org/2018/03/es-…

antfu.me/posts/publi… gist.github.com/sindresorhu…

5.8 社区生态

Github 40k + star

官方提供插件

@vitejs/plugin-vue: 提供 vue3 支持 @vitejs/plugin-vue-jsx: 提供 vue3 JSX 支持 @vitejs/plugin-react: 提供 React 支持 @vitejs/plugin-legacy: 提供低版本浏览器降级支持

海量社区插件:

github.com/vitejs/awes…

众多框架内置

  • Nuxt
  • SvelteKit
  • Astro
  • Vitepress

总结

本文主要针对于 Vite 的一些概念以及架构做了个简单的介绍,作为新一代的打包工具,我们可以好好了解,可以对比 webpack 等工具进行对比学习