我已经阅读了几 页关于 Webpack 中的热模块替换的内容。 甚至还有一个使用它的示例应用程序。 我已经阅读了所有这些,但仍然不明白。
我能用它做什么?
假设我想在将 CSS(一个样式表)和 JS 模块保存到磁盘时更新它们,而不需要重新加载页面并且不使用 LiveReload 等插件。这是热模块更换可以帮助我吗?我需要做什么样的工作,HMR 已经提供了什么?
首先,我想指出热模块更换 (HMR) 仍然是一个实验性功能。
HMR 是一种在正在运行的应用程序中交换模块(以及添加/删除模块)的方式。您基本上可以在不重新加载整个页面的情况下更新更改的模块。
先决条件:
这对 HMR 来说不是很多,但这里是链接:
我会将这些答案添加到文档中。
应用程序代码要求 HMR 运行时检查更新。HMR 运行时下载更新(异步)并告诉应用程序代码有可用的更新。应用程序代码要求 HMR 运行时应用更新。HMR 运行时应用更新(同步)。应用程序代码在此过程中可能需要也可能不需要用户交互(您决定)。
除了普通资产之外,编译器需要发出“更新”以允许从以前的版本更新到此版本。“更新”包含两部分:
清单包含新的编译哈希和所有更新块的列表 (2)。
更新块包含此块中所有更新模块的代码(如果模块被删除,则包含一个标志)。
编译器还确保模块和块 ID 在这些构建之间是一致的。它使用“记录” json 文件在构建之间存储它们(或者将它们存储在内存中)。
HMR 是一个可选功能,因此它只影响包含 HMR 代码的模块。该文档描述了模块中可用的 API。通常,模块开发人员编写在更新此模块的依赖项时调用的处理程序。他们还可以编写一个在更新此模块时调用的处理程序。
在大多数情况下,不必在每个模块中编写 HMR 代码。如果模块没有 HMR 处理程序,则更新会冒泡。这意味着单个处理程序可以处理完整模块树的更新。如果更新此树中的单个模块,则重新加载完整的模块树(仅重新加载,不传输)。
为模块系统运行时发出附加代码以跟踪模块parents和children.
parents
children
在管理方面,运行时支持两种方法:check和apply.
check
apply
Acheck向更新清单发出 HTTP 请求。当此请求失败时,没有可用的更新。否则,更新的块列表将与当前加载的块列表进行比较。对于每个加载的块,都会下载相应的更新块。所有模块更新都作为更新存储在运行时中。运行时切换到ready状态,这意味着更新已下载并准备好应用。
ready
对于处于就绪状态的每个新块请求,也会下载更新块。
该apply方法将所有更新的模块标记为无效。对于每个无效模块,模块中都需要有一个更新处理程序,或者每个父模块中都需要有一个更新处理程序。否则无效会冒泡并将所有父母也标记为无效。这个过程一直持续到不再发生“冒泡”。如果它冒泡到一个入口点,则该过程将失败。
现在所有无效模块都被处理(处理处理程序)并卸载。然后更新当前哈希并调用所有“接受”处理程序。运行时切换回idle状态,一切都照常进行。
idle
您可以在开发中使用它作为 LiveReload 的替代品。实际上 webpack-dev-server 支持热模式,它会在尝试重新加载整个页面之前尝试使用 HMR 进行更新。您只需要添加webpack/hot/dev-server入口点并使用--hot.
webpack/hot/dev-server
--hot
您还可以在生产中使用它作为更新机制。在这里,您需要编写自己的管理代码,将 HMR 与您的应用程序集成。
一些加载器已经生成了可热更新的模块。例如,style-loader可以交换样式表。你不需要做任何特别的事情。
style-loader
假设我想在将 CSS(一个样式表)和 JS 模块保存到磁盘时更新它们,而不需要重新加载页面并且不使用 LiveReload 等插件。这是热模块更换可以帮助我吗?
是的
我需要做什么样的工作,HMR 已经提供了什么?
这是一个小例子:https ://webpack.js.org/guides/hot-module- replacement/
一个模块只有在你“接受”它的情况下才能被更新。所以你需要module.hot.accept在模块的父母或父母的父母… 例如路由器是一个好地方,或一个子视图。
module.hot.accept
如果您只想将它与 webpack-dev-server 一起使用,只需添加webpack/hot/dev-server为入口点。否则,您需要一些 HMR 管理代码来调用check和apply.
if(module.hot)
records