盘点一下用了这么长时间遇到的Wujie 无界微前端的坑

6,981 阅读6分钟

目前也用无界微前端很长时间了,当时选择无界没有选择乾坤的原因就是无界的保活模式更加丝滑,客户就想要这种方式,但是在这段过程也遇到了很多问题,甚至有些就是无界目前解决不了的问题,所以希望大家今后遇到了也能提前避免

已经解决的问题

1、子应用使用wangEditor 在主应用中无法编辑 ,无法粘贴,工具栏无法正常使用

✨问题复现

  • 子项目中正常

子项目的wangEditor.gif

  • 主项目无法选中,无法粘贴

主项目的wangEditor.gif

✨出现这种问题的原因:

  1. 子应用运行在 iframe内,dom在主应用的shadowdom中,当选中文字时,在主应用监听selectionchange,并且通过 document.getSelection()获取选中的selection,在wangEditor中 会判断这个 selection instanceof window.Selection,很明显主应用的selection 不可能是 iframe 里面window Selection的实例,所以出现了问题
  2. shadowDom 大坑,在shadowDom中 Selection.isCollapsed永远为true,相当于永远没有选中,所以只能修改 wangEditor 的代码,让读取 isCollapsed 修改成 baseOffset 和 focusOffset的对比,就知道是否选中了文字了

✨解决方案

1、将 wangeditor 替换成 wangEditor-next,因为wangeditor 作者大大已经说因为种种原因后面不会再继续更新了,所以担心更新的同学可以使用 wangEditor-next 这个还有人在继续更新

2、直接替换一个富文本组件 vue-quill,我使用的就是这个,因为我们项目对富文本的需求没有那么重,只要能用就行,所以你也可以替换一个在无界中没有问题的富文本组件

3、由此我们知道了在无界中getSelection是有问题的 如果遇到了可以用这个插件尝试解决 wujie-polyfill.github.io/doc/plugins…

2、子应用使用vue-office 的 pdf 预览,在主应用中白屏

✨问题复现

  • 子应用 正常显示

pdf-1.jpg

  • 主应用直接加载不出来

pdf-2.jpg

✨解决方案:

直接换个轮子,因为vue-office 源码不对外开放,你根本不知道是它内部做了何种处理,所以最好的办法就是直接换个其他的能够预览pdf 的方式,我这边选择的是 kkfile 的方式,kkfile 不仅可以预览pdf 还可以预览很多其他的格式的文件,让后端去生成预览地址 然后前端直接用 iframe 去打开即可

3、开发环境下 vite4 或者 vite5 子应用的 element-plus的样式丢失或者自己写的:root 不生效

✨问题复现

  • 子应用正常

css.jpg

  • 主应用样式丢失

css2.jpg

✨出现这种问题的原因:

主要的原因是因为子应用的 :root 失效了,因为无界中是将:root 转成了:host ,但是如果你是在main.js 中外链的样式

import 'element-plus/dist/index.css'

这样的话无界将无法劫持到将 :root 转成:host css3.jpg

✨解决办法:

增加插件

 <WujieVue
    width="100%"
    height="100%"
    name="pro1"
    :url
    :sync="true"
    :exec="true"
    :alive="true"
    :props="{ jump }"
    :plugins="[{
      patchElementHook(element, iframeWindow) {
        if (element.nodeName === "STYLE") {
          element.insertAdjacentElement = function (_position, ele) {
            iframeWindow.document.head.appendChild(ele);
          };
        }
      },
    }]"
  ></WujieVue>

如果不生效请清除缓存重新启动,多试几次就行

4、el-select 位置偏移以及 el-table tootip 位置偏移的问题

✨问题复现:

select.jpg

✨出现这种问题的原因:

el中依赖了poper.js 的fixed定位偏移,子应用的dom挂载在shadowRoot上,导致计算错误

官网解决办法

select-2.jpg

试了,发现没啥用,所以维护官网的大大请更新快点,要不然哪个还想用无界啊!!

✨最后解决办法:

使用插件 wujie-polyfill.github.io/doc/plugins…

