umi [Feature Request] 发版后,页面不刷新会报错,希望能监听这种异常,方便提示用户刷新页面

lg40wkob  于 2022-12-31  发布在  其他
关注(0)|答案(5)|浏览(598)

Background

A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

Proposal

Describe the solution you'd like, better to provide some pseudo code.

Additional context

Add any other context or screenshots about the feature request here.

q9rjltbz

q9rjltbz1#

这个需求单纯在前端代码层考虑的话,还是不太现实或者说实现过于困难了。无论如何都要涉及一定的部署工作

提供几个我这边的思路:

方法一

后端

增加一个 websocket 实现 或者一个长连接的 api,用来做“server-side-push”,即:服务器端发生变化时主动通知客户端。

那么,我就可以让后端在每次有新发布时,通知客户端有“new release”,前端可以自行决定是给用户一个 popup 还是 message,甚至直接帮用户刷新页面都行

前端

应用启动时,就通过 websocket 或者长连接和服务器建立通信渠道,虽然等待后端的消息,一旦发现有“new release”,我这边的做法是给用户一个popup,告诉他务必刷新页面,否则程序可能出现错误。

从解决方案的角度看,这是个很简单并且容易实现的东西,因为前后端要做的事情都很常规,并没有什么特殊技术要求。大致就是后端写个 api,前端写个监听器 这类的东西。

方法二

抛开后端,只在前端做。
那就是每次上线编译时,把所有生成的文件列表写到一个 文件里去,随便什么名字都行,譬如: output-meta.json 。文件放到 public 目录下,随其他生成的文件一起部署。

前端代码里,写段请求监听程序, 应用启动时,每隔 1 小时(时间随便自己定)请求一次 output-meta.json ,检查这个文件的内容是否有变化,有变化就提示用户,有新 release。请他刷新。
注意: output-meta.json 文件部署时必须配置成无缓存,不然前端每次请求的都是之前的 cache 的结果,那么检查内容变化也就无从谈起了

zbsbpyhn

zbsbpyhn2#

这个需求单纯在前端代码层考虑的话,还是不太现实或者说实现过于困难了。无论如何都要涉及一定的部署工作

提供几个我这边的思路:

方法一

后端

增加一个 websocket 实现 或者一个长连接的 api,用来做“server-side-push”,即:服务器端发生变化时主动通知客户端。

那么,我就可以让后端在每次有新发布时,通知客户端有“new release”,前端可以自行决定是给用户一个 popup 还是 message,甚至直接帮用户刷新页面都行

前端

应用启动时,就通过 websocket 或者长连接和服务器建立通信渠道,虽然等待后端的消息,一旦发现有“new release”,我这边的做法是给用户一个popup,告诉他务必刷新页面,否则程序可能出现错误。

从解决方案的角度看,这是个很简单并且容易实现的东西,因为前后端要做的事情都很常规,并没有什么特殊技术要求。大致就是后端写个 api,前端写个监听器 这类的东西。

方法二

抛开后端,只在前端做。 那就是每次上线编译时,把所有生成的文件列表写到一个 文件里去,随便什么名字都行,譬如: output-meta.json 。文件放到 public 目录下,随其他生成的文件一起部署。

前端代码里,写段请求监听程序, 应用启动时,每隔 1 小时(时间随便自己定)请求一次 output-meta.json ,检查这个文件的内容是否有变化,有变化就提示用户,有新 release。请他刷新。
注意: output-meta.json 文件部署时必须配置成无缓存,不然前端每次请求的都是之前的 cache 的结果,那么检查内容变化也就无从谈起了

方法一,每次发完版还得去维护的地方发布个消息或版本,对于小项目来说,太复杂繁琐了。
方法二其实和方法一差不多,每次得手动一下。
这都代码报错了,umi肯定知道啊,提示都是他报的。
我在vue项目里实现了window.addEventListener('error', handleError, true) 实现了

g2ieeal7

g2ieeal73#

上面两个方案完全可以做到自动, 至少我这边在部署时是不需要人工额外做事情的。 还是那句话,没有任何特殊技术要求。

“这都代码报错了,umi肯定知道啊,提示都是他报的。”
都是静态文件请求,你的 handleError 里是通过什么来识别 当前错误是 因为版本升级导致的?

因为从报错的信息来说, 程序错误, 网络请求错误,版本升级 都可能引发 “unexpected token” 类型的 error。

如果在前端能细化,直接区分出这种错误,那我觉得倒是很不错。可以单方面搞定确实要比 再拉几个其他人合作要更有效率

tjjdgumg

tjjdgumg4#

上面两个方案完全可以做到自动, 至少我这边在部署时是不需要人工额外做事情的。 还是那句话,没有任何特殊技术要求。

“这都代码报错了,umi肯定知道啊,提示都是他报的。” 都是静态文件请求,你的 handleError 里是通过什么来识别 当前错误是 因为版本升级导致的?

因为从报错的信息来说, 程序错误, 网络请求错误,版本升级 都可能引发 “unexpected token” 类型的 error。

如果在前端能细化,直接区分出这种错误,那我觉得倒是很不错。可以单方面搞定确实要比 再拉几个其他人合作要更有效率

判断是js文件网络请求错误就行啊,咋不能区分,这种报错本身代码是不会有这问题的

ltskdhd1

ltskdhd15#

目前根据报错信息,大概写了个能用的版本,

umi不会直接报404,不存在的js返回的是html

**
 * 判断js资源是否返回404状态码
 * @param url
 * @return {Promise<any>}
 */
function isScript404(url: string) {
  return new Promise((resolve) => {
    const xhr = new XMLHttpRequest();
    xhr.open('GET', url, false);
    xhr.onreadystatechange = function () {
      if (xhr.readyState === XMLHttpRequest.DONE && xhr.status !== 200) {
        resolve(true);
        return;
      }
      const responseText = xhr.responseText;
      if (!responseText) {
        resolve(true);
        return;
      }
      // 内容不是"use strict 开头
      if (!responseText.startsWith('"use strict')) {
        resolve(true);
        return;
      }
      resolve(false);
    };
    xhr.send();
  });
}

/**
* 处理错误函数
* @param e
*/
async function handleError(e: any) {
  console.log('script resource load error....', e);
  const filename = e.filename;
  if (!filename) {
    return;
  }
  const fileExtName = getFileExtName(filename);
  if (!fileExtName || 'js' !== fileExtName) {
    return;
  }
  const bool = await isScript404(filename);
  if (!bool) {
    return;
  }
  alert('版本已更新,页面将自动刷新');
  window.location.reload();
}

// 绑定事件
window.addEventListener('error', handleError, true);

相关问题