三易详|webpack热更新原理(热更新和冷升级差别)

大家大概了解了webpack HMR 原理。能够得知以下几个方面核心内容:

1、监视文档转变

2、网络服务器与客户端通讯

3、更换步骤

4、降权实际操作

自然,因为 webpack 自身有个很完善的模块观念和生态,因而全部架构模式会比我们达到的 HMR 繁杂许多。在模块热更换中,是通过 webpack 的所有步骤负荷率去完成这一操控的,而并没限于 webpack-dev-server 和 webpack 及其业务代码自身,事实上,具有更为重要功效的是各种 loader,他们需要使用 HMR API 来达到 Hot Reload 的思路,确定何时注册模块、何时卸载掉模块;怎样注册和卸载掉模块。而 webpack 自身更像是一个调用方角色,不用考虑到具体注册和反注册逻辑性。

经历了上边的剖析,大家大部分确定了一个构思,其实就是剖析 webpack HMR 得到的结果。但由于你只有 runtime,因此完成 Hot Reload 变成了一个下面的图简单地步骤:

1、Server 运行一个 HTTP 网络服务器,而且注册和运行 WebSocket 服务项目,用以到时候与客户端通讯

2、在运行 Static 网络服务器后返回页面前引入 HMR 的客户端编码,业务方不用关注 HMR 具体的完成和加上相对应的适用编码服务器端监视磁盘文件的变更,将文档变更根据 WebSocket 发给客户端

3、客户端接到文档变更消息时开展相对应的模块解决

4、(模块解决不成功,降权为 Live Reload)

在推进 HMR 以前,大家可以直接完成一个简单的 Live Reload 来确保大家 1-3 步的完成并没有出现异常。

const Koa = require('koa')

const WebSocket = require('ws')

const chokidar = require('chokidar')

const app = new Koa()

const fs = require('fs').promises

const wss = new WebSocket.Server({ port: 8000 })

const dir = 'http://www.yujujie.cn/shbk/static'

const watcher = chokidar.watch('http://www.yujujie.cn/shbk/static',{

ignored: /node_modules|.git|[/]http://www.yujujie.cn/shbk/

})

wss.on('connection', (ws) =>{

watcher

.on('add', path => console.log(`File $ ath}added`))

.on('change', path => console.log(`File $ ath}has been changed`))

.on('unlink', path => console.log(`File $ ath}has been moved`))

.on('all', async (event, path) =>{

// Simple Live Reload

ws.send('reload')

})

ws.on('message', (message) =>{

console.log('received: %s', message)

})

ws.send('HMR Client is Ready')

})

const injectedData = ` `

app.use(async (ctx, next) =>{

let file = ctx.path

if (ctx.path.endsWith('/')){

file = ctx.path 'index.html'

}

let body

try{

body = await fs.readFile(dir file,{

encoding: 'utf-8'

})

}catch(e){

ctx.status = 404

return next()

}

if (file.endsWith('.html')) body = body.replace('', `${injectedData}`)

if (file.endsWith('.css')) ctx.type = 'text/css'

ctx.body = body

next()

})

app.listen(3001)

console.log('listen on port 3001')

手机查看编码不便,我将编码截屏贴这了

 


WebSocket实现简单的webpack HMR(热更新)效果

 

所述编码中,简单用了 chokidar 这一文档监视库,它很大的缓解了我工作量;而 WebSocket 和云服务器完成上暂不赘述,往往不直接用 koa-static 是因为我们应该针对 HTML 文档进行一些引入实际操作,之上 Live Reload 的完成比较简单,基本上可以概括为一句话:获知文档变化后向客户端推送 reload 信息,客户端接到信息实行页面刷新实际操作。

完成了一个 Live Reload 以后,下面我们只需变更引入的编码和发送至客户端消息两部分就可以,实际上 Hot Reload 和 Live Reload 本质区别其实就是「最少模块更换」与「页面刷新」的差别,因而其余部分全是无需变化的。

更换 HTML 和 CSS 乃是在其中简单的二项每日任务。

一般而言,我们应该遮盖 HTML 里面的内容,除开更新这一实际操作外,还有一个就是 document.write(),事实上大家都是通过这一函数公式来达到 HTML 的 Hot Reload 的:

// 监视

.on('all', async (event, path) =>{

if (path.endsWith('.html')){

body = await fs.readFile(path,{

encoding: 'utf-8'

})

const message = JSON.stringify({ type: 'html', content: body })

ws.send(message)

}

})

// 引入

let data ={}

try{

data = JSON.parse(event.data)

}catch (e){

// return

}

console.log(data)

if (data.type === 'html'){

document.write(data.content);

document.close();

console.log('[HMR]updated HTML');

}

 


WebSocket实现简单的webpack HMR(热更新)效果

 

那样阅读者最大的一个疑惑很有可能成了:精密度如何粗糙热更新,仿佛跟立即刷网页页面并没有区别?

假如我们需要进行精密度更高热更新,那样产生性能差别实际上是非常大的,我们一起来考虑一下假如我希望尽量粗粒度的热更新实际操作,下面都需要什么实际操作:

读取文件

结构语法树

比照和之前语法树的差别

通讯将差别发送给客户端

将差别转换成相对应的 DOM 实际操作

那般在所难免,我们就应该在存储空间中缓存文件每一个网页页面最初语法树,针对模块变的部件而言,HTML 自身的变更其实就是并不是不少,没必要开展这么复杂操作

CSS 也非常简单,只需清除老旧 CSS 文档再次引进就可升级 CSS 了,此次,我们自己的编码将也会更加精减。

// 监视

if (path.endsWith('.css')){

const message = JSON.stringify({ type: 'css', content: path.split('static/')[1] })

{n}

{n}{t}ws.send(message)

{n}

{n}{t}}

{n}

{n}{t}// 注入

{n}

{n}{t}if (data.type === 'css') {

{n}

{n}{t}const host = location.host

{n}

{n}{t}document.querySelectorAll('link[rel="stylesheet"]').forEach(el => {

{n}

{n}{t}const resource = el.href.split(host + '/')[1]

{n}

{n}{t}console.log(resource)

{n}

{n}{t}if (resource === data.cont

WebSocket实现简单的webpack HMR(热更新)效果

WebSocket实现简单的webpack HMR(热更新)效果

原创文章,作者:leping,如若转载,请注明出处:https://www.wxymghbl.com/hq-2808.html

(0)
上一篇 2022年10月16日 上午1:50
下一篇 2022年10月16日 上午3:39

相关推荐