qiankun解决主应用和子应用使用不同element-plus

2024-12-10  本文已影响0人  lihao_李浩

解决子应用样式覆盖主应用问题:针对不同版本的 Element UI 样式隔离

在微前端架构中,主应用和子应用可能会使用不同版本的库和样式表。尤其是像 Element UI 这样的 UI 框架,由于版本差异,子应用的样式有可能会影响到主应用的 UI,造成样式冲突。在这个场景中,主应用使用的是 Element UI 2.6.0 版本,而子应用使用的是 Element UI 2.4.4 版本,可能会导致样式覆盖问题。具体来说,子应用的样式可能会覆盖主应用的样式,导致布局错乱。

解决这个问题的思路是:拦截并禁止子应用加载特定的样式,确保子应用的 Element UI 样式不干扰主应用。下面将详细介绍如何实现这一解决方案。


问题分析

当子应用加载时,它的 Element UI 2.4.4 样式会与主应用的 Element UI 2.6.0 样式产生冲突,尤其是 theme-chalk 样式会被插入到 <head> 标签中,导致样式被覆盖。为了避免这种情况,我们可以通过监听 head.appendChild 方法,并判断即将插入的样式是否为 theme-chalk 样式,如果是,就拒绝插入。


解决思路

  1. 拦截样式插入:通过 Object.defineProperty 重新定义 document.head.appendChild 方法,拦截子应用插入的样式。
  2. 过滤 Element UI 样式:检测插入的样式标签是否是与 Element UI 相关的样式(例如 theme-chalk),如果是,则跳过插入,避免覆盖主应用样式。
  3. 保留主应用样式:仅允许主应用的样式正常加载,确保子应用的样式不会污染主应用的界面。

实现代码

microApp.value = loadMicroApp(
  {
    name: 'micro-system', // 注册子应用名称
    entry: '//localhost:3335/micro-sys/', // 子应用的入口地址
    container: renderEl.value, // 子应用的挂载容器
  },
  {
    sandbox: {
      strictStyleIsolation: false, // 禁用严格样式隔离
      experimentalStyleIsolation: true, // 启用实验性样式隔离
      speedy: true, // 提升样式加载速度
    },
  },
  {
    async afterMount(app, global) {
      const originAppendChild = global.document.head.appendChild;
      
      // 重新定义 document.head.appendChild 方法,拦截样式的插入
      Object.defineProperty(global.document.head, 'appendChild', {
        value(node: Element) {
          const dataId = node?.getAttribute('data-vite-dev-id');

          // 如果插入的样式是 Element UI 的 theme-chalk 样式,则跳过
          if (dataId && /element-plus\/theme-chalk/.test(dataId)) {
            return; // 不插入该样式
          }

          // 否则调用原始的 appendChild 方法,正常插入其他样式
          return originAppendChild.call(this, node);
        },
        writable: true, // 确保 appendChild 方法是可写的
        configurable: true, // 允许进一步修改或删除该属性
      });
    },
  }
);

解释与优化

  1. 拦截 appendChild

    • 我们首先保存了原始的 appendChild 方法,并在重新定义的方法中进行条件判断。如果待插入的样式是 element-plus/theme-chalk,我们通过 return 跳过该样式,不让它插入到 head 中。
  2. 确保样式不会影响主应用

    • 通过正则匹配样式的 data-vite-dev-id,我们能准确识别出子应用中的 Element UI 样式(如 theme-chalk),并避免它们影响主应用。这样,即使子应用使用了较旧的 Element UI 版本(2.4.4),也不会导致样式冲突。
  3. 实验性样式隔离

    • experimentalStyleIsolation 开启后,Qiankun 会尝试使用实验性样式隔离技术,避免子应用的样式污染主应用的样式。

注意事项


通过以上方案,您可以有效避免子应用的 Element UI 样式覆盖主应用的样式,确保微前端架构中的样式互不干扰,从而提高系统的稳定性和可维护性。

上一篇 下一篇

猜你喜欢

热点阅读