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

Vue3-关于Vite我要说的

时间:2023-03-31 23:40:54 vue.js

1.创建vite项目npminitvite-appcdnpminstallnpmrundev或yarncreatevite-appcdyarnyarndev2.vite介绍vite是基于Vue3单文件组件的非打包开发服务器,实现本地快速开发启动:快速冷启动,无需等待打包操作;即时热模块更新,更换性能与模块数量解耦,让更新飞起来;真正的按需编译,不再等待整个应用编译完成,这是一个巨大的变化。而vite也成功改写了webpack的命,让webpack开发者直呼大哥:那vite是怎么做到的呢?3.第一个问题通过运行npmrundev,你可以观察到这个项目被秒打开了。打开调试器可以看到浏览器直接请求.vue文件,后面跟着一些类型参数。单击这些请求并简单地检查文件的返回内容://main.jsimport{createApp}from'/@modules/vue.js'importAppfrom'/src/App.vue'//import'/src/index.css?import'//createApp(App).mount('#app')看这里最直观:convertvuereferenceto/@modules/vue.jsconvert./App.vueto/src/App.vue将./index.css转换为/src/index.css?import//HelloWorld.vue?type=style&index=0import{updateStyle}from"/vite/hmr"constcss="\np{color:red;}\n"updateStyle("62a9ebed-0",css)exportdefaultcss这里编译Helloworld.vue中的style样式,编译p{color:red};//index.css?importimport{updateStyle}from"/vite/hmr"constcss="#app{\nfont-family:Avenir,Helvetica,Arial,sans-serif;\n-webkit-font-smoothing:antialiased;\n-moz-osx-font-smoothing:grayscale;\ntext-align:center;\ncolor:#2c3e50;\nmargin-top:60px;\n}\n"updateStyle("\"2418ba23\"",css)exportdefaultcssandalsoglobalstyles执行更新监控。既然浏览器直接请求.vue文件,那么文件内容是如何解析的呢?该项目是如何在不使用webpack等打包工具的情况下直接运行vue文件。3.1挖掘vite的运行原理从上面的代码片段可以看出,最明显的特点就是使用了ESModule,代码以模块的形式导入到文件中,同时实现了on-按需加载。它最大的特点是在浏览器端使用导出导入的方式导入导出模块,在script标签中设置type="module",然后使用ES模块。正因为如此,vite高度依赖模块脚本特性,这意味着它从这里放弃了IE市场,参见JavascriptMDN。这样操作下还有一个效果就是去掉了webpack打包的步骤,不再需要将每个模块文件打包成一个bundle,从而支持浏览器的模块化加载。那么vite是如何处理这些模块的呢?关键是vite使用Koa搭建服务器,相关功能主要是通过createServer中的中间件进行注册。Vite对导入做了一层处理,流程如下:在koa中间件中获取请求体,通过es-module-lexer解析资源ast,获取导入的内容,判断是否导入resource是一个绝对路径,绝对把它当作一个npm模块返回处理后的资源路径,例如:"vue"=>"/@modules/vue"会处理表单中的模板、脚本、样式等需要的依赖http请求,并使用查询参数来区分和加载每个SFC文件模块内容。为什么这里需要@modules?举个栗子:importvuefrom'vue'vue模块安装在node_modules中,浏览器ESModule无法直接获取项目下node_modules目录下的文件。所以vite在import上做了一层处理,重写了前缀有@modules,让项目可以访问引用资源;另一方面,将文件路径写到同一个@modules中,类似于面向切片的编程,你可以从中执行其他操作而不影响其他资源,比如后面添加别名等配置。通过koa中间件将资源与@modules进行匹配,然后通过require('XXX')获取导出的资源返回给浏览器。3.2文件请求单页文件请求有一个特点,请求路径以*.vue结尾。当服务端收到具有该特性的http请求时,主要是根据ctx.path来处理请求,确定具体的vue文件,并使用parseSFC进行解析。文件,获取描述符,一个描述符包含了这个组件的基本信息,包括模板、脚本、样式等属性。下面是Comp.vue文件处理后得到的描述符,然后根据描述符和ctx.query.type选择对应的类型方法。处理完成后,返回ctx.bodytype为空处理script标签,使用compileSFCMain方法返回js内容类型为template,处理模板标签,使用compileSFCTemplate方法返回render方法类型为styles,处理style标签,并使用compileSFCStyle方法返回css文件在浏览器中使用的内容是使用ES模块通过http请求获取模块,所以vite必须提供一个web服务器来代理这些模块。上面提到的koa中间件就是负责这件事情的。vite通过请求路径query.type劫持获取资源内容返回给浏览器,然后将不同处理单页文件解析的资源文件进行拼接,最终响应浏览器进行渲染。另一方面,这也是一个很有趣的方法。webpack等打包工具会预先将各种模块打包到bundle中,但打包结果是静态的,不管某个模块的代码是否被使用。搞定了,还得打包,明显的缺点就是随着项目越来越大,打包文件越来越大。vite的优雅之处在于它是在需要某个模块的时候动态引入的,而不是提前打包,自然提升了开发体验。4.hmr热更新vite的热更新主要有四个步骤:通过watcher监听文件变化;通过服务器编译资源并将新的资源信息推送给客户端;需要框架支持组件重新渲染/重新加载;客户端接收资源信息并执行框架重新渲染逻辑。在客户端,Websocket监听一些更新的消息类型,然后分别进行处理:vue-reload——vue组件更新:通过import导入新的vue组件,然后执行HMRRuntime.reloadvue-rerender——vue模板更新:import通过import新建模板,然后执行HMRRuntime.rerendervue-style-update——vuestyleupdate:直接插入新的样式表style-update——cssupdate:文档插入新的样式表style-remove——cssremove:文档删除stylesheetjs-update——js更新:直接执行full-reload——页面roload:使用window.通过解析器获取当前文件内容,与缓存中上次的解析结果进行比较,有变化则执行相应的render。5.后续这篇文章简单介绍了vite的启动环节以及背后的简单原理。虽然短时间内vite不会取代webpack,但是我们可以看到vite强大的潜力和势不可挡的趋势。vite的更新实在是太快了。特别佩服游达的勤奋和开源精神。目前还在快速迭代中。会有单独的文章来分析每个内部原理的实现。希望大家多多期待。如果您有任何问题,请随时交流。欢迎大家关注作者公众号:前端优化