当前位置: 首页 > Web前端 > vue.js

拥抱下一代前端工具链——Vue老项目迁移Vite探索

时间:2023-04-01 01:17:50 vue.js

作者:京东物流邓道元背景介绍随着项目的不断维护,代码越来越多,项目也越来越大。调试代码的过程变得异常痛苦,项目启动的等待时间也越来越长,尤其是需要处理紧急问题的时候,项目切换启动的时候等待时间会特别长。受不了这个开发效率,决定把老项目迁移到vite。Vite工具发布已经有几天了。工具链和生态趋于稳定,最新版本更新到3.0。既然想法已经开始,行动还不如行动。1、什么是Vitevite?发音为/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,nodev14.18.23.1。首先,我们需要理清项目结构。与原来的Vue老项目相比,模板文件index.html需要从public下载移动到项目根目录,Vite会把index.html作为源码和模块图的一部分。由于我们只有一个入口文件,所以需要在index.html中引入main.ts,运行时可能会遇到如下写法结果报错favicon.ico"/>[vite]Internalservererror:URImalforme解决方案是写一个简单的插件来替换res=code.replace(/<%=\s+BASE_URL\s+%>/g,baseDir);和Vue-cli一样,需要一个配置文件vite.cofnig.js,和原来的vue.config.js同级3.2安装依赖既然我们要使用Vite,那么我们需要安装一个vite依赖。但是我们老项目是Vue2.0,vite先支持Vue3.0,所以还需要一个转换工具“vite-plugin-vue2”npmivite-plugin-vue2-S3.3修改配置文件和修改包.json脚本中使用vite"serve":"vite","build":"vitebuild"启动打包,修改vite.config.js,类似vue.config.jsimport{defineConfig}from'vite'import{createVuePlugin}from'vite-plugin-vue2'//https://vitejs.dev/config/这一行可以添加编辑器代码提示exportdefaultdefineConfig({plugins:[createVuePlugin({jsx:true,//兼容项目vueTemplateOptions:{}}),],resolve:{extensions:['.vue','.js','.ts','.jsx','.tsx','.json'],别名:[{find:'@',replacement:'/src'}]},server:{open:true,//控制台直接打开浏览器host:'xxxx.jd.com',//本地主机allowedHosts:['.jd.com','.jdwl.com','.jd.co.th','.jd.id'],port:80,cors:true,proxy:{'/api':{target:'https://xxx.jd.com',changeOrigin:true,重写:path=>path.replace(/^\/api/,'/api')}}},})3.4去掉原有的webpack相关依赖。你可以手动删除或重启一个vite项目,然后将需要的代码移动到vite项目中。3.5启动应用程序至此,我们就可以启动应用程序了。不出意外的话,会有很多报错信息,但不要慌,我们一一解决。.env.MODE:{string}应用运行的模式。import.meta.env.BASE_URL:{string}部署应用程序时的基本URL。由基础配置项决定。import.meta.env.PROD:{boolean}应用程序是否在生产环境中运行。import.meta.env.DEV:{boolean}应用程序是否在开发环境中运行(始终与import.meta.env.PROD相反)。当然,由于是老项目,这样的调用地方会比较多,我们可以用比较简单的方法来兼容exportdefaultdefineConfig({define:{'process.env':{}},})4.2全局变量因为VIte是ESM机制,有些package内部使用了node的全局对象,可以通过自己构建pollfill来解决这个问题,然后在main.ts顶部引入//polyfillsif(typeof(windowasany).global==='undefined'){;(windowasany).global=window}4.3Scssglobalvariableerror这是vite和vue-cli的配置方式不同导致的,如果使用环境变量,还需要适配vite的写法来兼容exportdefaultdefineConfig({css:{preprocessorOptions:{scss:{additionalData:'$ossHostVariable:\'import.meta\u200b.env.VUE_APP_OSS_HOST\';'}}}})4.4路径错误ViteisanESMmechanismpathisanode包,所以需要兼容浏览器importpathfrom'path'//替换为importpathfrom'path-broswserfiy'4.5Require错误的原因同上由于模块的加载方式不同,可以通过“vite-plugin-require-transform”插件解决importrequireTransformfrom'vite-plugin-require-transform'exportdefaultdefineConfig({plugins:[requireTransform({})]})4.6vue动态导入componentsvue组件的导入方式有很多种,vite可以支持()=>import('/.vue')导入方式导入,但是和webpack不同的是需要补齐文件的后缀,动态导入需要import.meta.glob的方式。constload=import.meta.glob('@/views/**/index.vue');exportconstconstantRoutes:any=[{path:'/404',component:load['404']},]4.7编译时分包策略constSPLIT_CHUNK_CONFIG=[{match:/[\\/]src[\\/]_?common(.*)/,output:'chunk-common',},{match:/[\\/]src[\\/]_?component(.*)/,output:'chunk-component',},];constrollupOptions={输出:{chunkFileNames:'assets/js/[name]-[hash].js',entryFileNames:'assets/js/[name]-[hash].js',assetFileNames:'assets/static/[name]-[hash].[ext]',manualChunks(id){for(SPLIT_CHUNK_CONFIG的constitem){const{match,output}=item;if(match.test(id)){返回输出;}}if(id.includes('node_modules')){returnid.toString().split('node_modules/')[1].split('/')[0].toString();}},},}5.上图中启动时间就不多说了,但是还是会出现一些问题。以开发模式为例,页面的首次加载时间比较慢,大概5s,不过这也可以理解,毕竟编译过程是交出来的。浏览器方面,相比老项目冷启动需要2~3分钟的体验,有了很大的提升。6.总结最后,我们来回顾一下整个迁移过程。首先理清项目结构,将index.html模板文件提到根目录,添加vite.config.js文件进行统计。然后编写配置文件vite.config.js,注意与vue.config.js的语法差异,注意兼容写法。最后,处理项目中两种打包工具的不兼容写法。大部分是由于模块规格不同,node环境和语法变量引起的,可以通过各种插件解决。以上就是本次迁移的全过程,丰富优化了前端工具链的构建流程,大大提升了开发者的幸福感和开发体验,项目冷启动时间提升了99%。虽然前期遇到了很多坑,但是成功之后的感受就是一个字,“真香”。