博客 / 詳情

返回

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

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

如果多個應用之間希望資源共享,除了使用 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(模塊聯邦) 的介紹, 更多有關 前端工程化 的內容可以參考我其它的博文,持續更新中~

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.