Tencent / wujie

极致的微前端框架
https://wujie-micro.github.io/doc/
Other
4.07k stars 584 forks source link

关于vue子应用在vue-devtools里失效的原因和解决方案 #520

Open 140948940 opened 1 year ago

140948940 commented 1 year ago

bug复现:官方demo即可,在保活模式时,这个bug是几率性的,在重建模式时,大概率会出现

首先vue3的失效原因是,在某些情况下,无界代理的window并不会将window.__VUE_DEVTOOLS_GLOBAL_HOOK__复制给子应用,导致vue3的devtoolsInitApp方法并不能正确给vue-devtools通信。vue2应该是vue-devtools并不会查找元素至shadowDom之类的原因导致 解决方案:主应用

bus.$on('__VUE_DEVTOOLS__', (version, sonWindow) => {
  if (version === '3') {
    if (!sonWindow.__VUE_DEVTOOLS_GLOBAL_HOOK__) {
      sonWindow.__VUE_DEVTOOLS_GLOBAL_HOOK__ = window.__VUE_DEVTOOLS_GLOBAL_HOOK__
    }
  } else {
    const instance = sonWindow
    const devtoolsDiv = document.createElement('div')
    devtoolsDiv.__vue__ = instance
    document.body.appendChild(devtoolsDiv)
  }
})

vue3子应用

sonWuJieBus.$emit("__VUE_DEVTOOLS__", "3", window);

vue2子应用

sonWuJieBus.$emit("__VUE_DEVTOOLS__", "2", vueInstance);
zhuoqi-chen commented 2 months ago
function createMainApp() {
  const { locale } = useLocale()
  const i18n = createI18n({
    legacy: false,
    locale,
  })
  const pinia = createPinia()
  const instance = createApp(APP)
  instance.use(createVfm())
  instance.use(router)
  instance.use(i18n)
  instance.use(pinia)
  instance.mount('#app')
  return instance
}
if (window.__POWERED_BY_WUJIE__) {
  let instance: any
  window.__WUJIE_MOUNT = () => {
    instance = createMainApp()
    if (import.meta.env.DEV) {
      const parent = window.__WUJIE_RAW_WINDOW__.parent as Window
      const types = {
        Fragment: undefined,
        Text: undefined,
        Comment: undefined,
        Static: undefined,
      }
      parent?.__VUE_DEVTOOLS_GLOBAL_HOOK__?.emit('app:init', instance, instance.version, types)
    }
  }
  window.__WUJIE_UNMOUNT = () => {
    instance.unmount()
  }
  window.__WUJIE.mount()
}
else {
  console.error('请在无界环境中运行')
  createMainApp()
}

It works for me! image