webpack热更新原理
来源:互联网 发布:网络信息科技经营范围 编辑:程序博客网 时间:2024/06/04 17:47
开发环境页面热更新早已是主流,常见的需求如赛事网页推送比赛结果、网页实时展示投票或点赞数据、在线评论或弹幕、在线聊天室等,都需要借助热更新功能,才能达到实时的端对端的极致体验。
webpack-hot-middleware
webpack-hot-middleware
中间件是webpack的一个plugin,通常结合webpack-dev-middleware一起使用。借助它可以实现浏览器的无刷新更新(热更新),即webpack里的HMR(Hot Module Replacement)。如何配置请参考 webpack-hot-middleware,如何理解其相关插件请参考 手把手深入理解 webpack dev middleware 原理與相關 plugins。
webpack加入webpack-hot-middleware后,内存中的页面将包含HMR相关js,加载页面后,Network栏可以看到如下请求:
__webpack_hmr是一个type为EventSource的请求, 从Time栏可以看出:默认情况下,服务器每十秒推送一条信息到浏览器。
如果此时关闭开发服务器,浏览器由于重连机制,将持续抛出类似GET http://www.test.com/__webpack_hmr 502 (Bad Gateway)
这样的错误。重新启动开发服务器后,重连将会成功,此时便会刷新页面。以上这些便是我们使用时感受到的最初的印象。当然,停留在使用层面不是我们的目标,接下来我们将跳出该中间件,讲解其所使用到的EventSource技术。
EventSource
EventSource 不是一个新鲜的技术,它早就随着H5规范提出了,正式一点应该叫Server-sent events,即SSE。鉴于传统的通过ajax轮训获取服务器信息的技术方案已经过时,我们迫切需要一个高效的节省资源的方式去获取服务器信息,一旦服务器资源有更新,能够及时地通知到客户端,从而实时地反馈到用户界面上。EventSource就是这样的技术,它本质上还是HTTP,通过response流实时推送服务器信息到客户端。
客户端新建一个EventSource对象非常简单。
const es = new EventSource('/message');// /message是服务端支持EventSource的接口
服务端实现/message接口,需要返回类型为 text/event-stream的响应头。
var http = require('http'); http.createServer(function(req,res){ if(req.url === '/message'){ res.writeHead(200,{ 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive' }); setInterval(function(){ res.write('data: ' + +new Date() + '\n\n'); }, 1000); } }).listen(8888);
我们注意到,为了避免缓存,Cache-Control 特别设置成了 no-cache,为了能够发送多个response, Connection被设置成了keep-alive.。发送数据时,请务必保证服务器推送的数据以 data:开始,以\n\n结束,否则推送将会失败(原因就不说了,这是约定的)。
以上,服务器每隔1s主动向客户端发送当前时间戳,为了接受这个信息,客户端需要监听服务器。如下:
es.onmessage = function(e){ console.log(e.data); // 打印服务器推送的信息 }
es可以监听任何指定类型的事件。
es.addEventListener("####", function(e) {// 事件类型可以随你定义 console.log('####:', e.data); },false)
服务器发送不同类型的事件时,需要指定event字段。
res.write('event: ####\n'); res.write('data: 这是一个自定义的####类型事件\n'); res.write('data: 多个data字段将被解析成一个字段\n\n');
使用EventSource技术实时更新网页信息十分高效。实际使用中,我们几乎不用担心兼容性问题,主流浏览器都了支持EventSource,当然,除了掉队的IE系。对于不支持的浏览器,其PolyFill方案请参考HTML5 Cross Browser Polyfills
CORS
关于CORS配置可以参考我另一篇博文 前端跨域详解
nginx配置
既然说到了EventSource,便有必要谈谈遇到的坑,接下来,就说说我遇到的webpack热更新延迟问题。
如我们所知,webpack借助webpack-hot-middleware插件,实现了网页热更新机制,正常情况下,浏览器打开 http://localhost:8080 这样的网页即可开始调试。然而实际开发中,由于远程服务器需要种cookie登录态到特定的域名上等原因,因此本地往往会用nginx做一层反向代理。即把 http://www.test.com 的请求转发到 http://localhost:8080 上转发过后,发现热更新便延迟了。
原因是nginx默认开启的buffer机制缓存了服务器推送的片段信息,缓存达到一定的量才会返回响应内容。只要关闭proxy_buffering即可。配置如下所示:
server { listen 80; server_name www.test.company.com; location / { proxy_pass http://localhost:8080; proxy_buffering off; } }
WebSocket
WebSocket是基于TCP的全双工通讯的协议,它与EventSource有着本质上的不同.(前者基于TCP,后者依然基于HTTP)。关于WebSocket可以参考我另一篇博文WebSocket
- webpack热更新原理
- webpack模块热更新
- webpack 配置热更新
- webpack与browser-sync热更新原理深度讲解
- webpack与browser-sync热更新原理深度讲解
- webpack与browser-sync热更新原理深度讲解
- App热更新原理
- webpack配置热更新代码分享
- webpack 热更新(实施同步刷新)
- webpack热模块替换(HMR)/热更新
- Android热更新实现原理
- Android热更新实现原理
- Android热更新实现原理
- Android热更新原理记录
- Android热更新实现原理
- redux+react+webpack+热加载+兼容IE8(持续更新)
- webpack-dev-server无法自动编译热更新
- redux+react+webpack+热加载+兼容IE8(持续更新)
- tensorflow的张量(tensor)的理解
- javaee中乱码的解决
- Java使用List<Map<K,V>>写复杂接口
- 从协议中dump一个文件接口
- 编译ijkplayer-android源码
- webpack热更新原理
- 在一个idea工作环境中导入多个maven项目模块
- qt 之解析 XML(QXmlStreamReader)
- C#学习之Task.ContinueWith(连续的任务)的使用
- jQuery.extend 函数及用法详细
- 获取本地图片的base64数据方法
- MySQL日期比较
- iOS设置或修改导航栏按钮、标题
- YUV到RGB转换