Webpack多页面项目转Vite升级初尝试

3,476 阅读6分钟

本文已参与好文召集令活动,点击查看:后端、大前端双赛道投稿,2万元奖池等你挑战!

最近社区讨论Vite火热,而且听说它是个“快枪手”,作为一个切图仔快代表着效率,怀着对快的期待和提高自己的眼界(吹牛的本事),尝试使用Vite对现有一个基于webpack多页面项目进行升级。

本文非深入了解,从中你能对Vite有个初步的认识,以此来对比与Webpack的差异,看完后你能了解到以下内容:

  • Vite火热的原因
  • Vite的优点是什么
  • Vite的缺点是什么
  • 升级过程的坑
  • 升级后的项目的提升(打包速度具象化,热更新速度具象化,包体积具象化)

Vite的吸引力

是什么原因导致Vite让那么多人垂涎呢?我最开始听到Vite时他们说它真的很快,但是大家都是打包工具,为什么说Vite比Webpack快呢?我们一起来揭秘,官方是这样介绍Vite的:

  • 极速的服务启动,使用原生 ESM 文件,无需打包!
  • 轻量快速的热重载,无论应用程序大小如何,都始终极快的模块热重载(HMR)
  • 丰富的功能,对 TypeScript、JSX、CSS 等支持开箱即用。
  • 优化的构建,可选 “多页应用” 或 “库” 模式的预配置 Rollup 构建
  • 通用的插件,在开发和构建之间共享 Rollup-superset 插件接口。
  • 完整类型化的API,灵活的 API 和完整 TypeScript 类型

我们来新建一个Vite的demo,使用

yarn create vite

就能轻松的创建起项目,其中会让你选择你要使用的框架,操作完成后,我们会看到根目录有一个index.html, 和Webpack不同,Vite是基于html作为入口,而Webpack是基于Js作为入口。在html中我们看到利用Vite建起的项目script中使用了type="module",这是什么呢?ES Modules 是用于处理模块的 ECMAScript 标准。通过设置type="module",我们可以在当前脚本支持使用import export来进行编写代码。

image.png

基本上现代浏览器都已经支持ESM的方式了

而这就是Vite快的秘密,Vite通过使用esm和koa中间件拦截请求,我们可以只在需要某个模块的时候动态(借助 import() )的引入它,而不需要提前打包。这一点和Webpack完全不同,Webpack会将各模块提前打包进bundle里,但打包的过程是静态的,就是在修改某一处代码后,会把所有模块进行打包,这样的坏处就是随着项目越来越大打包后的 bundle 也越来越大(当然Webpack也提供了很多类似bable-cache等插件来提高效率),即使这样Webpack依旧会执行打包这个过程,这样对比Vite来说确实不够优雅,因为vite来说,借住ESM它直接省去了打包这个过程。

优点

  1. 创建简单

Vite继承了Vue优良的传统,重在提高开发效率,所以相比Webpack减少了很多配置,使用Vite,你不再配置各种基础预处理器,它都内置了

  1. 与框架无关

虽然它的作者是Vue的创造者,但是Vite却与框架无关,它能和React,Vue,Svelte、Preact等框架使用

缺点

  1. 灵活度

因为本身的内部封装好了很多东西,所以现在看来定制化是比较困难的,这个点是看自己取舍,各有利弊。

  1. 未知性

现在Vite2出来没多久,社区还没有很多大型项目实践,是否还有很多坑有待观望

  1. 构建不一致

这也是我最担心的一点,开发的时候使用ESM方式进行开发,打包的时候使用Rollup进行打包,也就是说使用了两套方式,会担心生产环境和开发环境不一致情况,导致打包后的bug不好在生产环境中进行调试,这个点有待考察,需要对之后迁移的项目进行深度测试。

项目迁移

因为我们项目是从古老的手动打包升级到了webpack打包,大部分页面本身都使用了html,所以迁移成本比较少,主要是在原有的html中插入script type=module代码

迁移时遇到的问题:

  1. 过去一些图片资源使用require引入的均无法使用,需要修改为import,这点是因为本身Vite开发环境基于ESM而不支持CommonJs
  2. 过去我们使用环境变量并没特别的规范,在Vite中为了防止意外地将一些环境变量泄漏到客户端,只有以 VITE_ 为前缀的变量才会暴露给经过 Vite 处理的代码(这点和CRA类似),并且不是使用process.env的方式获取环境变量,而是使用import.meta.env的方式去获取。
  3. Vite默认打包兼容ESM,这里我们需要安装@vitejs/plugin-legacy来解决不支持的浏览器处理

整个项目迁移只用了不到2个小时,大部分时间在处理通过require引入的模块和资源,而打包好的文件是否能使用到生产环境还有待考究,打包后依然会引入ESM的方式,但是在ESM后加入了NoModule的加载方式。这样的好处在于现代浏览器我们将不在用加载那么多Polyfill,减少不必要的资源加载。如下:

image.png

项目提升

测试环境 window10 8G i5-6200U

单页面测试使用了项目中涉及资源和依赖最多的一个页面(图片资源100+,js文件20+);

打包工具单页面启动多页面启动单页面开发环境修改多页面开发环境修改单页面打包多页面打包
webpack49.964s18.829s0.827s4.347s11.981s26.57s
vite0.694s1.5s未知(<50ms)未知(<50ms)8.8s27.09s

在打包效率上基本一致,因为本身打包Webpack和Rollup差异不大,在打包上的优势就没有那么突出,打包体积上也相差不多,这里也就不做对比。

总结

完成了项目的迁移,对Vite有了大致的了解,在兼容性配置上有很多坑,可以继续沿用Webpack进行打包,而在开发环境使用Vite进行开发或许也是一个很好的搭配。后续主要还是对Vite配置做详细的认识和对项目进行测试,看是否有未触及的坑,未来对Vite持续观望,期待(愿景)有一天能摈弃各类打包工具,原生支持那该是多么美好。