[译]webpack官网文档 :概念 -- 11.模块热替换 (完)

原创翻译,转载请注明出处。 

原文地址:https://webpack.js.org/concepts/hot-module-replacement/

 

模块热替换(Hot Module Replacement/HMR),用来在一个运行中的应用里变换,增加和删除模块,而不需要页面再加载。这使变更一个模块的时候,不用通过刷新页面而更新这个模块,提高了开发的速度。

 

它是怎样工作的?

以应用视点

  1. 应用代码要求运行期HMR检查更新。
  2. 运行期HMR下载更新(异步),并告诉应用code发现了一个更新。
  3. 应用code要求运行期HMR实施更新。
  4. 运行期HMR实施(同步)

你可以通过设定HMR使这个过程自动执行,或者你可以选择在发生更新的时候请求用户交互。

 

以编译器(webpack)视点

除了正常的资源以外,编译器需要发出一个“update”来实现旧版本到新版本的更新。这个“update”包含了两部分:

  1. 更新清单(JSON
  2. 一个或多个更新代码块(JavaScript

更新清单包含一个新的编译哈希值和一个包含所有更新代码块的一览。

每一个更新代码块包含了存在于各自代码块里的被更新模块(或者一个表示模块被移除的标识符)

编译器确保在每次构建过程中模块ID和代码块ID一致。它通常把这些ID保存在内存中(例如,当使用webpack-dev-server的时候),但是也可以把它们存储在JSON文件中。

 

以模块视点

HMR是一个可选择使用的特性,它只影响包含HMR代码的模块。一个例子是通过style-loader来引入样式。为了让它有效,style-loader实现了HMR接口;当它通过HMR接收到一个更新的时候,用新的样式来替代旧的样式。

同样的,当一个模块实现了HMR接口的时候,你可以描述当发生更新的时候应该发生什么。

然而,在大多数情况下,并不强制在每一个模块里写HMR代码。如果一个模块没有HMR处理程序,更新就向上冒泡。这就意味着一个处理程序可以对完整的模块树进行更新。如果在这个模块树里的一个模块被更新了的话,这个模块树被重新载入(只是被重新载入,不是被更换)

 

以运行期HMR视点(技术上的)

对于模块系统运行期,会产生附加代码来跟踪父模块和子模块。

在管理方面,运行期支持两个方法:checkapply

  • Check发出对更新清单的HTTP请求。如果请求失败了,就是没有更新。如果成功了的话,对被更新代码块的列表和现在已经加载的代码块列表进行比较。对每一个已加载的代码块,下载相对应的更新代码块。所有的模块更新都保存在运行期里。当所有更新代码块都被下载完并准备好实施,运行期转入ready状态。
  • apply方法把所有更新过的模块标识为无效。对每一个无效模块,都需要一个在模块里或者在它父模块里的更新处理程序。另外,无效标识符会向上冒泡,使它的父模块也变为无效。每个冒泡一直持续到应用的入口点,或者到达一个带有更新处理程序的模块(看哪个先发生)。如果它从入口点开始冒泡,那么处理失败。

然后,所有的无效模块都被销毁(通过销毁处理程序)并被卸载掉。然后更新现在的哈希值,并且调用所有的accept处理程序。运行期切换回idle状态,一切正常继续。

 

能用它做什么?

可以在开发过程中实时再加载/替换来使用。webpack-dev-server支持一种热模式,它在试图再加载整个页面之前,尝试使用HMR加载更新部分。参照在React里实施HMR的例子。

一些加载器已经生成了可热更新的模块。例如,style-loader可以置换出一个页面的样式表。像这样的模块,你不需要做任何特别的事情。

 

Webpack的强大在于它的可定制,并且根据每个项目不同需求,有很多方法来配置HMR

 

-- End --

 

猜你喜欢

转载自stef.iteye.com/blog/2361385
今日推荐