Webpack中的热模块替换到底是什么?

我读过一个关于Webpack热模块替换的 页面。< br / > 甚至有一个样例应用程序 使用它.

. 0

我读了所有这些,但还是不明白。

我能用它做什么?

  1. 它是否应该只用于开发而不用于生产?
  2. 它是否像LiveReload,但你必须自己管理它?
  3. WebpackDevServer是否以某种方式与liverload集成?

假设我想在将CSS(一个样式表)和JS模块保存到磁盘时更新它们,而不需要重新加载页面,也不需要使用liverload等插件。这是热模块更换可以帮助我吗?我需要做什么样的工作,HMR已经提供了什么?

63830 次浏览

首先,我想指出热模块替换(HMR)仍然是一个实验特性。

HMR是一种在运行的应用程序中交换模块(以及添加/删除模块)的方法。基本上,您可以在不重新加载整个页面的情况下更新更改的模块。

文档

Prerequirements:

这不是关于HMR的,但这里有链接:

我将把这些答案添加到文档中。

它是如何工作的?

从应用程序视图

应用程序代码要求HMR运行时检查更新。HMR运行时下载更新(异步),并告诉应用程序代码有更新可用。应用程序代码要求HMR运行时应用更新。HMR运行时应用更新(同步)。应用程序代码在此过程中可能需要用户交互,也可能不需要(由您决定)。

从编译器(webpack)视图

除了正常的资产,编译器还需要发出"Update"允许从以前的版本更新到此版本。“Update"包含两部分:

  1. 更新清单(json)
  2. 一个或多个更新块(js)

清单包含新的编译散列和所有更新块的列表(2)。

更新块包含该块中所有更新模块的代码(如果模块被删除,则包含一个标记)。

编译器还确保这些构建之间的模块和块id是一致的。它使用&;records&;Json文件在构建之间存储它们(或将它们存储在内存中)。

从模块视图

HMR是一个可选特性,因此它只影响包含HMR代码的模块。文档描述了模块中可用的API。通常,模块开发人员编写的处理程序将在此模块的依赖项更新时调用。它们还可以编写一个处理程序,当该模块更新时调用该处理程序。

在大多数情况下,在每个模块中编写HMR代码并不是强制性的。如果模块没有HMR处理程序,则会弹出更新。这意味着单个处理程序可以处理完整模块树的更新。如果这个树中的一个模块被更新,整个模块树将被重新加载(只是重新加载,而不是传输)。

从HMR运行时视图(技术)

为模块系统运行时发出附加代码来跟踪模块parentschildren

在管理端,运行时支持两种方法:checkapply

check对更新清单执行HTTP请求。当此请求失败时,没有可用的更新。否则,更新的块列表将与当前加载的块列表进行比较。对于每个加载的块,都会下载相应的更新块。所有模块更新都作为更新存储在运行时中。运行时切换到ready状态,这意味着更新已经下载并准备应用。

对于处于就绪状态的每个新块请求,也会下载更新块。

apply方法将所有更新的模块标记为无效。对于每个无效模块,需要在模块中有一个更新处理程序,或者在每个父模块中有一个更新处理程序。否则无效气泡,并标记所有父母无效。这一过程一直持续到不再有“气泡”;发生。如果它冒泡到入口点,则流程失败。

现在所有无效的模块都被处置(处置处理程序)并卸载。然后更新当前哈希值,所有&;accept"调用处理程序。运行时切换回idle状态,一切继续正常。

generated update chunks

我能用它做什么?

您可以在开发中使用它作为liverload的替代品。实际上webpack-dev-server支持热模式,即在重新加载整个页面之前尝试使用HMR进行更新。你只需要添加webpack/hot/dev-server入口点,并用--hot调用dev-server。

您还可以在生产中使用它作为更新机制。在这里,您需要编写自己的管理代码,将HMR集成到应用程序中。

一些加载器已经生成了可热更新的模块。例:style-loader可以交换样式表。你不需要做任何特别的事情。

假设我想在将CSS(一个样式表)和JS模块保存到磁盘时更新它们,而不需要重新加载页面,也不需要使用liverload等插件。这是热模块更换可以帮助我吗?

是的

我需要做什么样的工作,HMR已经提供了什么?

这里有一个小例子:https://webpack.js.org/guides/hot-module-replacement/

只有当您“接受”;它。所以你需要module.hot.accept父模块或父模块的父模块…路由器是一个好地方,或者是一个子视图。

如果你只想在webpack-dev-server中使用它,只需添加webpack/hot/dev-server作为入口点。否则你需要一些HMR管理代码来调用checkapply

观点:是什么让它这么酷?

  • 它是LiveReload,但对每个模块都适用。
  • 您可以在生产中使用它。
  • 更新尊重你的代码分割,只下载更新你的应用程序使用的部分。
  • 您可以将它用于应用程序的一部分,并且它不会影响其他模块
  • 如果HMR被禁用,编译器将删除所有HMR代码(将其包装在if(module.hot)中)。

警告

  • 这是实验性的,没有经过很好的测试。
  • 预计会有一些bug。
  • 理论上可以在生产中使用,但现在将其用于一些重要的事情可能还为时过早。
  • 需要在编译之间跟踪模块id,因此需要存储它们(records)。
  • 在第一次编译之后,优化器不能再优化模块id。对捆绑包大小有一点影响。
  • HMR运行时代码增加了包的大小。
  • 对于生产使用,需要额外的测试来测试HMR处理程序。这可能相当困难。

虽然公认的答案正确地解释了一切,但下面的描述应该有助于更快地理解HMR是什么。

本质上(简单地说!)- 它通过在运行时用更改替换模块来减少页面刷新的数量,从而帮助开发

在搜索HMR时,我发现了一个文章,解释了这个概念,但它很长,所以这里有一个GIF图像,解释了这个概念,没有很多词。

这里它在工作-注意,计时器不会重置为0,因为它会在页面重新加载后,CSS改变自动刷新。 热模块替换GIF < / p >

Webpack有助于实现HMR。你可以找到docs 在这里

它有助于实现以下目标:

  • 在重载期间保留应用程序状态(在没有HMR的情况下总是丢失)

  • 通过只更新已更改的内容来节省宝贵的开发时间。

  • 更快地调整样式——几乎可以与在浏览器的调试器中更改样式相媲美。

在这里是webpack实现HMR的指南