// import { DocElementRectPlugin } from "wujie-polyfill";
<WujieVue
  width="100%"
  height="100%"
  name="xxx"
  :url="xxx"
  :plugins="[DocElementRectPlugin()]"
></WujieVue>

我的element-plus 的版本:"element-plus": "^2.9.0",

这个版本比较新,如果你们使用的是比较老的版本或者使用的是element-ui的话,上面的插件可能不生效,可以看下面的解决方案

github.com/Tencent/wuj…

总结下来无非是几个办法,要么是改element-ui 中的源码,然后在项目中打补丁

要么直接在子应用加代码

body{position: relative !important} 
.el-popper {position: absolute !important}

大家都可以都试一下,说不准哪个生效了

5、异步获取e.target 的 e.target 变成了 wujie-app

✨问题复现:

eTarget.jpg

eTarget2.jpg

官网文档方法 eTarget3.jpg

上面尝试了不行

✨最后解决办法:

使用 插件 wujie-polyfill.github.io/doc/plugins…

import { EventTargetPlugin } from "wujie-polyfill";
// vue
<WujieVue
  width="100%"
  height="100%"
  name="xxx"
  :url="xxx"
  :plugins=“[EventTargetPlugin()]”
></WujieVue>

完美解决

6、全局样式污染了子应用元素的样式

✨问题复现:

scope.jpg

scope2.jpg

✨最后解决办法:

比如主项目中你给 html 或者 body 文字居中,在子项目中也会受影响,其实这个不算是框架的问题,因为你写了这个是全局样式,那就说明了这个会影响所有的,所以建议大家样式尽量写scope 并且对全局的样式尽量主项目和子项目同步,不要出现不一样的情况,要不然很难去排查这种问题

目前还没找到解决办法的问题:

1、自定义事件

很多项目集成了第三方sdk 比如埋点、错误监控、数据通信,其中sdk 可能会使用了js 的自定义事件,这个时候在子组件中会失效

✨问题复现:

const customEvent = new CustomEvent('update', {
    bubbles: true,
    composed: true,
    detail: {
      msg:'我的数据更新喽'
    }
  })
setTimeout(() => {
    console.log(window.__WUJIE_RAW_WINDOW__,'window.__WUJIE_RAW_WINDOW__');
    window.dispatchEvent(customEvent)
    window.__WUJIE_RAW_WINDOW__ && window.__WUJIE_RAW_WINDOW__.dispatchEvent(customEvent)
  }, 2000)


window.addEventListener('update', function(event) {
    // 主应用没有反应,子组件中正常
    console.log(event)
  })
  window.__WUJIE_RAW_WINDOW__  &&  window.__WUJIE_RAW_WINDOW__ .addEventListener('testEvent', function(event) {
      // 主应用没有反应,子组件中正常
    console.log(event)
  })

会发现使用 window.addEventListener 或者 window.WUJIE_RAW_WINDOW .addEventListener 都没有用

✨出现这种问题的原因:

看了issue中作者说这个是无界中的bug ,所以如果有子组件用到这个自定义事件的,只能先将子组件用iframe 嵌入进去,等作者更新了再改回来

2、主应用路由切换和子应用路由切换点击浏览器退回没反应

✨问题复现:

官方示例:wujie-micro.github.io/demo-main-v…

大家也可以试一下,先点击主应用中的左侧vite 下的页面切换,然后再点击子应用中中间的页面切换,会发现需要点击两次浏览器的返回才能正常返回,可以看到我录屏下的点击返回前进和退回都没反应,只有多点一次才可以,目前还没找到好的解决办法,如果大家有办法解决可以告诉我。

两次点击.gif

结语

用了无界这么长时间给我的感觉还是比较好的,子应用保活非常丝滑,开箱即用,子应用基本上不需要更改任何代码直接可以继承到无界之中,这个优点真的是非常棒!不像qiankun 还得写很多适配的代码,当然qiankun 的社区真的比无界强大很多,很多问题你都能找到解决方案,只能说各有优缺点吧,主要看你自己怎么选择了