一、概述

(1)live reload

只要检测到代码改动就会自动重新构建,然后触发网页刷新

(2)webapack中的模块热替换

可以让代码在页面不刷新的前提下得到最新的改动,甚至不需要重新发起请求就能看到更新后的效果。

二、开启HMR

(1)HMR是需要手动开启的,并且有一些必要条件。

(2)确保项目是基于webpack-dev-server或webpack-dev-middle进行开发的,webpack本身的命令行并不支持HMR。

const webpack = require('webpack');
module.exports = {//...plugins: [new webpack.HotModuleReplacementPlugin()],devServer: {hot: true}
}

1、配置产生的结果是Webpack会为每个模块绑定一个module.hot对象,这个对象包含了HMR的API。借助这些API不仅可以实现对特定模块开启或者关系HMR,也可以添加热替换之外的逻辑。

2、调用HMR API 有两种方式,一种是手动地添加这部分代码;另一种是借助一些现成地工具,如react-hot-loader、vue-loader等。

3、如果应用的逻辑比较简单,可以直接手动添加代码来开启HMR。

//index.js
import { add } from 'util.js';
add(2, 3);
if (module.hot) {module.hot.accept();
}

假设index.js是应用的入口,可以把调用HMR API的代码放在入口中,这样HMR对于index.js和其依赖的所有模块都会生效。当发现有模块发生变动时,HMR会使应用在当前浏览器环境下重新执行一遍index.js(包括其依赖)的内容,但页面本身不会刷新。

三、HMR大致原理

(1)在本地开发环境下,浏览器是客户端,webpack-dev-server(WDS)相当于服务端。

(2)HMR的核心是客户端从服务端拉取更新后的资源(准确得说,HMR拉取的不是整个资源文件,而是chunk diff即chunk需要更新的部分)

1、WDS对本地源文件进行监听,当本地资源发生变化时WDS通过websocket向浏览器推送更新事件,并带上这次构建的hash,让客户端与上一次资源进行比对。

2、客户端发现有差别,会向WDS发送一个请求来获取更改文件的列表,即哪些模块有了改动。通常这个请求的名字为[hash].hot-update.json。

3、请求返回结果会告诉客户端,需要更新的chunk名字和hash。客户端借助这些信息继续向WDS获取该chunk的增量更新。

4、客户端处理增量更新。

四、HMR API

moudle.hot.decline:将当前文件的HMR关掉,当前文件发生改变时禁止使用HMR进行更新,只能刷新整个页面。

module.hot.accept(['./util.js']):当util.js发生改变时仍然可以启用HMR更新

五、热更新原理

(1)配置热更新

(2)npm run dev 进入 webpack-dev-server.js文件

1、webpack(config)生成一个compiler

2、new Server(compiler, options, log)生成一个server,启动一个本地服务

3、启动websocket服务,通过websocket,可以建立本地服务和浏览器的双向通信。

(3)进入webpack-dev-server/lib/Server.js

updateCompiler(this.compiler, this.options);
this.setupHooks();
this.setupDevMiddleware();

1、server里先调用updateCompiler

1)两段关键代码:一个是获取websocket客户端代码路径,另一个是根据配置获取webpack热更新代码路径。

2)作用:修改webpack.config.js的entry配置,将webpack-dev-server/client(socket)和webpack/hot/dev-server(检查更新逻辑)注入客户端。

// 修改后的entry入口
{ entry:{ index: [// 上面获取的clientEntry'xxx/node_modules/webpack-dev-server/client/index.js?http://localhost:8080',// 上面获取的hotEntry'xxx/node_modules/webpack/hot/dev-server.js',// 开发配置的入口'./src/index.js'],},
} 

b、setupHooks方法

1)用来注册监听事件的,监听每次webpack编译完成。(监听了compiler.done)

2)当监听到一次webpack编译结束,就会调用_sendStats方法通过websocket给浏览器发送通知,okhash事件,这样浏览器就可以拿到最新的hash值了,做检查更新逻辑

c、setupDevMiddleware

1)webpack监听文件变化

2)这个方法主要执行了webpack-dev-middleware库,作用是本地文件的编译和输出以及监听,webpack-dev-server只负责启动服务和前置准备工作,所有文件相关的操作都抽离到webpack-dev-middleware库了(调用了compiler.watch方法)

3)webpack-dev-middleware最后执行setFs方法,这个方法主要目的就是将编译后的文件打包到内存

(4)浏览器接收到热更新的通知

1)/webpack-dev-server/client/index.js,注入到客户端的代码,即websocket,接收到okhash事件推送。hash事件:更新最新一次打包后的hash值。 ok事件:进行热更新检查

2)ok回调函数调用reloadApp,方法又利用node.js的EventEmitter,发出webpackHotUpdate消息

3)'xxx/node_modules/webpack/hot/dev-server.js',注入到客户端的另外一个入口代码,会监听webpackHotUpdate这个事件并且获取到最新的hash,事件内部调用check

4)check方法内部,检查更新调用的是module.hot.check方法,此方法是通过HotModuleReplacementPlugin注入的

5)module.hot.check方法内部,利用上一次保存的hash值,调用hotDownloadManifest发送xxx/hash.hot-update.json的ajax请求,请求结果获取热更新模块,以及下次热更新的Hash 标识,并进入热更新准备阶段

6)调用hotDownloadUpdateChunk发送xxx/hash.hot-update.js 请求,通过JSONP方式(JSONP获取的代码可以直接执行)

