Webpack--模块热替换(HMR)

article/2025/10/7 12:00:04

一、概述

(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)过程图 


http://chatgpt.dhexx.cn/article/eCjxhm88.shtml

相关文章

HMR API及其原理

很久之前,遇到一个面试题:【在代码变更之后,如何实时看到更新后的页面效果呢?】 在传统的方案中,我们可以通过 live reload 也就是自动刷新页面的方式来解决的,不过随着前端工程的日益庞大,开发…

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

HMR 模块热替换(Hot Module Replacement 或 HMR)允许在运行时更新各种模块,而无需进行完全刷新。 HMR主要是通过以下几种方式,来显著加快开发速度: 保留在完全重新加载页面时丢失的应用程序状态。只更新变更内容,以节省宝贵的开…

【Webpack 性能优化系列(1) - HMR 热模块替换】

webpack系列文章: 【Webpack 性能优化系列(9) - 多进程打包】极大的提升项目打包构建速度!!!【Webpack 性能优化系列(8) - PWA】使用渐进式网络应用程序为我们的项目添加离线体验【Webpack 性能优化系列(7) - 懒加载和预加载】【…

hmr webpack 不编译_Webpack HMR 热更新实现原理深入分析

概述 在使用 Webpack 构建开发期时,Webpack 提供热更新功能为开发带来良好的体验和开发效率,那热更新机制是怎么实现的呢? 代码实现 Webpack 配置添加 HotModuleReplacementPlugin 插件 new webpack.HotModuleReplacementPlugin({ // Options…

webpack4.0核心概念(十)—— HMR(热模块替换-局部刷新)

HMR:当修改一个js或者css的时候,只刷新修改的内容,不进行整个页面的刷新。 css的HMR——只支持开发环境 不能使用mini-css-extract-plugin需要使用style-loader,因为它不支持抽离出的css,需要用style-loader ① 在webpack.config.js中配置 …

前端工程化——Livereload和HMR、本地开发服务器

目录 本地开发服务器解决的问题 动态构建 Mock服务 动态构建 源码改动之后,浏览器应该在何时获取重新编译后的资源? Livereload和HMR 有了构建系统的支持,前端开发人员可以使用诸多有利于开发和维护的技术进行源代码编写。然而如果在开…

hmr webpack 不编译_webpack hmr

参考: hmr技术支持程序运行时的模块(amd、commonJS等)的修改、添加和删除,而不用整个程序重新加载,这可以提升开发的效率: hmr后程序的状态可以得到保存 仅仅改变变化的部分,其余不变 调样式更加快捷,基本比…

18.webpack4之HMR

1.HMR(Hot Module Replacement)热模块替换 在开发环境,可以使用热模块替换(HMR)去实现如果一个模块发生变化,只会重新打包这一个模块(而不是所有模块都进行打包),而无需重…

webpack5之HMR原理探究

一、概念介绍 模块热替换(hot module replacement 或 HMR)是 webpack 提供的最有用的功能之一。它允许在运行时更新所有类型的模块,而无需完全刷新。 主要是通过以下几种方式,来显著加快开发速度: 保留在完全重新加载页面期间丢失的应用程…

hmr webpack 不编译_一文搞懂 webpack HMR 原理

关注「前端向后」微信公众号,你将收获一系列「用心原创」的高质量技术文章,主题包括但不限于前端、Node.js以及服务端技术 一.HMR Hot Module Replacement(HMR)特性最早由 webpack 提供,能够对运行时的 JavaScript 模块进行热更新(无需重刷&a…

Webpack HMR 原理全解析

执行 npx webpack serve 命令后,WDS 调用 HotModuleReplacementPlugin 插件向应用的主 Chunk 注入一系列 HMR Runtime,包括: 用于建立 WebSocket 连接,处理 hash 等消息的运行时代码 用于加载热更新资源的 RuntimeGlobals.hmrDow…

vite1.x 热更新(HMR)的实现原理

前言 将近一年前自己尝试阅读vite源码(2.x),虽然也有些收获但整体并没有到达我的预期,对于vite也是停留在一知半解的程度上。最近想重新开始学习vite,但回顾之前的学习历程,感觉不太想继续之前的方式&…

Webpack HMR 原理解析

Hot Module Replacement(以下简称 HMR)是 webpack 发展至今引入的最令人兴奋的特性之一 ,当你对代码进行修改并保存后,webpack 将对代码重新打包,并将新的模块发送到浏览器端,浏览器通过新的模块替换老的模…

Webpack的HMR原理解析

Hot Module Replacement(以下简称 HMR)是 webpack 发展至今引入的最令人兴奋的特性之一 ,当你对代码进行修改并保存后,webpack 将对代码重新打包,并将新的模块发送到浏览器端,浏览器通过新的模块替换老的模…

Esbuild Bundler HMR

Esbuild 虽然 bundler 非常快,但是其没有提供 HMR 的能力,在开发过程中只能采用 live-reload 的方案,一有代码改动,页面就需要全量 reload ,这极大降低开发体验。为此添加 HMR 功能至关重要。 经过调研,社…

Vite HMR

传统webpack的hmr是使用webpack的HotModuleReplacementPlugin,而vite则是采用native ES Module的devServer。 初始化本地服务器加载并运行对应的plugin 最重要的一件事就是运行plugin,目前vite支持的plugin大体如下图所示 1、建立ViteDevServer服务器…

webpack HMR

HMR或者hot模式下,启动webpack会在浏览器与服务器之间会建立一个websocket连接,使得浏览器可以和服务端建立全双工通信;当应用程序的代码更新时,会要求HMR runtime检查更新,有更新时,在websoket连接中会返回…

webpack中的HMR(热更新)原理剖析

简介 Hot Module Replacement(以下简称 HMR)是 webpack 发展至今引入的最令人兴奋的特性之一 ,当你对代码进行修改并保存后,webpack 将对代码重新打包,并将新的模块发送到浏览器端,浏览器通过新的模块替换…

HMR(热替换)

HMR 即模块热替换(hot module replacement)的简称,它可以在应用运行的时候,不需要刷新页面,就可以直接替换、增删模块。webpack 可以通过配置 webpack.HotModuleReplacementPlugin 插件来开启全局的 HMR 能力&#xff…

面试官:说说Webpack的热更新是如何做到的?原理是什么?

一、是什么 HMR全称 Hot Module Replacement,可以理解为模块热替换,指在应用程序运行过程中,替换、添加、删除模块,而无需重新刷新整个应用 例如,我们在应用运行过程中修改了某个模块,通过自动刷新会导致整…