一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第1天,点击查看活动详情。
正文
直观上的“两快”
- 服务起的快
- 文件热更新快
Vite 简介
尤大在微博上推广时对 Vite 做的简短介绍:
Vite,一个基于浏览器原生 ES imports 的开发服务器。利用浏览器去解析 imports,在服务器端按需编译返回,完全跳过了打包这个概念,服务器随起随用。同时不仅有 Vue 文件支持,还搞定了热更新,而且热更新的速度不会随着模块增多而变慢。针对生产环境则可以把同一份代码用 Rollup 打包。虽然现在还比较粗糙,但这个方向我觉得是有潜力的,做得好可以彻底解决改一行代码等半天热更新的问题。
传统构建模式(webpack:你直接说我名字得了)
vite 构建模式
目的:彻底解决改一行代码等半天热更新的问题,提高开发者的开发效率和幸福感。
不同环境的技术核心点
开发环境:esm + esbuild
生产环境:rollup
开发环境的两大核心
源码:以原生 ESM 方式提供源码
依赖:使用 esbuild 预构建依赖
ESM
ESM:原生模块功能(通俗点就是 import 和 export 这对海尔兄弟),现代浏览器都有了很好的支持(ie:都看我干嘛,我是传统浏览器科代表)
- 添加
type="module"表示这是个js原生模块,<script type="module"></script> - 引入一个模块,会发起服务请求,所以在本地测试引入如
file://路径文件的时候将会遇到CORS错误 - 只支持相对路径和绝对路径,不支持裸模块
esbuild
esbuild 构建速度比较
esbuild 是什么?
esbuild 是一个新的模块打包工具,它提供了与 Webpack、Rollup、Parcel 等工具**「相似」**的资源打包能力。
在 vite 中起什么作用
vite 默认开发过程中使用的浏览器是现代浏览器,是能在 script 标签上支持原生 ESM 和原生 ESM 动态导入的,但实际上的文件形式是多种多样的。
作用:
- 将作为
CommonJS或UMD发布的依赖项转换为ESM导出 - 将有许多内部模块的
ESM依赖关系转换为单个模块,以提高后续页面加载性能,例如:lodash-es
凭什么这么快?
语言优势
大部分前端打包工具都是用的 js 编写的,而 esbuild 选择用 go 编写。
1. `js` 是一门解释型语言,`go` 是一门编译型语言。编译型语言较解释型语言的最大优势就是执行速度
2. `js` 是一门单线程语言,而 `go` 天生具有多线程运行能力,会尽可能饱和的运用多核,更高效的内存使用率,也就意味着更高的运行性能
设计
- 完全重写整套编译流程所需要用到的所有工具!这意味着它重写了
js、ts、jsx、css 、json、图片等资源文件的加载、解析、链接、代码生成逻辑,从源头上就处理了性能问题 - 与
webpack的loade相似的加载器,针对性的对单一文件进行编译
vite 项目初始化配置
前置条件:node 版本 >= 12.0.0
聊聊 vite 在开发环境是怎么工作的
根据上面所说的,vite 想在开发环境使用 esm 模式开发,需要解决的五大痛点:
- 解决请求
es模块CORS问题 - 第三方库有的是以
CommonJS或UMD发布的,需要统一第三方库以esm方式导出 - 解决裸模块引入问题
- 处理类似
.vue等浏览器和esbuild都不支持解析的文件 - 文件热更新问题
针对性解决方案:
- 在本地启动一个
http服务,实现对浏览器请求的响应 - 服务启动前,会先将
package.json中的dependencies的依赖通过esbuild以esm的形式导出缓存在node_modules/.vite中。在请求拦截中分析请求内容,如果是裸模块或者.vue这种浏览器不认识的文件类型,则会重写导入,如/node_modules/.vite/vue.js?v=796112c2,如果是默认不支持的文件,则通过编译插件进行解析返回。 - 文件热更新问题主要分两点,文件监听和服务推送。先创建一个
websocket服务端,在transformIndexHtml解析html入口文件的时候将client路径注入进去,用来创建客户端的websocket,接收服务端推送。vite使用chokidar来监听文件变化,当监听到change的时候调用handleHMRUpdate通知客户端文件更新了,然后在client里判断是刷新页面还是更新组件。
至此,开发环境大概流程就清晰了许多,总结一下:
一切起源于一个远古操作:npm run dev,执行了 vite 命令,先在本地启动一个服务,启动后将依赖通过 esbuild 以 esm 的形式导出、缓存,在创建服务的时候同时在服务端创建了一个 websocket 服务,使用 chokidar 监听文件变化,然后在 index.html 注入客户端的 websocket 用来接收服务端的推送来判断刷新页面还是更新文件。
vite 的利与弊
利:
- 极大提升了开发效率和幸福感
- 上手简单,无需学习一堆复杂的配置项
- 与
Rollup极其接近的插件接口,意味着可以复用Rollup生态中大部分已经被反复锤炼的工具 - 开发效率提高了,课后学习(摸鱼)时间也就多了
弊:
- 启动服务的时间极限缩短了,思考(摸鱼)时间段也没有了,成也萧何败也萧何
- 对于
webpack重度用户 && 未使用过rollup用户,内心os:好不容易达到webpack大师段位,这会儿跟我说改rollup?
结语:那是用 webpack 还是 vite?.
总结
此次就分享了 vite 在开发阶段的工作流程和原理,未涉及 ssr 项目, rollup、vite 插件的开发和使用,架构迁移,项目升级。
关注度比较高的三个构建工具比较:深度分析前端构建工具:Vite2 v.s Snowpack3 v.s. Webpack5
学识有限,还请见谅,不足/错误之处欢迎在评论区讨论~