引入Vite = 多一个月

引入Vite = 多一个月

Vite 在21 ~ 22年在前端界可谓风生水起,颠覆传统也不为过。
20年4月,尤雨溪发推说:“我感觉我再也回不到Webpack了”,Webpack作者用中文直呼:大哥… 在22年的今天,我们再看这个Twitter是不是感觉这声 “大哥” 喊得歇斯底里 😂。

image.png

到底Vite有什么魔力,可以让全世界的前端开发者们争先恐后的投入怀抱呢?
如果只说一个特点,那就是 “快”,不是传统概念的那种快个百分之多少,是tm的几十倍几百倍的快!

什么概念呢,Vite 可以让你的项目甭管多大,1秒内启动;热更新更是快的离谱,几乎是保存的一瞬间就看到效果。说实话,第一次尝试的时候,我惊呆了,我从来没见过这样的速度,从来没体会过这样的开发体验,这个世界上还有这种东西,我感觉我也回不去了。

在技术研发团队中,有一个数字需要知道,每节省40分钟(8小时/21天),一年将会多出一个月。

一个 Vite 的引入,对于一些重型项目,尤其是对于那些非内存文件编译的项目,每天节省40分钟都算是比较保守的估算(一次热更新5秒,一次冷启动3分钟)。其次,对于开发者来说,每次等待编译思路的中断都是相当大的精力损耗。

Ps. 如果你们团队超过12个人,引入 Vite 可能就意味着团队里面多了一位开发者,一个在平均水平的开发者。

快的原理

YY完之后,咱们还是得考虑些实在的问题,这东西为什么快,它是不是还是个玩具,引入到咱们这样的大公司会不会出问题,会不会对咱们工作流程会不会有很大的冲击。

实际上,关于Vite的原理说简单也简单,说复杂也复杂,要真正理解还是要回顾下前端编译史的衍变过程:

  1. 无编译,直接运行(jQuery)
  2. 简单混淆、加密、兼容性补全编译
  3. Webpack模式编译(React、Vue等自创性语法,Coffee,Sass\Less,TypeScript,Pug\Jade,多端)
  4. 局部编译,工程化拆分
  5. Native ESM 浅编译、不编译
    1. https://www.skypack.dev/
    2. https://airpack.alibaba-inc.com/

所以为什么Vite快,我简单总结一下如下:

  1. 浏览器已经长大了,可以自己处理ES Module了,大家就别费劲转成一根筋的Bundle了
  2. 对于一些源码项目(src下的)大多用了些DSL,根据文件后缀做个简单转换,这个过程非常快
  3. 对于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 只需要在浏览器请求源码时进行转换并按需提供源码。根据情景动态导入代码,即只在当前屏幕上实际使用时才会被处理。
    image.png
    image.png

如何落地?

“知其然还知其所以然”之后,回归现状,看看手里头有些什么,可以从哪个地方入手把它逐步引进来。

首先,借助我们之前在团队内部推行的一套的微前端加载方案:《如何接”地气”地接入微前端?》。目前,我们已经收敛了了一套统一的页面编译规范和方法。

也就是说对于绝大多数的业务项目来说,项目中没有任何关于编译的配置。这样的话我们可以便捷的针对该场景下的产物做一层适配,使得我们开发者可以从原来的lzd start换为lzd vite,无缝启动原来的项目。

针对产物,我们之前的页面内容将会被编译成为一个标准的微前端子应用,然后通过加载器来加载对应页面内容,而加载器则是消费一个 UMD规范 的产物。

image.png

为了让整个流程符合Native ESM的消费路径,我们简单处理了一个Vite 转发插件,使得加载器加载到的JS是一份符合UMD规范的静态JS,然后再由这段静态JS创建一个<script type='module'>完成Vite消费路径,顺便加了些热更新的适配,可以让我们代理模式下也能享受Vite的热更新。

image.png

就这样花了一下午的时间,我们简单粗暴的完成了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” 与 “浏览器原生” 的壁垒,未来一定还会有许多精彩的改变不断出现,或许我们就是在路上的缔造者😜。

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×