去中心化元件共享方案 —— Webpack Module Federation(模組聯邦)

一顆冰淇淋發表於2023-03-26

在大型應用中, 我們可能會對其進行拆分,分成容器、主應用和多個子應用,使拆分後的應用獨立開發與部署,更加容易維護。但無論是微應用、公共模組應用,都需要放到容器中才能使用。

如果多個應用之間希望資源共享,除了使用 npm 包的形式,基於Webpack 5 Module Federation(模組聯邦)實現的EMP微前端方案也可以一試,它不限制技術棧,但依賴於 Webpack5。

使用場景

如果應用B需要使用應用A中的User模組,那麼應用B就相當於容器,同時應用A也可以使用來自應用C的Menu模組,此時應用A變成了容器。

如何使用

要想使用 Module Federation,肯定是需要搭建 webpack 環境,配置方式也比較簡單,使用 ModuleFederationPlugin 分別匯出/匯出即可。

A應用匯出檔案

webpack配置需要匯出的檔案路徑和名稱

 // 其餘配置省略
const Mfp = require('webpack').container.ModuleFederationPlugin;

module.exports = {  
  plugins: [
     new Mfp({
        // 對外提供打包後的檔名
        filename: 'user.js',    
        // 匯出的應用/組織什麼名字
        name: 'userComponent',
        // 要匯出哪一個檔案,key值為引入時的名字,value為當前檔案路徑
        exposes: {
            './username': './src/username.js',
            './userHobby': './src/userHobby.js',
        }
    })
  ]
}

B應用匯入檔案

webpack設定需要匯入的資源地址和名稱

const Mfp = require('webpack').container.ModuleFederationPlugin

plugins: [
    new Mfp({
        name: 'root',
        // key值為匯入後使用的名字,value為匯出的 filename@檔案地址/name,設定本地服務地址方便除錯
        remotes: {
            userComponent: 'userComponent@http://localhost:3001/user.js'
        }
    })
]

在需要使用的js檔案中非同步匯入,userComponent 是定義的匯入後的名字,斜槓(/)加上匯出檔案webpack配置exposes屬性的檔名

const Username = React.lazy(()=>import('userComponent/username'))
const UserHobby = React.lazy(()=>import('userComponent/userHobby'))

return (
<React.Suspense fallback="loading"> 
    <Username/>
    <UserHobby/>
</React.Suspense>)

引入後,http://localhost:3001/user.js 將會被載入,並且資源內容掛載到 window 物件中。

這樣,便可以達到應用之間共享元件的目的。

以上就是 Webpack Module Federation(模組聯邦) 的介紹, 更多有關 前端工程化 的內容可以參考我其它的博文,持續更新中~

相關文章