微前端-模块联邦

news2024/9/24 17:16:38

一、 Module Federation

模块联邦概述

Module Federation 即为模块联邦,是 Webpack 5 中新增的一项功能,可以实现跨应用共享模块。
在这里插入图片描述

二、快速上手

需求

通过模块联邦在容器应用中加载微应用。
在这里插入图片描述

应用结构

products
├── package-lock.json
├── package.json
├── public
│ └── index.html
├── src
│ └── index.js
└── webpack.config.js

应用初始化

  1. 在入口 JavaScript 文件中加入产品列表
import faker from "faker"

let products = ""

for (let i = 1 ; i <= 5 ; i++) {
products += `<div>${faker.commerce.productName()}</div>`
}

document.querySelector("#dev-products").innerHTML = products
  1. 在入口 html 文件中加入盒子
<div id="dev-products"></div>
  1. webpack 配置
const HtmlWebpackPlugin = require("html-webpack-plugin")

module.exports = {
mode: "development",
devServer: {
port: 8081
},
plugins: [
new HtmlWebpackPlugin({
template: "./public/index.html"
})
]
}
  1. 添加应用启动命令
"scripts": {
"start": "webpack serve"
}
  1. 通过 copy 的方式创建 container 和 cart

三、通过配置模块联邦实现在容器应用中加载产品列表微应用。

Module Federation

  1. 在产品列表微应用中将自身作为模块进行导出
// webpack.config.js
// 导入模块联邦插件
const ModuleFederationPlugin =
require("webpack/lib/container/ModuleFederationPlugin")

// 将 products 自身当做模块暴露出去
new ModuleFederationPlugin({
// 模块文件名称, 其他应用引入当前模块时需要加载的文件的名字
filename: "remoteEntry.js",
// 模块名称, 具有唯一性, 相当于 single-spa 中的组织名称
name: "products",
// 当前模块具体导出的内容
exposes: {
"./index": "./src/index"
}
})

// 在容器应用中要如何引入产品列表应用模块?
// 1. 在容器应用中加载产品列表应用的模块文件
// 2. 在容器应用中通过 import 关键字从模块文件中导入产品列表应用模块
  1. 在容器应用的中导入产品列表微应用
// webpack.config.js
// 导入模块联邦插件
const ModuleFederationPlugin =
require("webpack/lib/container/ModuleFederationPlugin")

new ModuleFederationPlugin({
name: "container",
// 配置导入模块映射
remotes: {
// 字符串 "products" 和被导入模块的 name 属性值对应
// 属性 products 是映射别名, 是在当前应用中导入该模块时使用的名字
products: "products@http://localhost:8081/remoteEntry.js"
}
})
// src/index.js
// 因为是从另一个应用中加载模块, 要发送请求所以使用异步加载方式
import("products/index").then(products => console.log(products))

通过上面这种方式加载在写法上多了一层回调函数, 不爽, 所以一般都会在 src 文件夹中建立bootstrap.js,在形式上将写法变为同步

// src/index.js
import('./bootstrap.js')
// src/bootstrap.js
import "products/index"

文件打包加载分析

  1. Products 应用打包分析
    在这里插入图片描述

  2. Container 应用打包分析
    在这里插入图片描述

  3. 文件加载顺序分析

在这里插入图片描述

四、加载 Cart 微应用

// cart/webpack.config.js
const ModuleFederationPlugin =
require("webpack/lib/container/ModuleFederationPlugin")

new ModuleFederationPlugin({
name: "cart",
filename: "remoteEntry.js",
exposes: {
"./index": "./src/index"
}
})
// container/webpack.config.js
remotes: {
cart: "cart@http://localhost:8082/remoteEntry.js"
}
// container/bootstrap.js
import "cart/index"
<!-- container/index.html -->
<div id="dev-cart"></div>

注意:cart/index.html 和 products/index.html 仅仅是在开发阶段中各自团队使用的文件,而 container/index.html 是在开发阶段和生产阶段都要使用的文件。

五、共享模块

实现模块共享

在 Products 和 Cart 中都需要 Faker,当 Container 加载了这两个模块后,Faker 被加载了两次。

在这里插入图片描述

// 分别在 Products 和 Cart 的 webpack 配置文件中的模块联邦插件中添加以下代码
{
shared: ["faker"]
}
// 重新启动 Container、Products、Cart

注意:共享模块需要异步加载,在 Products 和 Cart 中需要添加 bootstrap.js

共享模块版本冲突解决

Cart 中如果使用 4.1.0 版本的 faker,Products 中使用 5.2.0 版本的 faker,通过查看网络控制面板可以发现 faker 又会被加载了两次,模块共享失败。
解决办法是分别在 Products 和 Cart 中的 webpack 配置中加入如下代码

