Vite 在21 ~ 22年在前端界可谓风生水起,颠覆传统也不为过。
20年4月,尤雨溪发推说:“我感觉我再也回不到Webpack了”,Webpack作者用中文直呼:大哥… 在22年的今天,我们再看这个Twitter是不是感觉这声 “大哥” 喊得歇斯底里 😂。
到底Vite有什么魔力,可以让全世界的前端开发者们争先恐后的投入怀抱呢?
如果只说一个特点,那就是 “快”,不是传统概念的那种快个百分之多少,是tm的几十倍几百倍的快!
什么概念呢,Vite 可以让你的项目甭管多大,1秒内启动;热更新更是快的离谱,几乎是保存的一瞬间就看到效果。说实话,第一次尝试的时候,我惊呆了,我从来没见过这样的速度,从来没体会过这样的开发体验,这个世界上还有这种东西,我感觉我也回不去了。
在技术研发团队中,有一个数字需要知道,每节省40分钟(8小时/21天),一年将会多出一个月。
一个 Vite 的引入,对于一些重型项目,尤其是对于那些非内存文件编译的项目,每天节省40分钟都算是比较保守的估算(一次热更新5秒,一次冷启动3分钟)。其次,对于开发者来说,每次等待编译思路的中断都是相当大的精力损耗。
Ps. 如果你们团队超过12个人,引入 Vite 可能就意味着团队里面多了一位开发者,一个在平均水平的开发者。
快的原理
YY完之后,咱们还是得考虑些实在的问题,这东西为什么快,它是不是还是个玩具,引入到咱们这样的大公司会不会出问题,会不会对咱们工作流程会不会有很大的冲击。
实际上,关于Vite的原理说简单也简单,说复杂也复杂,要真正理解还是要回顾下前端编译史的衍变过程:
- 无编译,直接运行(jQuery)
- 简单混淆、加密、兼容性补全编译
- Webpack模式编译(React、Vue等自创性语法,Coffee,Sass\Less,TypeScript,Pug\Jade,多端)
- 局部编译,工程化拆分
- Native ESM 浅编译、不编译
所以为什么Vite快,我简单总结一下如下:
- 浏览器已经长大了,可以自己处理ES Module了,大家就别费劲转成一根筋的Bundle了
- 对于一些源码项目(src下的)大多用了些DSL,根据文件后缀做个简单转换,这个过程非常快
- 对于Deps,大多都是些处理好的CJS,直接上大哥 esbuild 10 ~ 200倍的编译速度,在上点文件缓存,还不给它整的服服帖帖
当然更多信息请参考官方文档《为什么选Vite》:
当冷启动开发服务器时,基于打包器的方式启动必须优先抓取并构建你的整个应用,然后才能提供服务。
Vite 通过在一开始将应用中的模块区分为 依赖 和 源码 两类,改进了开发服务器启动时间。
- 依赖 大多为在开发时不会变动的纯 JavaScript。一些较大的依赖(例如有上百个模块的组件库)处理的代价也很高。依赖也通常会存在多种模块化格式(例如 ESM 或者 CommonJS)。Vite 将会使用 esbuild 预构建依赖。esbuild 使用 Go 编写,并且比以 JavaScript 编写的打包器预构建依赖快 10-100 倍。
- 源码 通常包含一些并非直接是 JavaScript 的文件,需要转换(例如 JSX,CSS 或者 Vue/Svelte 组件),时常会被编辑。同时,并不是所有的源码都需要同时被加载(例如基于路由拆分的代码模块)。Vite 以 原生 ESM 方式提供源码。这实际上是让浏览器接管了打包程序的部分工作:Vite 只需要在浏览器请求源码时进行转换并按需提供源码。根据情景动态导入代码,即只在当前屏幕上实际使用时才会被处理。
如何落地?
“知其然还知其所以然”之后,回归现状,看看手里头有些什么,可以从哪个地方入手把它逐步引进来。
首先,借助我们之前在团队内部推行的一套的微前端加载方案:《如何接”地气”地接入微前端?》。目前,我们已经收敛了了一套统一的页面编译规范和方法。
也就是说对于绝大多数的业务项目来说,项目中没有任何关于编译的配置。这样的话我们可以便捷的针对该场景下的产物做一层适配,使得我们开发者可以从原来的lzd start
换为lzd vite
,无缝启动原来的项目。
针对产物,我们之前的页面内容将会被编译成为一个标准的微前端子应用,然后通过加载器来加载对应页面内容,而加载器则是消费一个 UMD规范
的产物。
为了让整个流程符合Native ESM
的消费路径,我们简单处理了一个Vite 转发插件,使得加载器加载到的JS是一份符合UMD规范
的静态JS,然后再由这段静态JS创建一个<script type='module'>
完成Vite消费路径,顺便加了些热更新的适配,可以让我们代理模式下也能享受Vite的热更新。
就这样花了一下午的时间,我们简单粗暴的完成了Vite的适配,愉快的享受在了电脑风扇不在呼呼呼、按下cmd + s
就能看到效果的幸福时光里。
生产环境
那么如此简单粗暴的做法显然不适合在生产环境里面使用。实际上对于业务项目,我们一开始也没有打算使用Vite去做生产环境的产物构建,对于技术选型还得从消费场景来看。
针对生产环境中的兼容性、稳定性、包大小等要求,使得我们对Vite使用Rollup
的产物还是没有十足的把握。
实际上在Vite的实现中对于开发态和生产态的编译流程本身也有差异,许多插件都需要针对开发态和生产态做兼容性处理的。
所以综上所述,Vite其实对于生产环境的编译速度提升不大(况且这也不是开发体验的痛点),与其在一个不熟悉的Rollup
生态下摸爬滚打,不如生产环境就让它保持原来的Webpack
进行编译。差异或许是存在的(一开始我们也这么认为),但应该都可以在统一的Builder
中做更新处理。
实际上,结果比我们一开始预期的要好太多,跑了1年多下来,Vite与Webpack的差异出现过1、2次,主要是出现在CSS加载的顺序上面,有时会导致部分样式覆盖优先级的变化。
我们在脚手架中依旧保留lzd start
方式使用 Webpack 进行启动,临时用 Webpack 启动适配即可。
总结
我们团队引入 Vite 已经一年多的时间了,过程中有一些小的磕绊,但总体受到前端开发者们的一致好评!目前基本上团队95%的项目已经切换使用Vite开发,许多用过 Vite 以后的小伙伴,回到自己原来的项目第一件事就先来试试看能不能给它改成 Vite。
从发展趋势来看,我认为Vite是一个大的集合,集合了无数个变革过程中的优秀项目,从而形成的一个奇点。
Vite 仿佛一扇大门,带我们看到一个新的领域,带我们真正感受了一把 “量变形成质变”,带我们真正感受到了技术带来的价值。
我相信,Vite 只是个起点,现在的加载方案效率上也还远没到最佳的状态,现在的方案也还没有完全打破 “社区DSL” 与 “浏览器原生” 的壁垒,未来一定还会有许多精彩的改变不断出现,或许我们就是在路上的缔造者😜。