webpack 的热更新是如何做到的?原理是什么?

2023-11-01

Hot Module Replacement,简称 HMR,在不需要刷新整个页面的同时更新模块,能够提升开发的效率和体验。热更新时只会局部刷新页面上发生了变化的模块,同时可以保留当前页面的状态,比如复选框的选中状态等。

在 webpack 中配置开启热模块也非常的简单,如下代码:

const webpack = require('webpack')
module.exports = {
  // ...
  devServer: {
    // 开启 HMR 特性
    hot: true,
    // hotOnly: true
  },
}

 热更新的实现

webpack-dev-server 启动的时候会做三件事情

  1. 启动 webpack,生成 compiler 实例,compiler 实例的功能很多,比如用来启动 webpack 的编译工作,监听文件变化等。
  2. 使用 Express 启动一个本地服务,使得浏览器可以访问本地服务
  3. 启动 websocket 服务,用于浏览器和本地 node 服务进行通讯。

监听文件变化

webpack 监听文件变化主要是通过 webpack-dev-middleware 这个库来完成,它负责本地文件的编译、输出和监听 webpack-dev-middleware 中执行了 compiler.watch 方法,它主要做了两件事情

  1. 对本地文件编译打包
  2. 编译结束之后,开启监听,文件发生变化时重新编译,并持续进行监听

监听 webpack 编译结束

setupHooks 方法用来注册监听事件,当监听到 webpack 编译结束时,通过 websocket 给浏览器发通知,浏览器拿到 hash 只之后就可以做检查更新逻辑。 

一、是什么

HMR全称 Hot Module Replacement,可以理解为模块热替换,指在应用程序运行过程中,替换、添加、删除模块,而无需重新刷新整个应用

例如,我们在应用运行过程中修改了某个模块,通过自动刷新会导致整个应用的整体刷新,那页面中的状态信息都会丢失

如果使用的是 HMR,就可以实现只将修改的模块实时替换至应用中,不必完全刷新整个应用

webpack中配置开启热模块也非常的简单,如下代码:

const webpack = require('webpack')
module.exports = {
  // ...
  devServer: {
    // 开启 HMR 特性
    hot: true,
    // hotOnly: true
  },
}

通过上述这种配置,如果我们修改并保存css文件,确实能够以不刷新的形式更新到页面中

但是,当我们修改并保存js文件之后,页面依旧自动刷新了,这里并没有触发热模块

所以,HMR并不像 Webpack 的其他特性一样可以开箱即用,需要有一些额外的操作

我们需要去指定哪些模块发生更新时进行HRM,如下代码:

if (module.hot) {
  module.hot.accept('./util.js', () => {
    console.log('util.js更新了')
  })
}

二、实现原理

首先来看看一张图,如下:

  • Webpack Compile:将 JS 源代码编译成 bundle.js
  • HMR Server:用来将热更新的文件输出给 HMR Runtime
  • Bundle Server:静态资源文件服务器,提供文件访问路径
  • HMR Runtime:socket 服务器,会被注入到浏览器,更新文件的变化
  • bundle.js:构建输出的文件
  • 在 HMR Runtime 和 HMR Server 之间建立 websocket,即图上 4 号线,用于实时更新文件变化

上面图中,可以分成两个阶段:

  • 启动阶段为上图 1 - 2 - A - B

在编写未经过webpack打包的源代码后,Webpack Compile 将源代码和 HMR Runtime 一起编译成 bundle文件,传输给Bundle Server 静态资源服务器

  • 更新阶段为上图 1 - 2 - 3 - 4

当某一个文件或者模块发生变化时,webpack监听到文件变化对文件重新编译打包,编译生成唯一的hash值,这个hash值用来作为下一次热更新的标识

根据变化的内容生成两个补丁文件:manifest(包含了 hash 和 chundId,用来说明变化的内容)和chunk.js 模块

由于socket服务器在HMR Runtime 和 HMR Server之间建立 websocket链接,当文件发生改动的时候,服务端会向浏览器推送一条消息,消息包含文件改动后生成的hash值,如下图的h属性,作为下一次热更细的标识

在浏览器接受到这条消息之前,浏览器已经在上一次socket 消息中已经记住了此时的hash 标识,这时候我们会创建一个 ajax 去服务端请求获取到变化内容的 manifest 文件

mainfest文件包含重新build生成的hash值,以及变化的模块,对应上图的c属性

浏览器根据 manifest 文件获取模块变化的内容,从而触发render流程,实现局部模块更新

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

webpack 的热更新是如何做到的?原理是什么? 的相关文章