7)通过xx/hash.hot-update.js 请求获取回来的新编译后的代码是在一个webpackHotUpdate函数体内部的。也就是要立即执行webpackHotUpdate这个方法。

8) webpackHotUpdate方法内部调用hotAddUpdateChunk方法,此方法会把更新的模块moreModules赋值给全局全量hotUpdate,再调用hotUpdateDownloaded方法,hotUpdateDownloaded方法会调用hotApply进行代码的替换。

9)hotUpdate代码做的事

a、删除过期的模块,就是需要替换的模块

b、将新的模块添加到 modules 中

c、通过__webpack_require__执行相关模块的代码

(5)过程图

Webpack--模块热替换(HMR)相关推荐

  1. webpack 3 零基础入门教程 #12 - 如何使用模块热替换 HMR 来处理 CSS

    模块热替换 是什么意思? 以前我们使用的 webpack --watch 或 webpack-dev-server 的功能是监听文件改变,就自动刷新浏览器,而这个 模块热替换 不用刷新浏览器,它是只让 ...

  2. webpack实践之路(七):模块热替换HMR

    HMR 模块热替换(Hot Module Replacement 或 HMR)允许在运行时更新各种模块,而无需进行完全刷新. HMR主要是通过以下几种方式,来显著加快开发速度: 保留在完全重新加载页面 ...

  3. webpack5 基础配置8 devServer 模块热替换HMR, 框架的HRM, HRM原理

    dev Server 之前运行一直是手动打开页面,修改代码后,每次都要run build非常麻烦. 第一种是通过watch来解决,每次代码一修改就自动编译然后重新渲染. 可以看到刚我们修改了代码,重新 ...

  4. webpack学习之2.自动编译、实时重载LiveReload、热替换HMR

    代码沿用webpack学习之1.基础配置 每次要编译代码时,手动运行 npm run build 就会变得很麻烦. webpack 中有几个不同的方式,可以在代码发生变化后自动编译代码: webpac ...

  5. react 动态修改路由_升级到 React Router 4 并实现动态加载和模块热替换

    这篇文章是升级到Webpack2坑--模块热替换失效页面不自动刷新?的后续.那篇文章主要说明了,升级到 Webpack 2 之后,通过升级webpack-dev-server和react-hot-lo ...

  6. webpack学习(七):启用 HMR(模块热替换)

    demo地址: https://github.com/Lkkkkkkg/webpack-demo 上次使用 webpack-dev-serve : https://blog.csdn.net/qq59 ...

  7. 【webpack】-- 模块热替换

    全称是Hot Module ReplaceMent(HMR),理解成热模块替换或者模块热替换都可以吧,和.net中的热插拔一个意思,就是在运行中对程序的模块进行更新.这个功能主要是用于开发过程中,对生 ...

  8. vue-cli3项目移动设备调试访问报错WDS:Disconnected,无法自动刷新或模块热替换

    原文地址:https://blog.csdn.net/qq_42420120/article/details/82912944 因为默认情况下,cli3中devServer开启时默认使用的IP不是局域 ...

  9. Angular 热替换HMR 报错cannot find name module

    热替换(Hot Module replacement) 该功能能够实现修改后页面不刷新也能更新 该功能使用websocket 实现,当后台的文件修改后,后台就会推送修改到前端,让前端替换修改的那一部分 ...

  10. webpack模块解析

    模块 在模块化编程中,开发者将程序分解成离散功能块(discrete chunks of functionality),并称之为模块 每个模块具有比完整程序更小的接触面,使得校验.调试.测试轻而易举. ...

最新文章

  1. 苹果 2020 iPhone 展望:相机大升级,5G 首次接入
  2. 让BASH,VIM美美的Powerline
  3. 到时间就站起来!用树莓派爆改升降办公桌,懒癌有救了
  4. ajax中 get 和 post 的区别
  5. BASH命令和SHELL脚本学习
  6. vue-cli2.9.6 build项目无法访问资源 无法访问elementUI字体
  7. iOS常用于显示几小时前/几天前/几月前/几年前的代码片段
  8. Abp vNext发布v2.3!
  9. SHLVL 和 BASH_SUBSHELL 两个变量的区别
  10. java.lang.InstantiationException: DWR can't find a spring config. See the logs for solutions
  11. pandas - pd.date_range-生成时间索引
  12. mysql存储过程教程(1)
  13. 我是如何把SpringBoot项目的并发提升十倍量级的
  14. 正则表达式验证注册页面
  15. ecshop后台首页mysql_ECSHOP后台自带数据库管理
  16. Qt调节电脑屏幕亮度
  17. 鸿蒙试炼如何拿经验,热血精灵派空空夜夜的勇士试炼 百万经验轻松得
  18. 爬虫练习:爬取网易云音乐热歌榜全部歌曲的热门评论
  19. 计算机网络-应用层和传输层协议分析实验(PacketTracer)
  20. 3Com控股华为3Com 合资公司将面临新轮调整

热门文章

  1. 华为-交换机堆叠配置
  2. pyqt win32发送QQ消息
  3. [信息论与编码]离散信源及其信息测度(2)
  4. 在ubuntu16.04下,使用unrar解压缩rar文件
  5. xmlhttp = new XMLHttpRequest();
  6. 中文分词软件包的使用
  7. 3、Vue+ElementUI制作用户登录页面
  8. 【转载】Matlab与C#连接的几种方式比较
  9. java选择结构与分支结构
  10. 图片翻译成中文其实很简单,只需这几步