首页 文章

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

提问于
浏览
161

我在Webpack中读过关于热模块替换的few pages .
甚至还有一个sample app .

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

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

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

2 回答

  • 2

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

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

    文档

    Prerequirements:

    它不是HMR,而是链接:

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

    它是如何工作的?

    从应用视图

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

    从编译器(webpack)视图

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

    • 更新清单(json)

    • 一个或多个更新块(js)

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

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

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

    从模块视图

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

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

    来自HMR运行时视图(技术)

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

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

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

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

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

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

    generated update chunks

    我该怎么办?

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

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

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

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

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

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

    只有"accept"模块才能更新模块 . 所以你需要在父母或父母的父母那里使用模块......例如路由器是一个好地方或子视图 .

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

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

    • 这是LiveReload但是对于每种模块类型 .

    • 您可以在 生产环境 中使用它 .

    • 这些更新会尊重您的代码拆分,并且只会下载您应用的已使用部分的更新 .

    • 您可以将它用于应用程序的一部分,但不会影响其他模块

    • 如果禁用HMR,编译器将删除所有HMR代码(将其包装在 if(module.hot) 中) .

    警告

    • 这是实验性的,未经过如此好的测试 .

    • 期待一些错误 .

    • 理论上可用于 生产环境 ,但将它用于严肃的事情可能为时尚早 .

    • 需要在编译之间跟踪模块ID,因此您需要存储它们( records ) .

    • 优化器在第一次编译后无法再优化模块ID . 对捆绑大小有点影响 .

    • HMR运行时代码增加了包大小 .

    • 对于 生产环境 用途,需要进行额外测试以测试HMR处理程序 . 这可能非常困难 .

  • 293

    无论如何,接受的答案都会使一切正确无误,以下描述有助于快速了解什么是HMR .

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

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

    这是工作 - 请注意,计时器不会像页面重新加载后那样重置为0,而css也会更改自动刷新 .

    Webpack有助于实现HMR . 你可以找到文档here

    它有助于实现以下目标

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

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

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

    Here是实现HMR的webpack指南

相关问题