Webpack & The Hot Module Replacement热模块替换原理解析

Webpack & The Hot Module Replacement热模块替换原理解析

The Hot Module Replacement(HMR)俗称热模块替换。主要用来当代码产生变化后,可以在不刷新游览器的情况下对局部代码块进行替换更新。这在很多情况下都很有用,例如在处理弹出框时,使用HMR可以及时的看到变化,如果用刷新游览器的方式会回到初始页面。

很多人使用过HMR却不知道它是如何工作的,这里会对HMR实现原理进行解析。

关于HMR需要知道的一些事

  • HMR是Webpack的一个可选功能,如果想使用需要主动打开。
  • 需要通过webpack-dev-server方式来管理webpack(另一种方式是CLI)
  • HMR只能工作在实现了HMR API的loaders里,例如:‘style-loader’,‘react-hot-loader‘
  • HMR只能在开发环境中使用,因为HMR会在打包的js中添加了很多额外的代码,并且webpack-dev-server也只用于开发环境。

HMR工作原理

webpack会在打包的js中注入很多js库来让HMR工作,下图展示了当一个文件发生变化是HMR是如何工作的。

图片颜色说明:

紫色:发生改变的js或者css文件

橘色:发生变化的代码块说明,变化后的代码块内容

彩兰色:项目代码

绿色:webpack-dev-server相关的库,有图中可以发现,webpack-dev-server主要负责server端和游览器端的通信。

蓝色:webpack核心和插件库,由图中可以发现,server端代码的监听以及游览器端新代码的替换都是由webpack的不同模块处理。

红色:react-loader或者style-loader等HMR库

执行流程:

  1. 当监听到文件发生变化时,webpack 使用HotModuleReplacementPlugin生成一个mainifest(一个json结构描述了发生变化的modules列表)和update file(一个js文件包含修改后的代码内容)
  2. webpack将上述变化信息告诉webpack-dev-server
  3. webpack-dev-server通过webSocket给运行在游览器上的‘webpack-dev-server/client’(在打包时注入的js代码)发送一条‘invalide’信息以及更新后代码的hash值(该hash值本次不会用到,使用上一版本的hash值).
  4. ’webpack-dev-server/client’会将上一版本代码的hash传递给“hot/dev-server”
  5. ‘hot/dev-server’使用JsonpRuntime向server端发送带有上版本hash的ajax请求,server端返回一个json,该json包含要所有要更新的模块的hash值。
  6. JsonpRuntime根据返回的json值使用jsonp请求具体的代码块,jsonp返回的js代码类似下面:
webpackHotUpdate(0,{ 82:  function(module, exports, __webpack_require__) {    exports = module.exports = __webpack_require__(79)();    exports.push([module.id, “input {\n background: pink;\n}”, “”])  }})
  1. 代码会调用webpackHotUpdate方法并携带module_id和具体修改内容。
  2. HMR runtime本身并不会处理代码修改,它会将不同文件交给对应的loader runtime处理(例如:react-hot-loader runtime 或者 style-loader runtime)
  3. 如果更新失败,会回退刷新游览器获取最新代码。

示例

当游览器首次加载app时,server端会推送当前代码版本号current_hash。

当修改style文件后,server端HotModuleReplacementPlugin会根据更新内容生成manifest和js文件,文件名根据current_hash生成,然后更新current_hash,并将新的hash值推送给游览器端,用作下次更新。

游览器端webpack-dev-server/client接收到新的hash值后,会将previous hash值传递给webpack/hot/dev-server,dev-server根据previous hash请求具体的mainifest和js代码,并使用jsonp更新。

参考文档:

Webpack & The Hot Module Replacement

Webpack HMR原理解析

原文地址:https://www.cnblogs.com/chenkeyu/p/10801197.html

时间: 2024-08-05 11:45:19

Webpack & The Hot Module Replacement热模块替换原理解析的相关文章

webpack的Hot Module Replacement运行机制