shared: {
faker: {
singleton: true
}
}

但同时会在原本使用低版本的共享模块应用的控制台中给予警告提示。

开放子应用挂载接口

在容器应用导入微应用后,应该有权限决定微应用的挂载位置,而不是微应用在代码运行时直接进行挂载。所以每个微应用都应该导出一个挂载方法供容器应用调用。

// Products/bootstrap.js
import faker from "faker"

function mount(el) {
let products = ""
for (let i = 1 ; i <= 5 ; i++) {
products += `<div>${faker.commerce.productName()}</div>`
}
el.innerHTML = products
}

// 此处代码是 products 应用在本地开发环境下执行的
if (process.env.NODE_ENV === "development") {
const el = document.querySelector("#dev-products")
// 当容器应用在本地开发环境下执行时也可以进入到以上这个判断, 容器应用在执行当前代码时肯定是获
取不到 dev-products 元素的, 所以此处还需要对 el 进行判断.
if (el) mount(el)
}

export { mount }
// Products/webpack.config.js
exposes: {
// ./src/index => ./src/bootstrap 为什么?
// mount 方法是在 bootstrap.js 文件中导出的, 所以此处要导出 bootstrap
// 此处的导出是给容器应用使用的, 和当前应用的执行没有关系, 当前应用在执行时依然先执行 index
"./index": "./src/bootstrap"
}
// Container/bootstrap.js
import { mount as mountProducts } from "products/index"
mountProducts(document.querySelector("#my-products"))

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/340703.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

程序的机器级表示part3——算术和逻辑操作

目录 1.加载有效地址 2. 整数运算指令 2.1 INC 和 DEC 2.2 NEG 2.3 ADD、SUB 和 IMUL 3. 布尔指令 3.1 AND 3.2 OR 3.3 XOR 3.4 NOT 4. 移位操作 4.1 算术左移和逻辑左移 4.2 算术右移和逻辑右移 5. 特殊的算术操作 1.加载有效地址 指令效果描述leaq S, DD…

【项目实战】32G的电脑启动IDEA一个后端服务要2min!谁忍的了?

一、背景 本人电脑性能一般&#xff0c;但是拥有着一台高性能的VDI&#xff08;虚拟桌面基础架构&#xff09;&#xff0c;以下是具体的配置 二、问题描述 但是&#xff0c;即便是拥有这么高的性能&#xff0c;每次运行基于Dubbo微服务架构下的微服务都贼久&#xff0c;以下…

使用太极taichi写一个只有一个三角形的有限元

公式来源 https://blog.csdn.net/weixin_43940314/article/details/128935230 GAME103 https://games-cn.org/games103-slides/ 初始化我们的三角形 全局的坐标范围为0-1 我们的三角形如图所示 ti.kernel def init():X[0] [0.5, 0.5]X[1] [0.5, 0.6]X[2] [0.6, 0.5]x[0…

每天10个前端小知识 【Day 12】

&#x1f469; 个人主页&#xff1a;不爱吃糖的程序媛 &#x1f64b;‍♂️ 作者简介&#xff1a;前端领域新星创作者、CSDN内容合伙人&#xff0c;专注于前端各领域技术&#xff0c;成长的路上共同学习共同进步&#xff0c;一起加油呀&#xff01; ✨系列专栏&#xff1a;前端…

I.MX6ULL内核开发9:kobject-驱动的基石

目录 一、摘要 二、重点 三、驱动结构模型 四、关键函数分析 kobject_create_and_add()函数 kobject_create()函数 kobject_init&#xff08;&#xff09;函数 kobject_init_internal(&#xff09;函数 kobject_add&#xff08;&#xff09;函数 kobject_add_varg&am…

JAVA集合专题4 ——ArrayDeque + BlockingQueue

目录ArrayDeque的特点BlockingQueue什么是BlockingQueue?什么叫阻塞队列?阻塞队列的应用场景是什么?BlockingQueue的阻塞方法是什么?BlockingQueue的四类方法codecode2ArrayDeque的特点 ArrayDeque是Deque接口子实现ArrayDeque数据结构可以表示为: 队列、双端队列、栈Arra…

C语言学习笔记(三): 选择结构程序设计

if语句 if(){} if (a1){printf("hehe");} //单独一个ifif(){}else{} int a 1, b 2;if (a b) {printf("haha"); //if else}else{printf("hehe");}if(){}else if(){} int a 1, b 2;if (a b) {printf("haha");}else if (a …

io的基本原理-nio

io的基本原理-nioio读写的基本原理io的模型1.同步阻塞IO2. 同步非阻塞IO3. IO多路复用4. 异步IO5.半同步半阻塞半异步IOnio是什么&#xff1f;NIO 的核心原理&#xff1a;java版代码cpp版本I/O&#xff08;Input/Output&#xff09;是计算机科学中指计算机和外部设备进行数据交…

