无界[wujie]微前端如何销毁/杀死/刷新保活的子应用?

原因

  1. 由于业务原因,子应用都需要保持状态,所以给子应用都设置为保活模式,在路由跳转时,无奈只能通过eventBus传递给子应用,由子应用进行跳转。
  2. 但是当出现一些情况我们需要刷新子应用,比如登录状态变了,用户退出登录。重新登录进入,子应用应该重新打开,虽说可以重新传递用户信息等参数给子应用,但是要处理的逻辑就未免过多了,也为未来运行埋下坑。
  3. 所以,就需要一个方法,让保活的子应用失效,在切换到该子应用时,子应用能够重新加载。
  4. 之前尝试了一下刷新页面(window.reload),可以把子应用杀死,但是不优雅,而且用户体验不好。
  5. destroyApp虽然杀死了应用,但是再也打不开了(没试过,官方说如果再也用不到该子应用才使用这个方法)。
  6. 无界作者在github的issue中提到,未来也许会提供refreshApp的方法,用来主动刷新保活的子应用。
  7. 但是现阶段还未提供这个方法,可以按照下面的方式来销毁应用。
  8. 这个方法我是从无界交流群里面知道的,副作用未知

具体方法

在子应用中销毁

// 在子应用中调用这个方法,即可把当前子应用的沙箱缓存清除
window.__WUJIE?.inject?.idToSandboxMap.clear();

在主应用中销毁

interface HTMLIframeElementWithContentWindow extends HTMLIFrameElement {
  contentWindow: Window;
}

// 主应用可以通过下述方法,主动清除指定子应用的沙箱缓存
const refreshApp = (name = "") => {
  if (!name) {
    console.error("refreshApp方法必须传入子应用的name属性");
    return;
  }

  // 这里的window应该是顶级窗口,也就是主应用的window
  const SUB_FRAME = window.document.querySelector(
    `iframe[name=${name}]`
  ) as HTMLIframeElementWithContentWindow;

  if (!SUB_FRAME) {
    console.warn(`未找到${name}子应用,跳过刷新`);
    return;
  }

  const SUB_WINDOW = SUB_FRAME.contentWindow;
  const SUB_IDMAP = SUB_WINDOW.__WUJIE?.inject?.idToSandboxMap; // 沙箱Map对象
  SUB_IDMAP.clear();
};

// 执行销毁
refreshApp();
interface HTMLIframeElementWithContentWindow extends HTMLIFrameElement {
  contentWindow: Window;
}

// 主应用中清除所有已激活的子应用沙箱缓存
const refreshAllApp = () => {
  // 找到所有无界子应用的iframe
  const ALL_SUB_IFRAME = window.document.querySelectorAll(
    "iframe[data-wujie-flag]"
  );

  if (ALL_SUB_IFRAME.length === 0) {
    console.warn("未找到任何子应用,跳过刷新");
    return;
  }

  // 拿到这些iframe里面的contentWindow
  const ALL_SUB_WINDOW = Array.from(ALL_SUB_IFRAME).map(
    v => (v as HTMLIframeElementWithContentWindow).contentWindow
  );

  // 依次执行清除
  ALL_SUB_WINDOW.forEach(v => v.__WUJIE?.inject?.idToSandboxMap?.clear());
};

// 执行销毁
refreshAllApp();
// 如果在销毁时,主应用当前的路由就是目标子应用,销毁后,子应用会失去响应,所以建议销毁后主应用应该及时跳转回首页
import { useRouter } from "vue-router";
const router = useRouter();
router.push('/'); // 填入首页的路由

可能会出现的问题

  1. 主应用销毁保活子应用后,若还处于子应用,在子应用中切换其他页面或者点击按钮等,子应用会失去响应,并提示以下错误。(因为沙箱已经销毁,所以就无响应了)
    image
posted @ 2023-08-31 16:05  脆皮鸡  阅读(2027)  评论(3)    收藏  举报