ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

每天一道面试题(14) - webpack热更新使用及其原理

2021-10-15 19:59:02  阅读:211  来源: 互联网

标签:面试题 14 hot 更新 server webpack dev 模块


文章目录

为什么需要热更新

在文件更新时, 希望能保持页面当前的状态值, 而不是直接刷新页面, 可以大大节省宝贵的开发调试时间

使用热更新以及遇到的问题

使用热更新

  • 第一种方案, 使用module.hot.accept()
if (module.hot) {
	module.hot.accept()
}

axios响应拦截器中返回的响应参数是上次拦截器返回的数据

原因是什么呢?

因为module.hot.accept()意思是重新执行一遍当前的模块, 所以axios的拦截器也被执行了

改成如下这样之后, 就不会执行axios的拦截器代码, 而是重新执行组件App的挂载

if (module.hot) {
	//如果accept传了依赖, 只会执行依赖对应的回调
	module.hot.accept('./App', () => {
		ReactDOM.render(<App />, document.getElementById('root'))
	})
}
  • 第二种方案: 使用react-hot-loader
    在Router文件中配置
import { hot } from 'react-hot-loader/root';
const Routes = () => {};
export default hot(Routes);

构建过程

首先来看下webpack在数据更新时的构建过程

  • webpack首次工作时会生成一个hash
  • 当更改数据之后hash改变并且多了两份文件
app.0cf25fbc9badf70fb401.hot-update.js
app.0cf25fbc9badf70fb401.hot-update.json

这个0cf25fbc9badf70fb401hash值其实就是更改前上一次的hash. 上一次的hash值作为了更新后下一次新生成文件的标识

hot-update.json会返回要更新的模块和新的hash值

热更新原理

参考链接: Webpack HMR 原理解析

  • 第一步,在 webpack 的 watch 模式下,文件系统中某一个文件发生修改,webpack 监听到文件变化,根据配置文件对模块重新编译打包,并将打包后的代码通过简单的 JavaScript 对象保存在内存中。
  • 第二步是 webpack-dev-server 和 webpack 之间的接口交互,而在这一步,主要是 dev-server 的中间件 webpack-dev-middleware 和 webpack 之间的交互,webpack-dev-middleware 调用 webpack 暴露的 API对代码变化进行监控,并且告诉 webpack,将代码打包到内存中。
  • 第三步是 webpack-dev-server 对文件变化的一个监控,这一步不同于第一步,并不是监控代码变化重新打包。当我们在配置文件中配置了devServer.watchContentBase 为 true 的时候,Server 会监听这些配置文件夹中静态文件的变化,变化后会通知浏览器端对应用进行 live reload。注意,这儿是浏览器刷新,和 HMR 是两个概念。
  • 第四步也是 webpack-dev-server 代码的工作,该步骤主要是通过 sockjs(webpack-dev-server 的依赖)在浏览器端和服务端之间建立一个 websocket 长连接,将 webpack 编译打包的各个阶段的状态信息告知浏览器端,同时也包括第三步中 Server 监听静态文件变化的信息。浏览器端根据这些 socket 消息进行不同的操作。当然服务端传递的最主要信息还是新模块的 hash 值,后面的步骤根据这一 hash 值来进行模块热替换。
  • webpack-dev-server/client 端并不能够请求更新的代码,也不会执行热更模块操作,而把这些工作又交回给了 webpack,webpack/hot/dev-server 的工作就是根据 webpack-dev-server/client 传给它的信息以及 dev-server 的配置决定是刷新浏览器呢还是进行模块热更新。当然如果仅仅是刷新浏览器,也就没有后面那些步骤了。
  • HotModuleReplacement.runtime 是客户端 HMR 的中枢,它接收到上一步传递给他的新模块的 hash 值,它通过 JsonpMainTemplate.runtime 向 server 端发送 Ajax 请求,服务端返回一个 json,该 json 包含了所有要更新的模块的 hash 值,获取到更新列表后,该模块再次通过 jsonp 请求,获取到最新的模块代码。这就是上图中 7、8、9 步骤。
  • 而第 10 步是决定 HMR 成功与否的关键步骤,在该步骤中,HotModulePlugin 将会对新旧模块进行对比,决定是否更新模块,在决定更新模块后,检查模块之间的依赖关系,更新模块的同时更新模块间的依赖引用。
  • 最后一步,当 HMR 失败后,回退到 live reload 操作,也就是进行浏览器刷新来获取最新打包代码。

标签:面试题,14,hot,更新,server,webpack,dev,模块
来源: https://blog.csdn.net/weixin_37719279/article/details/120789769

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有