目錄
介紹?
基本使用?
演示用法
初始化配置文件
remote?項目
host 項目?
為什么講這個呢,很多人覺得他不是微前端,也有人定義它也是微前端,看怎么理解了,我覺得他是一個去中心化技術,它可以讓多個獨立構建的應用之間,動態的調用彼此的模塊。這種運行機制,可以讓我們輕松的拆分應用,真正做到跨應用的模塊共享。
他是跟
webpack5
強耦合的,是基于webpack5內置插件的 無須安裝
介紹?
模塊聯邦(Module Federation)是一種在前端應用中實現模塊共享和跨應用程序共享的技術。它是由 webpack/lib/container/ModuleFederationPlugin 提供支持的。
模塊聯邦允許將應用程序拆分成多個獨立的模塊,這些模塊可以獨立開發、部署和維護。每個模塊可以由不同的團隊開發,并且可以在不同的應用程序中共享使用。這種方式可以提高開發效率,減少重復代碼,并且使得應用程序更加靈活和可擴展。
webpack/lib/container/ModuleFederationPlugin 是 webpack 的一個插件,它提供了實現模塊聯邦的功能。通過使用該插件,我們可以將應用程序的不同模塊打包成獨立的 bundle,并且可以在其他應用程序中動態加載和使用這些模塊。
使用模塊聯邦技術,我們可以實現以下應用場景:
-
微前端架構:將一個大型應用程序拆分成多個小型的子應用程序,每個子應用程序可以獨立開發和部署,然后通過模塊聯邦技術將它們組合在一起。這樣可以提高團隊的獨立性和開發效率。
-
插件化架構:將應用程序的不同功能模塊打包成獨立的插件,然后可以在其他應用程序中動態加載和使用這些插件。這樣可以實現應用程序的可擴展性和靈活性。
-
跨應用程序共享:不同的應用程序可以通過模塊聯邦技術共享使用彼此的模塊。這樣可以避免重復開發相同的功能,提高代碼的復用性和維護性。
總結來說,模塊聯邦技術通過 webpack/lib/container/ModuleFederationPlugin 插件提供了一種在前端應用程序中實現模塊共享和跨應用程序共享的方式。它可以提高開發效率,減少重復代碼,并且使得應用程序更加靈活和可擴展。
基本使用?
要使用 webpack/lib/container/ModuleFederationPlugin 插件實現模塊聯邦,你需要按照以下步驟進行設置:
-
在你的主應用程序(host application)的 webpack 配置文件中,引入?
webpack/lib/container/ModuleFederationPlugin
?插件。 -
在插件的配置中,指定需要共享的模塊名稱和對應的遠程入口文件。遠程入口文件是包含共享模塊的子應用程序(remote application)的打包文件。
-
在子應用程序的 webpack 配置文件中,同樣引入?
webpack/lib/container/ModuleFederationPlugin
?插件。 -
在子應用程序的插件配置中,指定需要共享的模塊名稱和對應的本地入口文件。本地入口文件是子應用程序的打包文件。
-
在主應用程序的代碼中,使用?
import()
?動態加載遠程模塊。這樣可以在運行時從子應用程序中加載共享模塊。
內部原理:?當你使用 webpack/lib/container/ModuleFederationPlugin 插件時,它會在構建過程中生成一個 manifest 文件。這個 manifest 文件包含了模塊的映射關系和加載邏輯。
在主應用程序中,當你使用?import()
?動態加載遠程模塊時,webpack 會根據 manifest 文件中的映射關系,找到對應的子應用程序,并從子應用程序中加載所需的模塊。
注意事項:
-
確保主應用程序和子應用程序的 webpack 配置文件中都正確配置了?
webpack/lib/container/ModuleFederationPlugin
?插件。 -
確保主應用程序和子應用程序的模塊名稱和入口文件配置一致,這樣才能正確地共享和加載模塊。
-
注意版本兼容性,確保 webpack 和相關插件的版本與?
webpack/lib/container/ModuleFederationPlugin
?插件兼容。 -
在使用模塊聯邦時,要注意處理好模塊的版本管理和依賴關系,以避免沖突和錯誤。
演示用法
構建兩個項目一個host一個remote
場景就是host項目想使用remote項目的list模塊,
初始化配置文件
下載依賴
pnpm init -y
pnpm i webpack webpack-cli webpack-dev-server html-webpack-plugin -D
remote?項目
index.js
import("./bootstrap");
?bootstrap.js
import { addList } from "./list";
let app = document.getElementById("app");
app.innerHTML = "<h2>remote</h2>";
addList();
異步加載
異步加載是一種優化技術,它可以在需要的時候動態地加載代碼,而不是在頁面加載時一次性加載所有的代碼。這樣可以提高頁面的加載速度和性能。
例子中,通過在入口文件中引入一個代碼文件來實現異步加載的方式是使用了動態導入(Dynamic Import)的語法。動態導入是ES6中的一個特性,它允許在運行時根據需要動態地加載模塊。
在你的例子中,入口文件(main.js)通過使用import("./bootstrap")
語法來動態地加載一個名為bootstrap的代碼文件。這樣,當執行到這行代碼時,瀏覽器會開始異步加載bootstrap.js文件,并在加載完成后執行其中的邏輯。
具體實現的原理是,當瀏覽器遇到動態導入語句時,會發起一個異步請求去加載指定的模塊文件。一旦模塊文件加載完成,瀏覽器會執行其中的代碼。這樣可以實現按需加載,提高頁面的加載速度和性能。
需要注意的是,動態導入返回的是一個Promise對象,你可以使用then
方法來處理加載完成后的邏輯,或者使用async/await
語法來等待加載完成。
總結起來,通過在入口文件中使用動態導入語法,可以實現異步加載代碼文件的邏輯,從而提高頁面的加載速度和性能。
?
remote 項目的webpack 配置
const { Configuration } = require("webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin"); //webpack5內置
/*** @type {Configuration} //配置智能提示*/
const config = {mode: "none", //none 開發模式 production 生產模式entry: "./index.js", //入口文件output: {// 輸出文件filename: "bundle.js", //輸出文件名},devServer: {// 本地服務器port: 9002, //remote 9002},// 開發插件plugins: [//html插件new HtmlWebpackPlugin({template: "./index.html",}),// 遠程模塊插件new ModuleFederationPlugin({name: "remote", //name必填filename: "remoteEntry.js", //filename必填 生成的文件名exposes: {"./addList": "./list.js", //暴露的模塊},}),],
};
module.exports = config;
host 項目?
host 項目的webpack 配置文件
const { Configuration } = require("webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
/*** @type {Configuration} //配置智能提示*/
const config = {mode: "none", //none 開發模式 production 生產模式entry: "./index.js", //入口文件output: {// 輸出文件filename: "bundle.js", //輸出文件名},devServer: {// 本地服務器port: 9003, //remote 9002},// 開發插件plugins: [//html插件new HtmlWebpackPlugin({template: "./index.html",}),// 遠程項目插件new ModuleFederationPlugin({name: "host", //name必填filename: "hostEntry.js", //filename必填 生成的文件名//對應關系remote對應的remote項目ModuleFederationPlugin的name 后面url對應的port以及對應ModuleFederationPlugin的filenameremotes: {remote: "remote@http://localhost:9002/remoteEntry.js", //引入模塊},}),],
};
module.exports = config;
host項目使用模塊 因為模塊是異步加載的
webpack/lib/container/ModuleFederationPlugin 插件通常與異步加載(dynamic import)一起使用。
模塊聯邦的核心思想是將應用程序拆分成多個獨立的模塊,并在需要時動態加載這些模塊。這種動態加載的方式可以帶來以下好處:
減少初始加載時間:通過異步加載,可以將應用程序的初始加載時間減少到最小。只有在需要時才會加載特定的模塊,而不是一次性加載所有模塊。這可以提高應用程序的性能和用戶體驗。
按需加載:異步加載允許根據用戶的操作和需求,按需加載特定的模塊。這樣可以避免加載不必要的模塊,減少資源的浪費。
模塊獨立性:通過異步加載,每個模塊可以獨立開發、部署和維護。這樣不同的團隊可以并行開發不同的模塊,而不會相互干擾。同時,模塊之間的依賴關系也可以更加靈活地管理。
動態更新:異步加載使得模塊聯邦可以實現動態更新。當一個模塊發生變化時,只需要重新加載該模塊,而不需要重新加載整個應用程序。這可以提高開發效率和部署靈活性。
因此,為了實現模塊聯邦的上述好處,webpack/lib/container/ModuleFederationPlugin 插件通常與異步加載一起使用。通過異步加載,可以按需加載模塊,提高性能、靈活性和開發效率。
//對應關系remote對應的remote項目的name addlist 對應的是key
import('remote/addList').then(({ addList }) => {let app = document.querySelector('#app');app.innerHTML = `<h3>Host</h3>
`;addList()
})
打完包觀察一下
其實就是一個cdn引入為什么這么做呢?
在之前我們十個項目共用一個模塊 會發到npm 例如1.0.0 這個模塊要改動 1.0.1,那每一個項目都要去重新install 一下 很繁瑣,而模塊聯邦是cdn 引入 無需 重新安裝每次就是最新的
?