Webpack中的热模块更换究竟是什么?

Dan*_*mov 194 javascript module livereload webpack

我已经阅读了 关于Webpack中的热模块替换的内容.
甚至还有一个示例应用程序使用它.

我已经阅读了所有这些,仍然没有得到这个想法.

我该怎么办?
它应该只用于开发而不是生产吗?
它是否像LiveReload,但你必须自己管理它?
WebpackDevServer是否以某种方式与它集成?

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

Tob*_* K. 333

首先,我想指出热模块更换(HMR)仍然是一个实验性功能.

HMR是一种在正在运行的应用程序中交换模块(以及添加/删除模块)的方法.您基本上可以更新已更改的模块而无需重新加载整页.

文档

Prerequirements:

这不是HMR,但这里是链接:

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

它是如何工作的?

从应用程序视图

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

从编译器(webpack)视图

除了普通资产之外,编译器还需要发出"更新"以允许从先前版本更新到此版本."更新"包含两部分:

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

清单包含新的编译哈希和所有更新块的列表(2).

更新块包含此块中所有更新模块的代码(如果删除了模块,则包含标志).

编译器还确保模块和块ID在这些构建之间是一致的.它使用"记录"json文件在构建之间存储它们(或者将它们存储在内存中).

从模块视图

HMR是一个选择加入功能,因此它只影响包含HMR代码的模块.该文档描述了模块中可用的API.通常,模块开发人员编写在更新此模块的依赖关系时调用的处理程序.他们还可以编写在更新此模块时调用的处理程序.

在大多数情况下,并不是必须在每个模块中编写HMR代码.如果模块没有HMR处理程序,则更新会冒泡.这意味着单个处理程序可以处理完整模块树的更新.如果更新此树中的单个模块,则重新加载完整的模块树(仅重新加载,不传输).

从HMR运行时视图(技术)

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

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

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

对于处于就绪状态的每个新块请求,还下载更新块.

apply方法将所有更新的模块标记为无效.对于每个无效模块,模块中需要有更新处理程序或更新每个父模块中的处理程序.否则无效的气泡会将所有父母标记为无效.这个过程一直持续到不再出现"冒泡".如果它冒泡到入口点,则该过程失败.

现在所有无效模块都被丢弃(处理处理程序)并卸载.然后更新当前哈希并调用所有"接受"处理程序.运行时切换回idle状态,一切都正常.

生成更新块

我该怎么办?

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

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

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

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

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

这是一个小例子:http://webpack.github.io/docs/hot-module-replacement-with-webpack.html

只有在您"接受"模块时才能更新模块.所以你需要module.hot.accept父母的模块或父母的父母......例如路由器是一个好地方或子视图.

如果您只想将它​​与webpack-dev-server一起使用,只需添加webpack/hot/dev-server为入口点即可.否则你需要一些调用check和调用的HMR管理代码apply.

意见:是什么让它如此酷?

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

注意事项

  • 它是实验性的,未经过如此好的测试.
  • 期待一些错误.
  • 理论上可用于生产,但将它用于严重的事情可能为时尚早.
  • 需要在编译之间跟踪模块ID,因此您需要存储它们(records).
  • 第一次编译后,优化器无法再优化模块ID.对包大小有点影响.
  • HMR运行时代码增加了包大小.
  • 对于生产用途,需要额外的测试来测试HMR处理程序.这可能非常困难.

  • 一个地狱的答案. (97认同)
  • 再次感谢您的解释,我[制作了一个视频](https://twitter.com/dan_abramov/status/485611717183819776)展示了HMR的强大功能来实时编辑React应用程序. (10认同)
  • 我将这个答案复制到文档中:http://webpack.github.io/docs/hot-module-replacement-with-webpack.html (4认同)
  • 当您在try-catch块中的HMR更新处理程序中包含`require`时,您可以捕获更新模块中的错误. (2认同)

sam*_*j90 8

无论如何,接受的答案将说明所有正确的内容,以下说明有助于快速了解什么是HMR。

热模块替换是javascript开发中的最新技术之一,吸引了开发人员的注意。它通过在运行时更改模块来减少页面刷新次数,从而有助于开发。

在搜索HMR时,我发现了一篇文章,解释了Internet上的概念,您可以从这里获得它,并添加一个无需过多解释即可解释该概念的GIF图像。

这是在起作用–请注意,计时器不会像重新加载页面后那样重置为0,并且CSS也更改为自动刷新。 热模块更换GIF

Webpack帮助实现HMR。您可以在这里找到文档

它有助于实现关注

  • 保留在完全重载期间丢失的应用程序状态。

  • 仅更新更改内容即可节省宝贵的开发时间。

  • 调整样式的速度更快-几乎可以与浏览器调试器中样式的更改相提并论。

是实现HMR的Webpack指南

  • 多么棒、简单、直接的答案,礼物更好地解释了 1000 个单词 (3认同)