前言
上一篇文章中,我向大家讲述了VITE在DEV流程中的大致的初始化过程,并且向大家讲述了我们从浏览器发出的资源请求是如何映射到VITE的DevServer的。
从这一篇文章开始,我们需要详细的开始聊这里面的细节了。
这篇文章估计是很多同学感兴趣的内容,因为这个这篇文章的主要知识点是大家熟悉的Node端服务器开发的知识点。
我们从中间件开始聊,接着会聊VITE在DEV阶段实现Rollup同等API所需要的辅助类,然后会聊到热更新和WebSocket相关的知识点,再然后,我们会聊VITE的preview的相关知识点,最后会聊依赖预构建的知识点,这是我目前计划的行文思路。
如果读者您没有阅读过我上一篇文章,请先查阅上一篇文章,这篇文章强依赖上一篇文章:Vite源码学习(六)------DEV流程探究起步的内容。
好了,废话就不多说了,精彩内容,马上开始。
从Server开始
衔接上文,我们聊到了VITE的DevServer使用的是一个叫做connect
的包,创建connect的实例,然后托管给node:http
创建的Server。
之前,我们是忽略了很多细节的,比如这篇文章需要详细聊的在
middleware
这个变量上,VITE又挂载了很多内置的中间件。
以下是挂载的中间件,足足有15个之多。
在明白了这些之后,我们就可以看一下是如何VITE实现的这些中间件的了。
备注:本系列文章可能不会逐一阐述这些中间件,我会只挑选重要的中间件进行阐述。
VITE的DevServer中间件是统一都存放在这个目录下的:
notFoundMiddleware
为了提高大家的学习积极性,增强学习的成就感,我们就从最简单的的中间件开始学习,哈哈。 打开这个中间件的源代码,可以发现实现是非常简单的:
要测试这个中间件的效果,不能用普通的GET请求,我们使用postman发送POST请求就可以测试出它的效果:
我们加一行日志查看效果:
可以看到,中间件明显是生效了的,哈哈,这样我们就学习了VITE的第一个中间件。
errorMiddleware
这个中间件是非常重要的,相信大家在使用VITE开发项目的时候一定遇到过这样的错误: 大家有没有想过这个错误信息是怎么来的呢?
接下来,我们就一起来探究这个错误信息遮罩的处理逻辑。 这个响应内容不太好触发,我之前在使用VITE的JS API启动DevServer的时候遇到过,正常我们使用CLI启动的时候是不会遇到这个响应内容生效的,我猜测可能是
html
流已经响应了(如果我的说法不正确的话,欢迎读者刊误)。
不过,仍然有一个关键的信息,我们可以看到这个错误仍然通过WebSocket传递给了客户端。(在本文中我还不会聊WebSocket中的细节,后面几篇肯定会聊到的,大家稍安勿躁)
VITE通过Server实例上的HMR上下文,把WebSocket的消息发送给了客户端。
客户端事先已经导入了VITE的客户端辅助函数,一个叫做
@vite/env
,一个叫做@vite/client
,通过这两个辅助工具的帮助,就可以把错误信息插入到我们正在开发的HTML界面上了。
在
@vite/client
中,又导入了@vite/env
:
然后插入错误信息遮罩:
这个遮罩是一个自定义元素:
经过以上处理,我们就在客户端看到了详细的错误信息。
最后,给大家补充一下VITE是如何导入@vite/client
这个辅助工具的。
VITE利用了transformIndexHtml
生命周期,然后在html中插入这个工具的导入:
htmlFallbackMiddleware
不知道大家发现没有,如果我们访问VITE的DevServer的时候,如果我们访问的是.html
结尾的后缀,如果能匹配到对应的后缀文件,则可以正常访问,否则不管什么样的地址都会被重定向到index.html
中。
其实上面的效果就是因为htmlFallbackMiddleware
的功劳,使得我们在开发的时候更方便,下面我们就一起来看看实现:
staticMiddleware
这个中间件主要用来处理静态文件,处理静态文件又分为两个步骤,第一个步骤是publicDir下面的静态文件。
关于publicDir还不清楚的同学,请自行查阅VITE的文档。
还有一种情况,那就是真的就是服务器上的静态资源,比如图片。
这个插件的应用顺序是在transformMiddleware
的后面的,也就是说,transformMiddleware
不转换的内容将会放行至这个插件。
transformMiddleware
是VITE在DEV阶段的重中之重的插件,必须作为压轴出现,所以,我们会在最后一个小节中阐述它。
先看以/@fs
开头的文件处理: 我为公司编写的活动开发脚手架,配置的路径别名读取的是当前程序运行的路径,VITE解析出来就是这样的:
还有一种,就是类似相对路径这样的:
初始化
sirv
: 中间件返回内容给后续流程处理:
另外,VITE还处理了publicDir下面的文件目录,其处理逻辑也是大同小异的。
transformMiddleware
之前提到过的重中之重的中间件,我们现在开始聊它。
在这个生命周期中,VITE会调用自己的插件列表,根据我们访问的内容转换资源并且返回,我们来看这个插件的实现: 在本文中,我们就不考虑sourceMap了:
对于raw请求,VITE不做转换:
相信很多同学在背面试八股文的时候都背过Http的协商缓存吧,哈哈哈,这儿就用到了,是不是觉得很亲切呢?
加载资源,返回资源:
因为我们此刻已经对资源进行转换了,已经不再需要后续的处理逻辑了,所以此刻可以直接返回给客户端。
VITE在处理的时候还进行了一个优化,如果是命中了依赖预构建的话,还设置了缓存时间,这个可以使得客户端可以少发送请求,进而提高效率。
对于之前我们提到的静态文件,如果之前的分支是不会命中的,所以直接走next
,进入到之前提到的静态中间件的处理流程中:
假设在执行transformRequest
这个过程中出现了错误的(假设这个错误是VITE未知的错误,一般都是我们的代码错误),会命中这个位置的逻辑,从而可以使请求流程走到之前聊到过的errorMiddleware
:
这个中间件里面调用的关键transformRequest
的核心内容我们在本文中就不再阐述,后续会用专门的篇幅详细介绍。
结语
在这篇文章中,我们已经把VITE的DevServer中重要的Middleware阐述清楚了,我们明白了为什么一个请求发出之后可以获取到资源。
从这些中间件中,其实我们也学习到了很多面试中常常背诵的八股文知识点和一些设计模式。
很多同学经常觉得自己的业务就是简单的增删改查,得不到提升,其实我们不妨换个角度来思考问题,就算是简单的CRUD,也可以通过一些手段来优化开发流程,改进工作流程,从而提高开发效率,最终使自己的技术水平得到提高。
我还是那个观点,纸上得来终觉浅,绝知此事要躬行。只有理论与实践相结合,才能够助力我们走的更远,而通过阅读知名开源项目的源代码,是一个较好的方式之一。
下一篇文章开始,我们就要阐述VITE在DEV阶段实现Rollup同等API所需要的辅助类了,敬请期待......