这是我参与【第四届青训营】笔记创作活动的第 13 天,今天学习了 Vite 的一些知识点
1. 浅谈构造工具
问题
为什么需要构建工具?
在 webpack 那篇文章中我讲到,前端工程的痛点就是难以管理资源文件,因此 webpack , vite 等工程化工具的出现,才有了 前端工程 这个概念。
1.1 前端构建工具的意义
- 模块化
- ESM、CommonJS、UMD
- 资源编译
- 高级语法的编译
- 产物质量
- 代码体积,代码性能
- 提开发效率
- 热更新
- 热更新
2. Vite 概要介绍
2.1 Vite 是什么?
🔔 定位:新一代前端构建工具
两大部分组成:
- No-bundle 开发服务,源文件无需打包
- 生产环境基于 Rollup 的 Bundler
核心特征 👉1. 高性能、dev 启动速度和热更新速度非常快! 👉2. 简单易用,开发者体验好
2.2 业界案例
- Rollup -> Vite
sveltejs
- 启动时间:2分15秒 -> 1.7秒
- 更新时间:23 秒 -> 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>
script 标签增加
type=module属性使用
ESM模块导入导出语法
2.4.2 基于原生 ESM 的开发服务优势
- 无需打包项目源代码
- 天然的按需加载
- 可以利用文件级的浏览器缓存
- Esbuild
- 基于原生语言(Go、Rust)编写前端编译工具链
- 如 Go 语言编写的 Esbuild,Rust 编写 SWC
来看下面这张图
非常非常明显:Esbuild 的速度非常快 Esbuild —— 基于 Golang 开发的前端工具,具有以下能力:
- 打包器 bundler
- 编译器 Transformer
- 压缩器 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
等价于 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
输入初始化参数
启动后的截图
可以看到,这个启动速度还是非常快的
3.2 使用 Sass / Scss & CSS Modules
项目目录
引入 Header 组件
3.3 使用静态资源
目录结构
以 svg 图片为例
除了常见的图片格式,Vite 也内置了对于 JSON、Worker、WASM 资源的加载支持
3.4 使用 HMR
无需额外配置,自动开启
3.5 生产环境 Tree Shaking
优化原理
- 基于 ESM 的
import/export语句依赖关系,与运行时状态无关 - 在构建阶段将未使用到的代码进行删除
4. Vite 整体架构
4.1 预打包
为什么要进行预打包?
- 避免
node_modules过多的文件请求 - 将
CommonJS格式转换成ESM格式
实现原理
- 服务启动前扫毛代码中用到的依赖
- 用
ESbuild对依赖代码进行预打包 - 改写
import语句,指定依赖为预构建产物路径
4.2 单文件编译
用 Esbuild 编译 TS/JSX
优势: 编译速度提供 10 - 100 X 局限性
- 不支持 类型检查
- 不支持语法降级到 ES5
4.3 代码压缩
压缩性能对比
Esbuild 作为默认压缩工具,替换传统的 Terser、Uglify.js 等压缩工具
4.4 插件机制
开发阶段: 模拟 Rollup 插件机制
生产阶段: 直接使用 Rollup
插件兼容性可以查阅:
vite-rollup-plugins.patak.dev/
5. Vite 进阶路线
5.1 深入双引擎
- esbuild
参考资料: esbuild 官方文档 rollup 官方文档
- rollup.js
5.2 插件开发
为什么需要插件机制?
- 抽离核心逻辑
- 易于扩展
通过上述的 Hook,我们可以在不同的构建阶段插入自定义的逻辑
示例
使用插件
- 开发 Vite 插件
- 配置文件引入插件
5.3 代码分隔(拆包)
问题:
- 无法进行并发请求
- 缓存复用率低
参考资料: cn.vitejs.dev/config/buil… rollupjs.org/guide/en/#o…
5.4 JS 编译工具 (Babel)
出现的原因:
- JavaScript 语法标准繁多,浏览器支持程度不一
- 开发者需要用到高级语法
原理图
5.5 语法安全降级
以 Promise 为例,IE11没有支持
参考资料: @babel/preset-env 文档
5.6 服务端渲染(SSR)
一种常见的渲染模式,用于提升首屏性能和 SEO 优化
构建阶段
代码执行阶段
5.7 深入了解底层标准
参考资料
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: 提供低版本浏览器降级支持
海量社区插件:
众多框架内置
- Nuxt
- SvelteKit
- Astro
- Vitepress
总结
本文主要针对于 Vite 的一些概念以及架构做了个简单的介绍,作为新一代的打包工具,我们可以好好了解,可以对比
webpack等工具进行对比学习