使用webpack打包,难免会使用Hot Module Replacement功能,该功能能够实现修改.添加或删除前端页面中的模块代码,而且是在页面不刷新的前提下.它究竟是怎么运作的呢?本文主要从调试工具.配置文件.官方文档三个方面进行解析. 调试工具 首先从chrome的调试工具network中看看,代码改变的时候,页面与后端之间发生了什么? 页面初始加载 我们看到除了加载页面所依赖的文件外,多了一个连接,这是一个Server-sent Events,相关的介绍可以参考这篇文章,而且每隔一段时

webpack——Modules && Hot Module Replacement

blog:JavaScript Module Systems Showdown: CommonJS vs AMD vs ES2015 官网链接: Modules 官网链接:Hot Module Replacement(概念) 官网链接:Hot Module Replacement(API) Modules In modular programming, developers break programs up into discrete chunks of functionality calle

webpack-Hot Module Replacement(热更新)

模块热替换(Hot Module Replacement) 模块热替换(HMR - Hot Module Replacement)功能会在应用程序运行过程中替换.添加或删除模块,而无需重新加载整个页面.主要是通过以下几种方式,来显著加快开发速度: 保留在完全重新加载页面时丢失的应用程序状态. 只更新变更内容,以节省宝贵的开发时间. 调整样式更加快速 - 几乎相当于在浏览器调试器中更改样式. 这一切是如何运行的? 让我们从一些不同的角度观察,以了解 HMR 的工作原理…… 在应用程序中 通过以下步

webpack学习之—— 模块热替换(Hot Module Replacement)

模块热替换(HMR - Hot Module Replacement)功能会在应用程序运行过程中替换.添加或删除模块,而无需重新加载整个页面.主要是通过以下几种方式,来显著加快开发速度: 保留在完全重新加载页面时丢失的应用程序状态. 只更新变更内容,以节省宝贵的开发时间. 调整样式更加快速 - 几乎相当于在浏览器调试器中更改样式. 在应用程序中 通过以下步骤,可以做到在应用程序中置换(swap in and out)模块: 应用程序代码要求 HMR runtime 检查更新. HMR runti

A Beginner’s Guide to Webpack 4 and Module Bundling

原文: https://www.sitepoint.com/beginners-guide-webpack-module-bundling/ ----------------------------------------------------------------- This article is featured in our book, Modern JavaScript Tools & Skills. Get familiar with the essential tools tha

webpack里的module选项配置

webpack里的module 有loaders选项和noParse选项,noParse选项配置不需要解析的目录和文件 module:{ loaders:[], noParse: [ path.join(__dirname + '/client/node_modules/jquery/'), path.join(__dirname + '/client/lib/**') ] }

webpack:Cannot find module 'extract-text-webpack-plugin'

问题: 在终端中使用此命令安装了extract-text-webpack-plugin,npm install -g extract-text-webpack-plugin并在webpack.config.js文件中导入,但是运行终端npm run build后,仍然收到错误显示:Cannot find module 'extract-text-webpack-plugin'. 原因: extract-text-webpack-plugi不是全局安装 解决方法: 1.添加-g标志来安装packa

webpack 模块标识符(Module Identifiers)

让我们向项目中再添加一个模块 print.js: project webpack-demo |- package.json |- webpack.config.js |- /dist |- /src |- index.js + |- print.js |- /node_modules print.js + export default function print(text) { + console.log(text); + }; src/index.js import _ from 'loda

webpack最简单的入门教程里bundle.js之运行单步调试的原理解析

读这篇文章的朋友,请确保对webpack有最基础的认识. 您可以阅读我前一篇文章:Webpack 10分钟入门 来在本地运行一个Webpack的hello world项目.https://www.toutiao.com/i6612879647568822788/ 我这里可以在回顾一下这个web pack的hello world项目. 用webpack打包之后,项目文件夹里包含了这些资源: index.html的源代码很简单,就包含了一个webpack打包后生成的bundle.js文件: 那么运行