这是我参与「第五届青训营 」笔记创作活动的第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启动速度和热更新速度很快
- 简单易用,开发者体验好
传统构建工具
当前构建工具的问题和原因:
- 缓慢的热启动,项目编译等待成本高。
- 缓慢的热更新,修改代码后不能实时更新。
- 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整体架构
开发阶段和生产阶段,插件机制
依赖预打包
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
先学习基本使用,尝试各项常用配置,然后学习插件开发
插件开发
插件机制:抽离核心逻辑,易于扩展
Vite插件开发,在插件中写hook函数,在插件运行过程中运行hook,主要学习config、configResolved、resolveId、transform
代码分割(拆包)
传统前端工程只会产生1个bundle,即一个产物文件,无法进行浏览器并发请求,缓存复用率低,只要一个源文件改动,整个bundle就失效了。
拆包后,一个文件改动只会影响一个bundle,提升页面加载速度
学习Babel实现原理
语法安全降级
实现语法的安全降级,如IE11也不支持Promise:
- 上层解决方案,Vite提供了@vitejs/pligin-legacy,通过该插件实现安全的语法降级
- 底层原理是借助Babel进行语法自动降级,提前注入Ployfill实现,如core-js、regenerator-runtime
服务端渲染SSR
C端页面常用的渲染模式,用于提升首屏性能和SEO优化
构建阶段
代码执行阶段
深入了解底层标准
重点特性:
- 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)