拥抱下一代前端工具链 -Vue 老项目迁移 Vite 探索
作者:京东物流 邓道远
背景描述
随着项目的不断维护,代码越来越多,项目越来越大。调试代码的过程就变得极其痛苦,等待项目启动的时间也越来越长,尤其是需要处理紧急问题的时候,切换项目启动,等待的时间就会显得尤为的漫长。无法忍受这种开发效率的我,决定将老项目迁移至 vite。
距离 Vite 工具发布到现在已经有了一些日子了,工具链与生态已经趋于稳定,最新版本已经更新到了 3.0,既然念头已起,心动不如行动。
1、什么是 Vite
vite 发音为/vit/ 法语中就是快的意思,“人”如其名,就是快
一个开发服务器,它基于原生 ES 模块,提供了丰富的内建功能,如速度快到惊人的模块热更新(HRM)
一套构建指令,它使用 rollop 来打包你的代码,并且是预配置的,可输出用于生产环境的高度优化过的静态资源。
2、为什么快
众所周知,当冷启动服务器时,基于打包器的启动必须优先抓取并构建你的整个应用,然后才能提供服务,这一抓取构建的过程随着文件越来越多,时间也会越来越长。
而 Vite 却通过将应用中的木块区分为依赖和源码两类,从而优化了大量的服务器启动时间。
依赖大多为在开发时不会变动的纯 JavaScript。一些较大的依赖(例如有上百个模块的组件库)处理的代价也很高。依赖也通常会存在多种模块化格式(例如 ESM 或者 CommonJS)。
Vite 将会使用 esbuild 预构建依赖。esbuild 使用 Go 编写,并且比以 JavaScript 编写的打包器预构建依赖快 10-100 倍。
源码通常包含一些并非直接是 JavaScript 的文件,需要转换(例如 JSX,CSS 或者 Vue/Svelte 组件),时常会被编辑。同时,并不是所有的源码都需要同时被加载(例如基于路由拆分的代码模块)。
Vite 以原生 ESM 方式提供源码。这实际上是让浏览器接管了打包程序的部分工作:Vite 只需要在浏览器请求源码时进行转换并按需提供源码。根据情景动态导入代码,即只在当前屏幕上实际使用时才会被处理。
3、如何完成老项目迁移
当前项目是 Vue2.0,vue-cli4.0,node v14.18.2
3.1 首先我们需要先明确项目结构
与原来的 Vue 老项目相比,模板文件 index.html 需要从 public 挪到项目根目录中,Vite 将 index.html 视为源码和模块图的一部分。由于我们只有一个入口文件,所以在 index.html 中需要引入 main.ts
而且运行过程中可能会遇到下面写法引发的报错
解决办法是可以写一个简单的插件替换一下
与 Vue-cli 相同,需要一个配置文件 vite.cofnig.js, 与原来的 vue.config.js 同级
3.2 安装依赖
既然我们使用 Vite,那么我们需要安装一个 vite 依赖。但是我们的老项目是 Vue2.0,vite 优先支持 Vue3.0,所以我们还需要一个转换工具 "vite-plugin-vue2"
3.3 修改配置文件
修改 package.json 中的 scripts,启动和打包方式使用 vite
"serve": "vite",
"build": "vite build",
修改 vite.config.js,与 vue.config.js 相似
3.4 剔除原来的 webpack 相关依赖
可以手动剔除 也可以重新启动一个 vite 项目再将所需代码移动到 vite 项目中
3.5 启动应用
这个时候我们就可以启动应用了,不出意外的话,会有许多的报错信息,不过不要慌,我们一个一个的解决
4、遇见的问题汇总
4.1 环境变量
webpackl 里的环境变量是默认存储在 process.env 里的,而 vite 是存储在 import.meta.env 里的
import.meta.env.MODE: {string} 应用运行的模式。
import.meta.env.BASE_URL: {string} 部署应用时的基本 URL。他由 base 配置项决定。
import.meta.env.PROD: {boolean} 应用是否运行在生产环境。
import.meta.env.DEV: {boolean} 应用是否运行在开发环境 (永远与 import.meta.env.PROD 相反)。
当然,既然是老项目,这种调用位置会有很多,我们可以使用比较简单的做法来兼容
4.2 global 变量
因为 VIte 是 ESM 机制,有些包内部使用了 node 的 global 对象,解决此问题可以通过自建 pollfill, 然后在 main.ts 顶部引入
4.3 Scss 全局变量报错
这一点是 vite 与 vue-cli 配置方式不同引发,而且如果使用了环境变量也需要适配 vite 的写法兼容
4.4 path 报错
Vite 是 ESM 机制 path 是 node 的包,所以需要兼容浏览器的引入方式,需要安装依赖 “path-broswserfiy”
只需要将引入的包替换即可
4.5 Require 报错
问题的引发与上面一致 都是模块加载方式的不同导致的,可以通过"
vite-plugin-require-transform"插件来解决
4.6 vue 组件的动态导入
vue 的组件导入方式有很多,vite 可以支持 () => import('/.vue')的方式导入,不过与 webpack 的区别在于需要补全文件的后缀,动态导入需要 import.meta.glob 的方式
4.7 编译时的分包策略
5、启动时间
不多说了 上图
不过还会有一些问题,开发模式下比如页面首次加载时间比较缓慢,大约在 5s 左右,不过这也是可以理解的,毕竟编译过程都交给了浏览器,相比于老项目冷启动动辄 2 3 分钟的体验,已经是天大的提升了。
6、总结
最后再来回顾一下,整体的迁移过程。
首先,明确项目结构,index.html 模板文件 提到根目录下,统计增加 vite.config.js 文件。
然后,编写配置文件 vite.config.js 注意与 vue.config.js 上的语法区别,注意兼容写法。
最后,处理项目中两种打包工具的不兼容写法。大部分还是模块规范的区别,node 环境的变量以及语法所引发,可以通过各种各样的插件来兼容解决。
以上即为本次迁移的全部过程,丰富、优化了前端工具链的构建流程,极大的提升了开发人员的幸福感,以及开发体验,项目冷启动时间更是提升了百分之 99%。虽然前期遇到了许多的坑,但是成功后的感受就是一个字,"真香"。
版权声明: 本文为 InfoQ 作者【京东科技开发者】的原创文章。
原文链接:【http://xie.infoq.cn/article/52e3f740207da24948b56112d】。文章转载请联系作者。
评论