react lazy加载资源找不到的问题

在 Umi 4 中,默认按页拆包进行优化,实现每个页面只需加载最少的 js 资源,这会产生很多异步 js 分包。通常我们会开启 hash: true 构建,将 js / css 等资源做长期缓存,而 html 不缓存。

然而,在版本发布时,如果有用户在旧的应用 html 上加载新的页面,会导致旧资源 xxx.hash.js 加载不到。比如在整个替换 oss 存储内容的情况下,因为新版本已经发布,旧的 hash 文件不存在了。

下面为大家介绍两种解决方案:

一、加载失败自动重试方案

可以考虑 patch React.lazy 加载方法,遇到加载失败后自动 reload 页面重试。以下是自动重试的示例代码,若阻塞超过 10s,则弹出报错弹窗需用户手动刷新加载:

javascript 复制代码
// src/global.tsx

import { Modal, Result } from 'antd';
import React from 'react';

const originLazy = React.lazy;

React.lazy = (factory) => {
  return originLazy(() => factory().catch(loadError));
};
let hasError = false;
function loadError(): { default: React.ComponentType<unknown> } {
  const time = Number(window.location.hash.match(/#s(\d+)/)?.[1]);
  const now = Date.now();
  const isReloading =!time || time + 10000 < now;
  if (isReloading) {
    window.location.hash = `#s${now}`;
    window.location.reload();
  }

  const module = {
    default: () => {
      if (hasError) {
        return null;
      }
      hasError = true;
      return (
        <Modal
          open
          cancelButtonProps={{
            style: {
              display: 'none',
            },
          }}
          onOk={() => {
            window.location.reload();
          }}
          okText="Reload"
        >
          <Result title="Generic error message" status="error">
            {`Oops, something went wrong.`}
          </Result>
        </Modal>
      );
    },
  };

  return module;
}

参考来源:https://twitter.com/cpojer/status/1730141247900459166。

另外,也可参考 Vite 的 preload error 实现,自行在 loadError 内 dispatch 事件,之后在需要监听的地方处理即可。

二、自动检测新版本是否发布方案

还可参考https://github.com/umijs/umi/issues/10171 中的方案,在后台轮询 html 内容,在 html 中或其他位置维护新的版本标识,发版后将自动提示用户刷新页面。

注:添加版本标识的方案多样,如在 api.onBuildHtmlComplete 构建完成后手动修改 html,或 headScripts 手动添加等:

javascript 复制代码
//.umirc.ts

  headScripts: [
    {
      content: `// version: 1.2.3`
    }
  ],

此外,"version-rocket"这个库也可以参考。单独开了一个工作线程,后台轮询比对版本标识,逻辑相同。

相关推荐
JustHappy8 小时前
古法编程秘籍(二):什么是代码模块化?别背概念,把房间收拾明白就够了
前端·后端
小江的记录本8 小时前
【JVM虚拟机】堆内存分代模型:年轻代(Eden+Survivor)、老年代、元空间Metaspace(附《思维导图》+《面试高频考点清单》)
java·前端·jvm·后端·python·spring·面试
weixin_471383039 小时前
图片预解码缓存
前端·浏览器缓存·图片预解码
一起学开源9 小时前
一文读懂 ReAct 范式:让 AI Agent 真正学会“思考+行动“
java·javascript·react.js·ecmascript·react·alibaba·智能体开发
郑洁文10 小时前
基于网络爬虫的Web敏感信息泄露自动化检测工具
前端·爬虫·网络安全·自动化
郑洁文11 小时前
可视化Web渗透分析工具的设计与实现
前端
罗超驿11 小时前
18.Web API 实战:元素与表单属性的获取和修改
开发语言·前端·javascript
边界条件╝11 小时前
微前端进阶(四)
前端·状态模式
无风听海11 小时前
JSON Web Token(JWT)完全指南
java·前端·json
IT_陈寒12 小时前
Python闭包里藏的这个坑,差点让我加班到凌晨
前端·人工智能·后端