普遍直译为『模块联邦』,我们看看官网是怎么说的?
十多年的掇刀网站建设经验,针对设计、前端、开发、售后、文案、推广等六对一服务,响应快,48小时及时工作处理。成都营销网站建设的优势是能够根据用户设备显示端的尺寸不同,自动调整掇刀建站的显示方式,使网站能够适用不同显示终端,在浏览器中调整网站的宽度,无论在任何一种浏览器上浏览网站,都能展现优雅布局与设计,从而大程度地提升浏览体验。成都创新互联公司从事“掇刀网站设计”,“掇刀网站推广”以来,每个客户项目都认真落实执行。
Motivation
Multiple separate builds should form a single application. These separate builds should not have dependencies between each other, so they can be developed and deployed individually. This is often known as Micro-Frontends, but is not limited to that.
多个独立的构建可以形成一个应用程序。这些独立的构建不会相互依赖,因此可以单独开发和部署它们。
这通常被称为微前端,但并不仅限于此。
通俗点讲,即MF提供了能在当前应用中远程加载其他服务器上应用的能力。对此,可以引出下面两个概念:
它与我们普遍讨论的基座应用、微应用有所不同,它是去中心化的,相互之间是平等的,每个应用是单独部署在各自的服务器,每个应用都可以引用其他应用,也能被其他应用所引用,即每个应用可以充当host的角色,亦可以作为remote出现。
项目结构如下:
module-home:首页,在layout展示一个字符串。
module-layout:布局,只包含一个html模板。
module-lib:暴露工具方法,共享lodash库。
3.1 相关配置参数一览
3.2 各应用的配置
// apps/module-lib/webpack.config.js
plugins: [
new ModuleFederationPlugin({
name: 'lib',
filename: 'remoteLib.js',
library: { type: 'var', name: 'lib' },
exposes: {
// 提供工具方法
'./utils': './index.js',
},
shared: ["lodash"]
})
]
// apps/module-home/webpack.config.js
plugins: [
new ModuleFederationPlugin({
name: 'home',
filename: 'remoteHome.js',
library: { type: 'var', name: 'home' },
exposes: {
// 提供挂载方法
'./mount': './index.js',
},
shared: ["lodash"]
})
]
// apps/module-layout/webpack.config.js
plugins: [
new ModuleFederationPlugin({
name: 'main',
filename: 'remoteMain.js',
remotes: {
'lib': 'lib@http://localhost:3001/remoteLib.js',
'home': 'home@http://localhost:3003/remoteHome.js',
},
shared: ['lodash']
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, './public/index.html'),
inject: 'body'
})
]
// apps/module-layout/boot.js
import {getUid, setUid} from 'lib/utils' // 使用module-lib中暴露的方法
import {mount} from 'home/mount' // 使用module-home中暴露的挂载方法
import _ from 'lodash';
setUid();
setUid();
console.log(getUid())
console.log(_.get)
mount()
如下图所示:在layout中展示了home挂载的节点,控制台也打印了调用lib中方法的log,同时lib分享的lodash也生效了(全程只加载了一个lodash)。
3.3 以remoteLib为例简要分析
// 定义全局变量
var lib;
/******/ (() => { // webpackBootstrap
/******/ "use strict";
/******/ var __webpack_modules__ = ({
/***/ "webpack/container/entry/lib":
/*!***********************!*\
!*** container entry ***!
\***********************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
eval("var moduleMap = {\n\t\"./utils\": () => {\n\t\treturn __webpack_require__.e(\"index_js\").then(() => (() => ((__webpack_require__(/*! ./index.js */ \"./index.js\")))));\n\t}\n};\nvar get = (module, getScope) => {\n\t__webpack_require__.R = getScope;\n\tgetScope = (\n\t\t__webpack_require__.o(moduleMap, module)\n\t\t\t? moduleMap[module]()\n\t\t\t: Promise.resolve().then(() => {\n\t\t\t\tthrow new Error('Module \"' + module + '\" does not exist in container.');\n\t\t\t})\n\t);\n\t__webpack_require__.R = undefined;\n\treturn getScope;\n};\nvar init = (shareScope, initScope) => {\n\tif (!__webpack_require__.S) return;\n\tvar name = \"default\"\n\tvar oldScope = __webpack_require__.S[name];\n\tif(oldScope && oldScope !== shareScope) throw new Error(\"Container initialization failed as it has already been initialized with a different share scope\");\n\t__webpack_require__.S[name] = shareScope;\n\treturn __webpack_require__.I(name, initScope);\n};\n\n// This exports getters to disallow modifications\n__webpack_require__.d(exports, {\n\tget: () => (get),\n\tinit: () => (init)\n});\n\n//# sourceURL=webpack://module-lib/container_entry?");
/***/ })
1、moduleMap:用来映射expose的模块
2、get方法:导出给host应用,用于获取remote expose的模块
3、init方法:导出给host应用,用于将remote模块注入
get方法中调用了__webpack_require__.e加载chunk
/******/ // This file contains only the entry chunk.
/******/ // The chunk loading function for additional chunks
/******/ __webpack_require__.e = (chunkId) => {
/******/ return Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => {
/******/ __webpack_require__.f[key](chunkId, promises);
/******/ return promises;
/******/ }, []));
/******/ };
__webpack_require__.e调用__webpack_require__.f
/******/ __webpack_require__.f.consumes = (chunkId, promises) => {
/******/ if(__webpack_require__.o(chunkMapping, chunkId)) {
/******/ chunkMapping[chunkId].forEach((id) => {
// 如果host已经有则直接使用,否则去remote安装
/******/ if(__webpack_require__.o(installedModules, id)) return promises.push(installedModules[id]);
/******/ var onFactory = (factory) => {
/******/ installedModules[id] = 0;
/******/ __webpack_require__.m[id] = (module) => {
/******/ delete __webpack_require__.c[id];
/******/ module.exports = factory();
/******/ }
/******/ };
/******/ var onError = (error) => {
/******/ delete installedModules[id];
/******/ __webpack_require__.m[id] = (module) => {
/******/ delete __webpack_require__.c[id];
/******/ throw error;
/******/ }
/******/ };
/******/ try {
/******/ var promise = moduleToHandlerMapping[id]();
/******/ if(promise.then) {
/******/ promises.push(installedModules[id] = promise.then(onFactory)['catch'](onError));
/******/ } else onFactory(promise);
/******/ } catch(e) { onError(e); }
/******/ });
/******/ }
/******/ }
/******/ })();
可以学习开源项目:基于 Webpack 5 Module Federation,优雅且实用的微前端解决方案 https://github.com/yuzhanglong/mf-lite。
网站题目:百度工程师带你了解ModuleFederation
网站URL:http://www.36103.cn/qtweb/news18/5518.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联