随机推荐

  • 常用的正则表达式汇总(最全)

    0 常用的正则表达式汇总 1 匹配中文 u4e00 u9fa5 2 英文字母 a zA Z 3 数字 0 9 4 匹配中文 英文字母和数字及下划线 u4e00 u9fa5 a zA Z0 9 同时判断输入长度 u4e00 u9fa5 a z
  • /bin/sh -e

    e含义 每条指令之后 都可以用 去判断它的返回值 零就是正确执行 非零就是执行有误 加了 e之后 就不用自己写代码去判断返回值 返回非零 脚本就会自动退出
  • JUST技术:高效时空索引揭秘及使用指南

    一 问题背景 城市中超过80 的数据都与时空有关 如加油站点 出租车轨迹 交通路况等 这些数据多为半结构化和非结构化数据 并且需要管理的数据量巨大 传统的时空数据库管理海量数据时会出现性能严重下降的情况 如带有PostGIS插件的Postg
  • 编程题中的问题 2020-9-13

    1 多行的输入输出 Scanner sc new Scanner System in int t sc nextInt 以空格和回车区别的数 String s sc nextLine 或得一行的内容 因为好久没有接触基本的输入输出了 导致今
  • STM32进阶:使用STM32驱动ST7735S(内附核心源码)

    使用STM32驱动ST7735S 内附核心源码 感觉很久很久没有来博客更新了 历经千难万阻 终于做出来了TFT显示屏的SPI驱动 这里分享以下核心源码 接下来一段时间开始准备考科一了 后面有时间了再来更新 有三种模式下的驱动 一 软件SPI
  • Linux入门篇-RHEL8的网络管理

    简介 没有比 Linux 网络管理更重要的知识 只适用于 centos rhel 系列 不低于 rhel7 版本 RHEL8网络管理服务 在早期的Linux发行版本里几乎所有的网络服务都是network服务 从RHEL7开始红帽官方建议采用
  • 如何声明静态方法 和 实现?

    如何声明静态方法 和 实现 在 C 中 声明和实现静态方法 静态成员函数 与普通成员函数有一些区别 静态方法属于类本身 而不是类的对象 因此在声明和实现时需要特殊的语法 声明静态方法 在类的声明中 通过在函数原型前面添加关键字 static
  • Spring Boot整合Elasticsearch

    Elasticsearch是一个全文搜索引擎 专门用于处理大型数据集 根据描述 自然而然使用它来存储和搜索应用程序日志 与Logstash和Kibana一起 它是强大的解决方案Elastic Stack的一部分 我之前的一些文章中已经对此进
  • 专辑一:爱之初体验(初级)

    1 Everyone Has a Story in Life 每个人都有自己的故事 A 24 year old boy seeing out from the train s windows shouted Dad look the tre
  • C++子类不能使用初始化列表来初始化父类的属性

    不能使用初始化列表来初始化父类的属性 变量赋值 函数调用要在函数内 不能使用初始化列表来初始化父类的属性 报错 xx 不是类 xxx 的非静态数据成员或基类 主要原因 子类不能使用初始化列表来初始化父类的参数或属性 报错代码 class O
  • TCP/IP详解笔记(9)

    TFTP简单文本传输协议和BOOTP引导程序协议 TFTP协议 TFTP主要使用UDP协议 当需要将程序或文件同时向许多机器下载时就需要TFTP 或者当无盘系统工作时先广播一TFTP请求 网络上的TFTP服务器就会发送响应 其中包含可执行的
  • 秩亏自由网平差的附加条件法

    目录 一 原理概述 二 案例分析 三 代码实现 四 结果展示 一 原理概述 N B T P B N B TPB N
  • 为什么学习java

    我们为什么要学习java 前几天在上课的时候 老师问了一句这样的话 为什么要学习java 好家伙 当然是热 穷 爱 的 了 当然 如此肤浅也是万万不能的 于是我陷入沉思 是啊 现在主流编程语言这么多 python c c 为什么我要学习ja
  • 使用Tensorflow实现CNN进行手写数字识别

    传统的机器学习需要使用不同的特征提取算法获取特征 深度卷积神经网络为图像分类提供了统一的解决方案 一 卷积神经网络 卷积神经网络CNN是多层神经网络的一个变种 传统的多层神经网络 当隐层数变多时 节点数目过多时就会造成参数个数过多 训练难度
  • 【STM32】基本定时器

    基于stm32f103 基于 零死角玩转STM32 F103指南者 进行学习 定时器 分类 基本定时器 通用定时器 高级定时器 功能框图 简单来说就是来自APB或者AHB的时钟 经过PSC 1到65535分频 形成时基 每经过一个时基 TI
  • Matlab R2021b下载安装教程

    1 本人使用百度网盘下载 2 准备工具 内存较大的电脑 会占用20 G 请注意 百度网盘 还需要耐心 这点我待会细说 3 Matlab R2021b下载地址私信我即可 4 开始下载 然后就是漫长的等待过程 因为我在学校宿舍 网速慢 但是总体
  • 机器学习sklearn之贝叶斯网络实战(三)

    贝叶斯网络的结构学习 包括 基于评分的结构学习 基于约束的结构学习以及两者结合的结构学习方法 hybrid structure learning 评分函数主要分为两大类 贝叶斯评分函数 基于信息论的评分函数 贝叶斯评分函数主要包括 K2评分
  • 虚拟机VMware最详细下载与安装教程!

    前面给大家讲过了虚拟机VBox的安装 个人觉得还是没有VMware好用 因为VMware有快照功能 而VBox没有 所以今天就给大家说下VMware的安装 有很多细节方面需要注意 不然很可能安装失败 这里就说下15 5 2的安装 建议不要安
  • WMware WorkStation克隆CentOS7

    WMware WorkStation克隆CentOS7 1 克隆说明 vmware中的完整克隆是基于指定的虚拟机克隆出相同的一份出来 不必再安装 但是我们要保证几个地方不能一样 一个是主机名称 hostname 一个是虚拟网卡设备mac地址
  • webpack 的热更新是如何做到的?原理是什么?

    Hot Module Replacement 简称 HMR 在不需要刷新整个页面的同时更新模块 能够提升开发的效率和体验 热更新时只会局部刷新页面上发生了变化的模块 同时可以保留当前页面的状态 比如复选框的选中状态等 在 webpack 中