qiankun解決主應(yīng)用和子應(yīng)用使用不同element-plus造成樣式覆蓋問題

解決子應(yīng)用樣式覆蓋主應(yīng)用問題:針對不同版本的 Element UI 樣式隔離

在微前端架構(gòu)中,主應(yīng)用和子應(yīng)用可能會使用不同版本的庫和樣式表。尤其是像 Element UI 這樣的 UI 框架,由于版本差異,子應(yīng)用的樣式有可能會影響到主應(yīng)用的 UI,造成樣式?jīng)_突。在這個(gè)場景中,主應(yīng)用使用的是 Element UI 2.6.0 版本,而子應(yīng)用使用的是 Element UI 2.4.4 版本,可能會導(dǎo)致樣式覆蓋問題。具體來說,子應(yīng)用的樣式可能會覆蓋主應(yīng)用的樣式,導(dǎo)致布局錯(cuò)亂。

解決這個(gè)問題的思路是:攔截并禁止子應(yīng)用加載特定的樣式,確保子應(yīng)用的 Element UI 樣式不干擾主應(yīng)用。下面將詳細(xì)介紹如何實(shí)現(xiàn)這一解決方案。


問題分析

當(dāng)子應(yīng)用加載時(shí),它的 Element UI 2.4.4 樣式會與主應(yīng)用的 Element UI 2.6.0 樣式產(chǎn)生沖突,尤其是 theme-chalk 樣式會被插入到 <head> 標(biāo)簽中,導(dǎo)致樣式被覆蓋。為了避免這種情況,我們可以通過監(jiān)聽 head.appendChild 方法,并判斷即將插入的樣式是否為 theme-chalk 樣式,如果是,就拒絕插入。


解決思路

  1. 攔截樣式插入:通過 Object.defineProperty 重新定義 document.head.appendChild 方法,攔截子應(yīng)用插入的樣式。
  2. 過濾 Element UI 樣式:檢測插入的樣式標(biāo)簽是否是與 Element UI 相關(guān)的樣式(例如 theme-chalk),如果是,則跳過插入,避免覆蓋主應(yīng)用樣式。
  3. 保留主應(yīng)用樣式:僅允許主應(yīng)用的樣式正常加載,確保子應(yīng)用的樣式不會污染主應(yīng)用的界面。

實(shí)現(xiàn)代碼

microApp.value = loadMicroApp(
  {
    name: 'micro-system', // 注冊子應(yīng)用名稱
    entry: '//localhost:3335/micro-sys/', // 子應(yīng)用的入口地址
    container: renderEl.value, // 子應(yīng)用的掛載容器
  },
  {
    sandbox: {
      strictStyleIsolation: false, // 禁用嚴(yán)格樣式隔離
      experimentalStyleIsolation: true, // 啟用實(shí)驗(yàn)性樣式隔離
      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; // 不插入該樣式
          }

          // 否則調(diào)用原始的 appendChild 方法,正常插入其他樣式
          return originAppendChild.call(this, node);
        },
        writable: true, // 確保 appendChild 方法是可寫的
        configurable: true, // 允許進(jìn)一步修改或刪除該屬性
      });
    },
  }
);

解釋與優(yōu)化

  1. 攔截 appendChild

    • 我們首先保存了原始的 appendChild 方法,并在重新定義的方法中進(jìn)行條件判斷。如果待插入的樣式是 element-plus/theme-chalk,我們通過 return 跳過該樣式,不讓它插入到 head 中。
  2. 確保樣式不會影響主應(yīng)用

    • 通過正則匹配樣式的 data-vite-dev-id,我們能準(zhǔn)確識別出子應(yīng)用中的 Element UI 樣式(如 theme-chalk),并避免它們影響主應(yīng)用。這樣,即使子應(yīng)用使用了較舊的 Element UI 版本(2.4.4),也不會導(dǎo)致樣式?jīng)_突。
  3. 實(shí)驗(yàn)性樣式隔離

    • experimentalStyleIsolation 開啟后,Qiankun 會嘗試使用實(shí)驗(yàn)性樣式隔離技術(shù),避免子應(yīng)用的樣式污染主應(yīng)用的樣式。

注意事項(xiàng)

  • 確保樣式隔離:在使用微前端時(shí),除了攔截樣式加載,還可以通過嚴(yán)格的樣式隔離配置(strictStyleIsolation)來避免樣式污染。
  • 調(diào)試和優(yōu)化:在開發(fā)過程中,確保子應(yīng)用和主應(yīng)用的樣式都能正確加載。遇到樣式?jīng)_突時(shí),可以通過 console.log 或調(diào)試工具進(jìn)一步分析問題。
  • 版本兼容性:盡量確保主應(yīng)用和子應(yīng)用的庫版本兼容,特別是像 Element UI 這樣的 UI 框架,版本差異可能導(dǎo)致更多樣式?jīng)_突。

通過以上方案,您可以有效避免子應(yīng)用的 Element UI 樣式覆蓋主應(yīng)用的樣式,確保微前端架構(gòu)中的樣式互不干擾,從而提高系統(tǒng)的穩(wěn)定性和可維護(hù)性。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容