在 vue/cli 中使用 Module Federation

webpack5 的新特性,分模塊共同開(kāi)發(fā)。多個(gè)獨(dú)立的構(gòu)建可以組成一個(gè)應(yīng)用程序,這些獨(dú)立的構(gòu)建之間不應(yīng)該存在依賴(lài)關(guān)系,因此可以單獨(dú)開(kāi)發(fā)和部署它們。這通常被稱(chēng)作微前端,但并不僅限于此。
我們分為本地模塊、遠(yuǎn)程模塊。
其中本地模塊即為普通模塊,是當(dāng)前構(gòu)建的一部分;而遠(yuǎn)程模塊不屬于當(dāng)前構(gòu)建,并在運(yùn)行時(shí)從所謂的容器加載。
加載遠(yuǎn)程模塊被認(rèn)為是異步操作。當(dāng)使用遠(yuǎn)程模塊時(shí),這些異步操作將被放置在遠(yuǎn)程模塊和入口之間的下一個(gè)chunk的加載操作中。如果沒(méi)有chunk加載操作,就不能使用遠(yuǎn)程模塊。
chunk的加載操作通常是通過(guò)調(diào)用import()實(shí)現(xiàn)的,但也支持像 require.ensure或require([...])之類(lèi)的舊語(yǔ)法。
容器是由容器入口創(chuàng)建的,該入口暴露了對(duì)特定模塊的異步訪問(wèn)。暴露的訪問(wèn)分為兩個(gè)步驟:
步驟1:加載模塊(異步的)
步驟2:執(zhí)行模塊(同步的)
步驟1將在chunk加載期間完成。步驟2將在與其他(本地和遠(yuǎn)程)的模塊交錯(cuò)執(zhí)行期間完成。這樣一來(lái),執(zhí)行順序不受模塊從本地轉(zhuǎn)換為遠(yuǎn)程或從遠(yuǎn)程轉(zhuǎn)為本地的影響。
容器可以嵌套使用,容器可以使用來(lái)自其他容器的模塊。容器之間也可以循環(huán)依賴(lài)。
在 vue/cli 中使用 Module Federation,使用只需以下幾個(gè)步驟:
home 項(xiàng)目
// vue.config.jsmodule.exports = {publicPath: 'http://localhost:8084/',chainWebpack: (config) => {config.plugin('module-federation-plugin').use(require('webpack').container.ModuleFederationPlugin, [{name: "home", // 模塊名稱(chēng)filename: "remoteEntry.js",exposes: { // 對(duì)外暴露的組件'./HelloWorld': './src/components/HelloWorld.vue'},}])},devServer: {port: 8084,hot: true,headers: {"Access-Control-Allow-Origin": "*","Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS","Access-Control-Allow-Headers":"X-Requested-With, content-type, Authorization",}}}
app 項(xiàng)目
// vue.config.jsmodule.exports = {publicPath: 'http://localhost:8085/',chainWebpack: (config) => {config.plugin('module-federation-plugin').use(require('webpack').container.ModuleFederationPlugin, [{name: "app",remotes: { // 導(dǎo)入home: 'home@http://localhost:8084/remoteEntry.js',},}])},devServer: {port: 8085,hot: true,headers: {"Access-Control-Allow-Origin": "*","Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS","Access-Control-Allow-Headers":"X-Requested-With, content-type, Authorization",}}}
使用組件
// 使用 home 項(xiàng)目里面的組件<template><div id="app"><img alt="Vue logo" src="./assets/logo.png"><HelloWorld msg="1111"/></div></template><script>export default {name: 'App',components: {HelloWorld: () => import('home/HelloWorld')}}</script><style>#app {font-family: Avenir, Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;color: #2c3e50;margin-top: 60px;}</style>
