umijs / qiankun

📦 🚀 Blazing fast, simple and complete solution for micro frontends.
https://qiankun.umijs.org
MIT License
15.61k stars 2k forks source link

[Bug] 主应用DOM结构发生变化后,导致子应用的name发生变化,name会自动+1 #2892

Open asyncguo opened 5 months ago

asyncguo commented 5 months ago

What happens?

当多个子应用来回切换时,从第二个子应用切回第一个子应用,子应用的appName会自动加1

image

Mini Showcase Repository(REQUIRED)

最小重现

How To Reproduce

  1. 来回切换子应用,再次切换到app1时就会触发
  2. 切换过程中会动态更新主应用的菜单(因为业务上是动态从子应用获取的,case里只是mock了更新操作)

分析原因:

因为子应用 app1 第二次打开时,主应用的DOM结构发生了变化,导致qiankun中的计算出的containerXPath会发生变化,从而导致appConfigPromiseGetterMap获取不到缓存,重新执行了loadApp,获取到的appInstanceId会自动+1

image

源码定位

请问如何解决主应用 DOM 结构变化导致的 containerXPath 不同所产生的问题呢

Context

asyncguo commented 5 months ago

$$cacheLifecycleByAppName 这个 api 好像可以解这个问题

if (container) {
    // using appName as cache for internal experimental scenario
    if ($$cacheLifecycleByAppName) {
        const parcelConfigGetterPromise = appConfigPromiseGetterMap.get(name);
        if (parcelConfigGetterPromise) return wrapParcelConfigForRemount((await parcelConfigGetterPromise)(container));
    }

    if (containerXPath) {
        const parcelConfigGetterPromise = appConfigPromiseGetterMap.get(appContainerXPathKey);
        if (parcelConfigGetterPromise) return wrapParcelConfigForRemount((await parcelConfigGetterPromise)(container));
    }
}
pauldu-design commented 4 months ago

你好,请问解决了吗,我这边也是类似的场景

asyncguo commented 4 months ago

你好,请问解决了吗,我这边也是类似的场景

$$cacheLifecycleByAppName 可以解

lusq010 commented 1 week ago

你好,请问解决了吗,我这边也是类似的场景

得case-by-case看吧,比如你的场景下是什么原因导致了子应用容器节点到body间的dom结构发生了变化,再看下是否可以避免这个变化