这是我参与「第四届青训营」笔记创作活动的的第 15 天
为什么需要前端构建工具
前端模块化
- 提供一个统一的模块方案
- 兼容不同的模块规范
语法转译
- 高级语法转译。如果 sass、TypeScript
- 资源加载,如图片、字体、worker
产物质量
产物压缩、无用代码删除、语法降级
开发效率
支持热更新
Vite 是什么
Vite 是新一袋的前端构建工具。
Vite 的两大组成部分
- no-bundle 开发服务,源文件不需要打包即可在开发环境中使用。这也是 Vite 与传统的前端构建工具最大的区别。
- 生产环境时基于 Rollup 的 Bundler
Vite 的核心特征
- 高性能,dev server 启动速度和热更新的速度非常快。因为 Vite 不需要打包,所以在启动和热更新时速度都提升了很多。
- 简单易用,开发者体验好。
前端构建工具当前的问题
启动缓慢:项目编译的等待成本高
热更新缓慢:修改代码之后不能实时更新
这两个问题的瓶颈主要在于:
- bundle 带来的性能开销。即在开发的过程中也进行项目的打包。
- JavaScript 语言本身的性能瓶颈。
Vite 如何解决问题
无 bundle 方案
由于现代浏览器基本都支持 ESM,因此 Vite 直接将源文件作为 ESM 提供给浏览器使用。这样的方案有下面几点好处:
- 无需打包项目源代码
- 天然的按需加载
- 可以利用文件级别的浏览器缓存
编译性能优化
Vite 深度利用了 esbuild,因此获得了 esbuild 同样的高性能。esbuild 是基于 Go 开发的前端工具,具有以下能力:
- 打包器 Bundler
- 编译器 Transformer
- 压缩器 Minifier
使用 Vite
通过 pnpm create vite
来创建一个 Vite 项目,cli 会询问你的需求来安装对应的依赖并生成配置文件。
CSS Modules
Vite 会自动转换 CSS Modules,可以在代码中引入 CSS Modules 来使用样式。
静态资源
在 Vite 中,静态资源也可以直接引入使用。
HMR
HMR 即模块热替换,即在开发环境中,如果某个模块的内容有变更,则只替换这个模块的内容,且其他部分的状态不受影响。HMR 在 Vite 中是默认开启的,无需任何额外配置。
Tree Shaking
Vite 的 Tree Shaking 是基于 ESM 的 import/export 语句依赖关系的静态分析,与运行时的状态无关。
因此在构建阶段就会将没有使用到的代码删除,不会被打包进最终的产物代码中。
Tree Shaking 在 Vite 中也是默认开启的,无需配置。
Vite 整体架构
预打包
为什么要进行预打包
- 避免 node_modules 过多的文件请求
- 将 CommonJS 的格式转换为 ESM 的格式
实现原理
- 服务启动前扫描代码中用到的依赖
- 使用 esbuild 对依赖代码进行预打包
- 改写 import 语句,指定依赖为预构建产物的路径
单文件编译
Vite 使用 esbuild 编译 TS/JSX
优势
Vite 的编译速度提升 10-100x
局限性
不支持 TypeScript 类型检查
不支持将语法降级到 ES5
代码压缩
Vite 使用 esbuild 作为默认压缩工具,替换了传统的 Terser、Uglify.js 等工具。
插件机制
Vite 由于在开发环境中使用的不是 Rollup,因此 Vite 有一个 Plugin Container 来模式 Rollup 插件机制,使得 Vite 可以支持一些 Rollup 插件。而在生产环境,Vite 直接使用 Rollup。