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

时间:2014-07-05 00:13:56

标签: javascript module livereload webpack

我在Webpack上阅读了关于热模块替换的few pages 甚至有sample app uses it

我已经阅读了所有这些并且仍然没有得到这个想法。

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

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

3 个答案:

答案 0 :(得分:314)

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

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

文档

Prerequirements:

与HMR不同,但这里有链接:

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

它是如何工作的?

从应用视图

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

从编译器(webpack)视图

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

  1. 更新清单(json)
  2. 一个或多个更新块(js)
  3. 清单包含新的编译哈希和所有更新块的列表(2)。

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

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

    从模块视图

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

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

    从HMR运行时视图(技术)

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

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

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

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

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

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

    generated update chunks

    我该怎么办?

    您可以在开发中将其用作LiveReload替代品。实际上,webpack-dev-server支持热模式,尝试在尝试重新加载整个页面之前使用HMR进行更新。您只需要添加webpack/hot/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作为入口点。否则,您需要一些调用checkapply的HMR管理代码。

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

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

    注意事项

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

答案 1 :(得分:6)

接受的答案通过以下描述来解释一切正确有助于快速了解什么是HMR。

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

在搜索HMR时,我发现article在互联网上解释了这个概念,你可以从这里得到它并添加一个GIF图像来解释这个概念而没有太多解释。

这里正在工作 - 请注意,计时器不会像重新加载页面那样重置为0,而css也会更改自动刷新。 Hot Module Replacement GIF

Webpack有助于实现HMR。您可以找到文档here

有助于实现以下目标

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

  • 只需更新已更改的内容,即可节省宝贵的开发时间。

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

Here是实现HMR

的网络包指南

答案 2 :(得分:0)

热模块更换(HMR)是自动实时更新DEVELOPMENT服务器的工具。它监视文件更改,并告诉浏览器替换特定模块或元素,而无需重新加载整个页面。 (例如样式加载程序,它无需引用即可更新您的CSS)    HMR是webpacks的内置插件。 在index.js中,添加以下配置:

if(module.hot){
   module.hot.accept();
}

或通过

npm install react-hot-loader

HMR的优点:

  • 当您调试代码时,语句将保留在控制台中,因为浏览器不再引用页面。
  • 刷新页面令人头疼。您必须等到页面加载完毕,在大型应用程序中可能要花几秒钟的时间。 HMR可提高生产率。
  • 您可以使用HMR保持应用程序状态