概念
Webpack 模塊聯邦是一種先進的代碼共享技術,它允許在多個獨立構建的 Web 應用程序之間共享代碼,而無需將這些代碼提前發布到 npm 倉庫或其他中央存儲。
這項技術特別適用于微前端架構,因為它能讓各個前端團隊獨立開發、部署自己的應用,同時還能無縫共享組件、庫或功能模塊。
通俗點說就是在微前端架構中每個應用都是獨立的,獨立開發,獨立部署,在開發過程中避免不了有些模塊是重復使用的,如何把這些重復的模塊利用起來,一般情況下會通過 npm 進行安裝或者相關代碼重復編寫,這樣做不好的地方就是代碼冗余,因為是微前端,會出現很多重復的內容,重復進行編寫,開發效率降低,而模塊聯邦就很好的解決了這些問題。
好處
動態加載:模塊可以在運行時動態加載,僅在需要時加載相關功能模塊,減少初始加載體積,加速頁面加載。
代碼重用:可以共享通用的庫和組件,避免重復代碼,優化代碼復用率。
版本管理:各個模塊可以獨立升級和版本化,不會因某個模塊的更新影響整個應用。
性能優化:共享庫避免重復包含,打包體積更小,網絡傳輸更快,提高應用性能。
關鍵概念
主容器與遠程容器
- 主容器(Host):負責加載其他應用模塊的應用,消費模塊的容器。
- 遠程容器(Remote):提供模塊供其他應用加載的應用,提供模塊的容器。
動態加載
模塊聯邦允許應用在運行時動態加載其他應用的模塊,而不是在構建時靜態合并。這使得各個應用可以獨立構建和部署,運行時按需加載所需的模塊。
舉例說明一下
假設場景
我們有兩個獨立的項目:app1
和 app2
。
app1
想要復用 app2
中的一個名為 CoolButton
的組件。
創建主容器應用(Host)
首先,安裝 Webpack 5 和相關插件:
npm install webpack webpack-cli html-webpack-plugin --save-dev
設置?app2
?作為共享模塊的提供者(遠程容器)
首先,在 app2
的 webpack.config.js
文件中,我們需要配置 app2
以共享 CoolButton
組件。
// app2/webpack.config.js
module.exports = {output: {publicPath: 'http://localhost:3002/', // 公共路徑,確保在不同域下也能正確加載uniqueName: 'app2', // 確保在聯邦中的唯一命名},plugins: [new webpack.container.ModuleFederationPlugin({name: 'app2',filename: 'remoteEntry.js',exposes: {'./CoolButton': './src/components/CoolButton', // 共享 CoolButton 組件},}),],
};
在?app1
?中消費?app2
?提供的?CoolButton
?組件(主容器)
接下來,在 app1
中,我們需要配置 app1
以消費來自 app2
的 CoolButton
。
// app1/webpack.config.js
module.exports = {plugins: [new webpack.container.ModuleFederationPlugin({name: 'app1',remotes: {app2: 'app2@http://localhost:3002/remoteEntry.js', // 指定app2的遠程入口},shared: {react: { singleton: true },'react-dom': { singleton: true },},}),],
};
然后,在 app1
的代碼中,我們可以像導入本地模塊一樣導入 app2
的 CoolButton
:
// app1/src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import CoolButton from 'app2/CoolButton';ReactDOM.render(<React.StrictMode><div><h1>Welcome to App1</h1><CoolButton label="Click me!" /></div></React.StrictMode>,document.getElementById('root')
);
總結
以上對模塊聯邦進行簡單的介紹,當然實際使用當中還要根據各自的項目進行配置,大家可以查看官方文檔進行更深一步了解Webpack 5 發布 (2020-10-10) | webpack 中文文檔