Vite 知识体系 | 青训营笔记

97 阅读5分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 14 天

R-C.jfif

课程笔记

浅谈构建工具

在进行前端开发的过程中,我们最核心的要素就是资源,各种各样的资源包含在我们的项目当中,比如JS、TS、JSX、CSS、SCSS、PNG等等这些类型各异的资源。

所以我们在进行前端工程化时会有如下困难:

  • 模块化

    前端没有统一模块引入的规范,常见的规范有:ESModule、CommonJS、UMD、AMD等,因此需要提供兼容不同模块规范的处理方案

  • 资源编译

    目前众多的高级语法已经成为前端项目开发的标配,如TS, JSX, Vue, Less, Sass等,对于浏览器而言,只认识传统的三大件(HTML、CSS、JS),所以需要将高级语法进行编译;另外呢,静态资源如图片、字体等也需要进行加载

  • 产物质量

    随着前端项目体量增大,需要对其压缩优化,将一些未被使用到的模块进行剔除 需要对产物的兼容性进行处理,以适配更多的浏览器和客户端,进行语法降级处理

  • 开发效率

    能够大大提升开发时的效率,如给予热更新

Vite 概要介绍

Vite概览

定位:

一代的前端构建工具

两大组成部分:

  • 开发环境的 No-bundle 服务,源文件无需打包
  • 生产环境基于 Rollup 的 Bandle 处理

具备能力:

  • 打包器 - Bundle
  • 编译器 - Transfer
  • 压缩器 - Minifier

核心特征:

  • 高性能,dev 启动速度和热更新速度非常快
  • 简单易用,开发体验好

业界案例

image.png

该案例中,前端构建工具从 Rollup 转变为 Vite 之后

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

image.png

该案例中,前端构建工具从 Webpack 转变为 Vite 之后

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

当下问题

image.png

在之前的构建工具下,开发体验问题日渐显露:

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

产生这些问题的瓶颈在哪呢?

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

两大行业趋势

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

image.png

  • 基于原生语言(GO、Rust)编写前端编译工具链。

    如 GO 语言编写的Esbuild、Rust编写的SWC。

image.png

浏览器原生 ESM 支持

两大要素:

  • script 标签增加type="module"属性
  • 使用ESM模块导入导出语法

image.png

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

  • 无需打包项目源代码。
  • 天然的按需加载
  • 可以利用文件级的了浏览器缓存

image.png

基于 Esbuild 的编译性能优化

Esbuild---基于Golang开发的前端工具,具备如下能力:

  • 打包器 Bundler
  • 编译器 Transformer
  • 压缩器 Minifier

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

image.png

Vite 上手实践

项目初始化

  • Vite项目初始化命令

image.png

  • 输入初始化参数

image.png

  • 启动

image.png

启动完成后,打开浏览器访问对应地址即可。

使用 SCSS & CSS Modules

  • 目录结构

image.png

  • 引入 Header 组件

image.png

使用静态资源

  • 目录结构

image.png

  • 以 SVG 图片为例

image.png

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

生产环境 Tree Shaking

优化原理:

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

image.png

Tree Shaking 在 Vite 中无需配置,默认开启。

Vite 整体架构

关键技术:依赖预打包

为什么进行预打包?

  • 避免node_module过多的文件请求
  • 将Commonjs格式转化成ESM格式

实现原理

  • 服务启动前扫描代码中用到的依赖
  • 用Esbuild对依赖代码进行预打包
  • 改写import语句,指定依赖预构建产物路径
  • 关键技术:单文件编译

如用Esbuild编译TS/JSX

局限性

  • 不支持类型检查
  • 不支持将语法降级到ES5
  • 关键技术:代码压缩
  • Esbuild作为默认的压缩工具,替换传统的Terser, Uglify.js等压缩工具

关键技术:插件机制
开发阶段:使用了Plugin Container进行(Mock Rollup)模拟插件机制
生产环境:直接使用Rollup

Vite进阶路线

  • 深入双引擎 - Esbuild、Rollup

  • 插件开发

    • 抽离核心逻辑
    • 易于扩展
    • 不同阶段的Hooks
  • 代码分割(拆包)

    问题:

    • 无法进行并发请求
    • 缓存复用率低
  • 编译工具

    • babel
  • 语法安全降级

  • 上层解决方案,@vitejs/plugin-legacy

  • 底层实现,借助babel进行语法自动降级,提前注入Poly-fill实现,如core-js、regenerator-runtime等

  • 服务端渲染(SSR),用于提高首屏性能和SEO的优化

  • 深入底层和社区生态

总结

通过本次课程,大致对Vite构建工具有了一定的了解,从Vite安装到Vite进阶,学习到了很多的Vite知识,Vite给我最直观的印象就是响应迅速开箱即用。在今后的开发中我们可以使用Vite来快速构建我们的项目,这是我学习Vite构建工具的最大用途。