前端页面在正式生产环境实现热更新

7 篇文章 0 订阅
2 篇文章 0 订阅
最近项目进入测试阶段,因为是新项目首轮测试,要改要优化的东西太多,每次发完测试版后都要跟测试小姐姐说我发版了,你刷新一下可以验了,就很麻烦,像我这么社恐的人,每次开口都很艰难,于是,我弄了个自动检测更新的功能,只要测试那边在线(页面是打开状态),我发版后,页面上就会提示有更新,可以刷新页面进行更新。
  • 开始之前咱先研究下开发环境下是怎么搞定热更新的,都知道项目在本地开发时都是有热更新的,只要修改保存后页面就会自动刷新或更新,这都借助了工程化构建工具,如果webpack-dev-server等。
    其实都是基于socket来实现自动刷新的。当构建完成后,dev-server会启动一个http服务器,并在端口上监听。当我们打开本地地址时,页面中会嵌入一段socket脚本,该脚本会通过websocket连接到dev-server的socket服务器。
    当本地文件发生变化时,会通知socket服务器,socket服务器收到通知后,会向客户端发送消息,客户端收到消息后,会刷新页面实现热更新。当然也不是所有的情况都会刷新,有些情况下是采用注入或者说是替换代码的形式来更新,如比小修改或者修改样式之类的。
  • 为了这么一个小功能不可能去搞个socket来实现吧,太麻烦了不至于,于是直接上最简单粗暴的办法,那就是轮询,反正内网上公司自己的物理服务器,性能不用担心,是否优雅也不在考虑范围,直接看代码。
/**
 * 处理线上产环境热更更新
 * 主要原理:通过轮询的方式查询页面,然后页面的html字符串中提取出所有的script的src, 
 * 因为框架通过打包后,每次打包出来的文件的文件指纹都不一样,通过对比文件名称是否一样来判断网页是否有更新,
 */



let lastSrcs:Array<string> = [] // 上一次获取到的script地址
const scriptReg = /\<script.*src=["'](?<src>[^"']+)/gm;

/**
 * 查询页面,提取出head中script的src
 * @returns 
 */
async function extractNewScfipts():Promise<string[]> {
  const html = await fetch('/?file=src/autoRefresh.ts&_timestamp='+Date.now()).then(res => res.text());
  scriptReg.lastIndex = 0
  let result = [];
  let maech;
  while ((maech = scriptReg.exec(html))) {
    if(maech.groups) result.push(maech.groups.src)
  }
  return result
}

/**
 * 判断是否有更新
 * @returns 
 */
async function needUpdate():Promise<boolean>{
  // 拿到所有script的src
  const newScripts = await extractNewScfipts() 
  if(!lastSrcs.length){
    // 页面首次加载时进行负值
    lastSrcs = newScripts
    return false
  }
  let result = false
  // 对比上一次和新的数组是否想等
  if(lastSrcs.length !== newScripts.length){
    // 有更新
    return true
  }
  for (let i = 0; i < lastSrcs.length; i++) {
    // 循环判断是否某项不相等
    if(lastSrcs[i] !== newScripts[i]){
      result = true
      break
    }
  }
  lastSrcs = newScripts
  return result
}

const DATEINIT = 1000 * 60
/**
 * 生产环境热更新
 */
export function autoRefresh() {
  setTimeout(async () => {
    const willUpdate = await needUpdate();
    if (willUpdate) {
      const result = confirm('页面有更新,点击确定更新页面');
      if (result) {
        location.reload();
      }
    }
    autoRefresh();
  }, DATEINIT);
}
  • 当然办法还有很多种,我就喜欢简单粗暴的这种。
  • 有那说的不对的欢迎喷我,你们的攻击就是我前进的动力。嘿嘿!
  • 10
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要使用WebSocket实现数据库更新时前端页面的实时刷新,你可以按照以下步骤进行操作: 1. 在后端,使用WebSocket协议与前端建立连接。你可以使用一些流行的WebSocket库,如Socket.io(Node.js)或Tornado(Python)来简化这个过程。 2. 在前端,使用JavaScript的WebSocket API与后端建立连接。可以使用以下代码示例: ```javascript const socket = new WebSocket('ws://your-server-url'); socket.onopen = () => { console.log('WebSocket连接已建立'); }; socket.onmessage = (event) => { console.log('收到消息:', event.data); // 在收到消息时执行相应的操作,如更新页面内容 }; socket.onclose = () => { console.log('WebSocket连接已关闭'); }; ``` 3. 在后端,监听数据库的更新操作。当数据库发生更新时,通过WebSocket向前端发送消息。具体实现方式取决于你使用的数据库和后端语言。 例如,如果你使用Node.js和MongoDB,可以使用MongoDB的Change Streams功能来监听数据库的变化,并通过WebSocket发送消息给前端。以下是一个简单的示例: ```javascript const { MongoClient } = require('mongodb'); const WebSocket = require('ws'); const url = 'mongodb://localhost:27017'; const dbName = 'your-database-name'; const collectionName = 'your-collection-name'; const wss = new WebSocket.Server({ port: 8080 }); (async function () { const client = await MongoClient.connect(url, { useUnifiedTopology: true }); const db = client.db(dbName); const collection = db.collection(collectionName); const changeStream = collection.watch(); changeStream.on('change', (change) => { const message = JSON.stringify(change); wss.clients.forEach((client) => { if (client.readyState === WebSocket.OPEN) { client.send(message); // 向前端发送更新消息 } }); }); })(); ``` 这样,当数据库中的数据发生变化时,后端会将变化信息通过WebSocket发送给前端前端页面可以根据接收到的消息来实时更新内容。 请注意,以上代码只是一个简单的示例,实际上,你需要根据你的具体需求和技术栈进行相应的配置和开发。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值