Vite知识体系 | 青训营笔记

92 阅读6分钟

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

一、本堂课的重点内容

  • 构建工具
  • Vite概要介绍
  • Vite上手实战
  • Vite整体架构
  • Vite进阶路线

二、详细知识点介绍

构建工具

前端项目的组成部分:核心要素是资源

  • 逻辑代码:js ts jsx
  • 样式代码:css scss less
  • 静态资源:png jpg webp

当前前端工程化面临的问题:

  • 模块化,python、go等语言都有标准的模块化规范,js没有统一的规范。当前JS主要的模块化规范有ESM、CommonJS、UMD,至今未能实现统一
  • 资源编译,当前的前端工程内存在很多高级语法,浏览器不支持,需要编译为浏览器可识别的语法,需要一系列工具链,各种工具链的集成也成为刚需。浏览器的标准赶不上前端开发者的“脑洞”,各种高级语法,各种语法糖来提升开发效率,但浏览器不支持
  • 产物质量,线上的代码需要压缩,提高线上性能,不需要的产物需要删掉。多端兼容性问题,需要兼容到Android4.4和iOS9
  • 开发效率,需要支持热更新,修改代码后能立刻看到效果

构建工具解决上述问题:

  • 模块化,构建工具提供统一模块加载方案,兼容不同模块规范
  • 语法转译,构建工具会集成一系列编译工具链,如Sass,TS相关编译工具。静态资源加载工具,图片、字体、Worker
  • 产物质量,构建工具可以进行产物压缩和无用代码删除,语法降级,实现浏览器兼容
  • 开发效率,构建工具提供热更新系统

Vite概要介绍

Vite是新一代前端构建工具,有2大组成部分:

  • 开发阶段的No-bundle开发服务,相当于Nodejs的dev server,项目的源文件无需打包,是与传统构建工具最大的不同
  • 生产环境基于Rollup的Bundler,将所有业务代码打包,Vite对Rollup的构建场景进行了深度的定制和优化

Vite的核心特征:

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

image.png

传统构建工具

当前构建工具的问题和原因:

  • 缓慢的热启动,项目编译等待成本高。
  • 缓慢的热更新,修改代码后不能实时更新。
  • bundle带来的性能开销大,在开发过程中有bundle过程,比较消耗性能
  • JS语言的性能瓶颈,本身单线程,性能优化手段少

行业内解决这些问题的趋势:

  • 全球浏览器对原生ESM的普遍支持,占比92%以上,且IE老版本浏览器已经被彻底淘汰
    • script标签增加了type="module"属性
    • 使用ESM模块导入到处语法
    • Vite的dev server就是用了此原理,浏览器加载type为module属性的标签后请求Vite dev server,直接返回模块文件,而无需打包项目源代码,去除了Bundle的开销。实现天然的按需加载,可以利用文件级的浏览器缓存
  • 基于原生语言(Go,Rust)编写的前端编译工具链,如Go编写的Esbuild、Rust编写的SWC(对标Babel,速度达到Babel的几十倍)等,及其衍生出的一系列工具链
    • Vite深度利用了Esbuild,性能极高
    • Esbuild是基于Golang开发的前端工具,包含打包器Bundler对标Webpack、编译器Transformer对标babel、压缩器Minifier对标uglifyJS

Vite整体架构

image.png

开发阶段和生产阶段,插件机制

依赖预打包

load modules是不可控的,里面可能夹杂各种文件请求,文件请求数量很大;load modules的文件格式多种多样,可能有CommonJS格式,浏览器不识别

Vite进行依赖预打包,在dev server扫描代码中的依赖,对于依赖的代码采用Esbuild进行打包,改写业务代码中的import语句。

单文件编译

也通过Esbuild进行编译TS/TSX,但Esbuild不支持类型检查,需要先调用一次tsc,而且不支持降级到ES5,只能降到ES6。

代码压缩

代码压缩是非常耗时的阶段,Vite中用Esbuild作为默认压缩工具,替换传统的Terser,uglify.js等压缩工具。

插件机制

Dev阶段Vite提供了Plugin Container机制,用来模拟Rollup的插件机制,最终可以在开发阶段和生产环境阶段使用。

Vite进阶路线

双引擎

双引擎:Esbuild和Rollup

先学习基本使用,尝试各项常用配置,然后学习插件开发

插件开发

插件机制:抽离核心逻辑,易于扩展

image.png

Vite插件开发,在插件中写hook函数,在插件运行过程中运行hook,主要学习config、configResolved、resolveId、transform

代码分割(拆包)

传统前端工程只会产生1个bundle,即一个产物文件,无法进行浏览器并发请求,缓存复用率低,只要一个源文件改动,整个bundle就失效了。

image.png

拆包后,一个文件改动只会影响一个bundle,提升页面加载速度

image.png

学习Babel实现原理

语法安全降级

实现语法的安全降级,如IE11也不支持Promise:

  • 上层解决方案,Vite提供了@vitejs/pligin-legacy,通过该插件实现安全的语法降级
  • 底层原理是借助Babel进行语法自动降级,提前注入Ployfill实现,如core-js、regenerator-runtime

服务端渲染SSR

C端页面常用的渲染模式,用于提升首屏性能和SEO优化

image.png

构建阶段

image.png

代码执行阶段

深入了解底层标准

重点特性:

  • CJS规范
  • ESM规范,基本实现大一统趋势
  • HTTP 2.0特性

三、实践练习例子

浏览器对原生ESM支持

<script type="module">
    import {foo} from './foo.js'
    console.log(foo)
</script>

Vite使用方法

Vite项目初始化

npm i -g pnpm
pnpm create vite
pnpm install
npm run dev

优化原理,生产环境下的Tree Shaking:

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

Tree Shaking只能用于ESM,在Vite中无需配置,默认开启

四、课后个人总结

本节课学习了Vite的知识体系,Vite是新一代的前端工程打包管理工具,相对于传统工具如Webpack,Vite极大提高了效率,得益于Vite使用了众多高效的原生编译和打包工具。本节课学习了Vite的使用和架构,整体上说与Webpack差距不大,之前学习了Webpack,对本节课的理解有很大帮助,Vite比Webpack更加简洁,希望以后继续深入学习。

五、参考链接

‍⁡‍‬​‍‌⁡⁡​⁣​⁡⁣​‍⁡‌‬⁣⁢​​⁤⁣​‌‌⁡‬​⁣⁤‬​‌⁣⁢⁡‍‍‬‍⁤⁣⁢⁡Vite 知识体系.pptx - 飞书云文档 (feishu.cn)