您的位置:首页 > 数码常识数码常识

vite和webpack(vite与webpack)

2025-05-11人已围观

vite和webpack(vite与webpack)
  前些天尤大在Vue 3.0 beta直播中提到了一个vite的工具,其描述是:针对Vue单页面组件的无打包开发服务器,可以直接在浏览器运行请求的vue文件,对其原理比较感兴趣,因此体验并写下了本文,主要包括vite实现原理分析和一些思考。

  vite与webpack

  预备知识

  vite重度依赖module sciprt的特性,因此需要提前做下功课,参考:JavaScript modules 模块 - MDN。module sciprt允许在浏览器中直接运行原生支持模块

  当遇见import依赖时,会直接发起http请求对应的模块文件。

  开发环境

  本文使用的版本为vite@0.3.2,附github项目地址~目前这个项目貌似每天都在更新 首先克隆仓库

  环境安装完毕后在项目下创建examples目录,新增index和Comp.vue文件,这里直接用README.md中的例子

  首先是inidex

  然后是Comp.vue

  然后在exmples目录下运行

  即可在浏览器http://localhost:3000打开预览,同时支持文件热更新哦~

  如果需要调试源码,启动npm run dev即可,会开启tsc -w --p监听src目录的改动并实时输出到dist目录下,接下来就可以开启欢乐的源码时间~

  入口文件

  目前这个项目迭代非常频繁(昨天还有historyFallbackMiddleware这个中间件呢今天貌似就没了),但是大概的实现思路应该是基本确定了,因此先确定本次源码阅读目标:「了解如何在不使用webpack等打包工具的前提下直接运行vue文件」。基于这个目的,主要是了解实现思路,理清整体结构,不用拘泥于具体细节。

  从入口bin/vite.js开始

  可以看见createServer方法,直接定位到src/server/client.tx。vite使用的是Koa构建服务端,在createServer中主要通过中间件注册相关功能

  vite是通过下面这种middleware的形式注册koa中间件,

  看起来跟Vue2的源码结构比较类似,通过装饰器逐步添加功能~目前只需要理清这四个插件的作用就可以了。

  这个中间件的作用编译index和SFC等文件内容,处理相关的依赖。

  比如上面的html文件script标签内容,通过rewriteImports等方法的处理会被编译成

  这样当浏览器解析并运行这个module类型的script标签时,就会请求对应的模块文件,其中

  /__modules/vue是 koa 服务器的静态资源目录文件,http://sjzlt.cn/shuma/Comp.vue是我们编写的单页面组件文件此外貌似还会提供sourcemap等功能

  对于入口文件而言,需要script标签下相关依赖。对于单页面组件而言,在vue-loader中,也需要处理tmplate、script和style标签;在vite中,这些依赖都会被当做css和js文件请求的方式进行加载。

  单页面组件主要包含template、script和style标签,其中script标签内代码的导出会被编译成

  而style及template标签会被重写成/Comp.vue?type=xxx的形式,重新发送http请求,这个通过query参数的形式区分并加载SFC文件各个模块内容的方式,与vue-loader中通过webpack的resourceQuery配置进行处理如出一辙,如果了解vue-loader运行原理的同学看到这里估计就已经恍然大悟了,之前写过一篇从vue-loader源码分析CSS-Scoped的实现,里面也介绍了vue-loader的大致原理。

  回到vite,现在我们清楚了moduleResolverMiddleware的作用,主要就是重写模块路径,将SFC文件的依赖通过query参数进行区分,方便浏览器通过url加载实际模块。打开浏览器控制台,可以查看具体的文件请求

  11111111111111111111

  VuePlugin

  前面提到单页面组件的template和style会被处理成单独的的import路径,通过query.type区分,那么当服务器接收到对应的url请求时,如何返回正确的资源内容呢?答案就在第二个插件VuePlugin中。

  单页面文件的请求有个特点,都是以*.vue作为请求路径结尾,当服务器接收到这种特点的http请求,主要处理

  根据ctx.path确定请求具体的vue文件使用parseSFC解析该文件,获得descriptor,一个descriptor包含了这个组件的基本信息,包括template、script和styles等属性下面是Comp.vue文件经过处理后获得的descriptor

  然后根据descriptor和ctx.query.type选择对应类型的方法,处理后返回ctx.bodytype为空时表示处理script标签,使用compileSFCMain方法返回js内容type为template时表示处理template标签,使用compileSFCTemplate方法返回render方法type为styles时表示处理style标签,使用compileSFCStyle方法返回css文件内容

  回头整理一下流程

  入口文件依赖Comp.vue的script代码Com.vue依赖tempplate编译的render方法,依赖style标签编译的css代码,这两个文件放在script的编译代码中进行依赖声明

  每个标签内容解析完成之后,会通过LRUCache缓存起来,方便下次重复使用

  至此,我们就大致了解了vite是如何通过koa直接运行vue文件的,其思路跟vue-loader比较类似,借助module script处理文件依赖,然后通过拼接不同的query.type处理单页面文件解析后的各个资源文件,最后响应给浏览器进行渲染。

  hmrPlugin

  前面提到vite也是支持文件热更新的,既然没有使用webpack,那该是如何做到的呢?答案就是自己实现一个哈哈哈~

  热更新主要通过webSocket实现,包括ws服务端和ws客户端两个部分,hmrPlugin主要负责ws服务端的部分,ws客户端在src/client.ts中实现,并通过在第一步处理模块依赖时import "/__hmrClient"将服务端和客户端关联起来。

  目前主要定义了下面几种消息类型

  reloadrerenderstyle-updatestyle-removefull-reload

  当文件发生变化时,服务端在handleVueSFCReload方法中会根据变化的类型推送不同的消息,当客户端接收到对应消息时,会结合vue.HMRRuntime进行处理或者重新加载新的资源。

  热更新这里目前还有不少TODO,感觉是一个学习热更新原理的不错案例,先码一下后面回头重新细读。

  关于热更新的原理,社区有不少原理分析了,不妨移步阅读

  Webpack 热更新轻松理解webpack热更新原理servePlugin

  这个插件主要用于实现一些koa请求和响应的配置。

  经过上面的分析,每次请求时,都会从入口文件开始,依次分析每个依赖

  对于普通文件,直接查找服务器静态资源,通过servePlugin中配置koa-static实现对于vue文件,会重新拼接http请求,对于每个请求,包括path和query,其中path用于确定组件文件,query.type用于确定具体使用啥方法来返回响应内容

  在上面这一步,很明显对于每个vue文件而言,都会发送多个http请求,然后执行查找和解析的操作是很频繁的,如果不配置缓存,服务器的性能负担比较大,koa-conditional-get和koa-etag应该就是为了解决这个问题,不过目前看起来还没有实现。

  小结

  至此,就完成了vite源码的基础阅读,由于本地阅读源码的主要目的是了解整个工具的实现原理和大致功能,因此并没有深入了解每个函数的实现细节,几个比较重要的方法包括rewriteImports、compileSFCMain、compileSFCTemplate、compileSFCStyle、updateStyle等均没有展示具体代码实现,主要的收获是了解了

  结合module script和query.type实现一套类似于vue-loader的机制,直接在服务端运行vue文件使用websocket手动实现热更新,由于时间关系这里并没有细读~

  刚看见vite介绍时就觉得这会是一个非常有趣的工具,虽然还没有正式发布,耐不住去看了一下。感觉主要的作用有

  使用vite快速开发demo,而不必安装一大堆依赖类似于jsfiddle等在线预览vue文件,方便开发、测试和分发单文件组件

  目前看来vite还缺少打包等重要特性,应该是没法替代webpack等工具的。不过感觉vite应该也不是用来替换现有开发工具的,所以后面大概也不会添加打包等功能吧~

  上面就是小居数码小编今天给大家介绍的关于(vite与webpack)的全部内容,希望可以帮助到你,想了解更多关于数码知识的问题,欢迎关注我们,并收藏,转发,分享。

  94%的朋友还想知道的:

  Webpack怎么安装(webpack使用步骤)



  152970
 

很赞哦! ()

随机图文