美文网首页
vite技术揭秘--hmr(消息派发与处理)

vite技术揭秘--hmr(消息派发与处理)

作者: 习惯水文的前端苏 | 来源:发表于2022-09-09 08:57 被阅读0次

\bullet 前言

    上一节,已经比较详细的了解了如何塞一个客户端给浏览器,可以说,已经万事俱备,只欠“change”事件了

\bullet 思路

    我们页面显示的内容是由一个个vue组件组成的,那更新页面其实就约等于更新vue组件,那更新vue组件不就可以使用$forceUpdate,那理论上我们想办法拿到变更的vue文件对应的组件实例,然后去执行它的强制更新api,不就做到了局部更新嘛

\bullet 源码

    \ast 消息派发

        chokidar包能够准确的知道哪一个文件发生了变更

        由于缓存机制的存在,vite会先清一下缓存

        接着调用handleHMRUpdate来处理热更新,需要对不同的文件变更做定制化处理:配置文件的修改需要重启服务器才能生效、html文件的修改必须是全量更新等

        \alpha 修改配置

            找到vite.config.js,新增proxy配置项

            由于vite只在服务启动时收集配置项并在开发周期中做相应的调用,因此需要重启node以重新收集

        \beta 修改html文件

            由于热更新的具体实现是由vue或react提供的,而这些框架操作的目标都是以某一个根节点开始的,故需要全量更新

        \gamma 修改.vue文件

            这里也会去做一次清缓存操作,然后根据当前变动文件的缓存标识生成一条ws消息

            最后使用ws.send发送给客户端(即client.js文件)

    \ast 消息接收与处理

        此时,我们已经完成了消息派发,只需要在client.js中对消息做下监听即可

        那么,拿到这个消息后,怎么做才能实现局部更新呢???

        \alpha 热更新的接入对用户来说应当是无感的,且要想实现热更新,就必须能够定位得到具体是哪个组件发生了更新,因此,我们需要对每一个组件做收集

             既然client.js中已经为我们提供了注册方法,那就只需要想办法去调用即可,我们知道在plugin阶段是能够拿到组件源码的,那么我们只需要在源码中拼接出对client.js中注册方法的调用,即可完成组件收集

            这将把文件标记到dataMap中

            同时返回一个包含accet函数的方法类

        \beta 注册热更新回调

            调用上一步向源码插入的accept函数

            这将收集注册的回调函数并等待调用

        \gamma 执行回调

            当接收到socket消息时,读取路径标识判断是否是可更新的文件请求

            接着内部发起请求,获取修改后的文件源码,并借用plugin-vue的能力进行编译

            此时在客户端拿到的值如下

            这显然是一个组件实例,则对render函数的调用,理论上能正确渲染出修改后的内容,那么只需要找到vue中对应的组件实例,替换render函数,然后重新调用vue的updateComponent即可完成一次hmr

            事实上,vue在开发环境中会向全局挂载相关api

            其中的createRecord函数会将组件实例收集起来,而另外两个本质上都属于更新方法

            因此,回调函数的核心即对上述api做调用

相关文章

网友评论

      本文标题:vite技术揭秘--hmr(消息派发与处理)

      本文链接:https://www.haomeiwen.com/subject/ugaqnrtx.html