Java Set集合

7 Set集合 7.1 Set集合的概述和特点 Set集合的特点 不包含重复元素的集合没有带索引的方法&#xff0c;所以不能使用普通for循环 Set集合是接口通过实现类实例化&#xff08;多态的形式&#xff09; HashSet&#xff1a;添加的元素是无序&#xff0c;不重复&#xff0c;无索引…

线程和QObjects

QObject的可重入性&#xff1a; QThread继承了QObject&#xff0c;它发出信号以指示线程开始或完成执行&#xff0c;并提供一些插槽。 QObjects可以在多个线程中使用发出调用其他线程中槽的信号&#xff0c;并将事件发布到在其他线程中“活动”的对象。这是可能的&#xff0…

redis可视工具AnotherRedisDesktopManager的使用

redis可视工具AnotherRedisDesktopManager的使用 简介 Another Redis DeskTop Manager 是一个开源项目&#xff0c;提供了以可视化的方式管理 Redis 的功能&#xff0c;可供免费下载安装&#xff0c;也可以在此基础上进行二次开发&#xff0c;主要特点有&#xff1a; 支持 W…

Matlab中安装NURBS工具箱及使用

文章目录前言一、NURBS工具箱的安装1 打开matlab&#xff0c;点击附加功能2 输入nurbs3 下载后压缩包解压4 将解压后的文件夹放到matlab文件夹的toolbox文件夹里面5 选择“预设路径”上方的“预设”二、NURBS工具箱的使用2.1 NURBS 结构&#xff1a;2.2 对NURBS工具箱的初步理解…

关于表的操作 数据库(3)

目录 前期准备工作&#xff1a; 一、单表查询&#xff1a; 二、多表查询&#xff1a; 前期准备工作&#xff1a; 修改数据库的配置文件&#xff0c;&#xff0c;使其可以显示库名&#xff0c;其中//d代表当前使用的数据库名 注&#xff1a;vim /etc/my.cnf.d/mysql-server.c…

Session与Cookie的区别(四)

咖啡寄杯的烦恼 虽然店里生意还可以&#xff0c;但小明无时无刻不想着怎么样发大财赚大钱&#xff0c;让店里的生意变得更好。 他观察到最近好多便利商店开始卖起了咖啡&#xff0c;而且时不时就买一送一或是第二件半价&#xff0c;并且贴心地提供了寄杯的服务。 寄杯就是指说你…

《剑指offer》:数组部分

一、数组中重复的数字题目描述&#xff1a;在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的&#xff0c;但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如&#xff0c;如果输入长度为7的数组{2,3,1…

C语言fscanf和fprintf函数的用法详解

fscanf() 和 fprintf() 函数与前面使用的 scanf() 和 printf() 功能相似&#xff0c;都是格式化读写函数&#xff0c;两者的区别在于 fscanf() 和 fprintf() 的读写对象不是键盘和显示器&#xff0c;而是磁盘文件。这两个函数的原型为&#xff1a;int fscanf ( FILE *fp, char …

【力扣-LeetCode】1138. 字母板上的路径-C++题解

1138. 字母板上的路径难度中等98收藏分享切换为英文接收动态反馈我们从一块字母板上的位置 (0, 0) 出发&#xff0c;该坐标对应的字符为 board[0][0]。在本题里&#xff0c;字母板为board ["abcde", "fghij", "klmno", "pqrst", &quo…

点云转3D网格【Python】

推荐&#xff1a;使用 NSDT场景设计器 快速搭建 3D场景。 在本文中&#xff0c;我将介绍我的 3D 表面重建过程&#xff0c;以便使用 Python 从点云快速创建网格。 你将能够导出、可视化结果并将结果集成到您最喜欢的 3D 软件中&#xff0c;而无需任何编码经验。 此外&#xff0…

总投资超500亿,广州白云机场三期扩建工程的IT投资更吸引人

【科技明说 | 每日看点】2023年基建大工程计划出台&#xff0c;广州白云机场三期将落实百亿元投资引发业内关注。据悉&#xff0c;广州白云机场三期扩建工程投资达537.7亿元&#xff0c;计划于2025年建成投产。这是中国民航历史上规模最大的改扩建工程&#xff0c;其扩建工程今…

TC3xx FlexRay™ 协议控制器 (E-Ray)-01

1 FlexRay™ 协议控制器 (E-Ray) E-Ray IP 模块根据为汽车应用开发的 FlexRay™ 协议规范 v2.1 执行通信【performs communication according to the FlexRay™ 1) protocol specification v2.1】。使用最大指定时钟&#xff0c;比特率可以编程为高达 10 Mbit/s 的值。连接到物…