概念
模块联邦 :Module Federation
- Module Federation的动机 是为了不同开发小组共同开发一个或者多个应用
- 应用将被划分为更小的应用块,一个应用块,可以是比如头部导航,或者侧边栏的前端组件,也可以是数据获取逻辑的逻辑组件
- 每一个应用块由不同的组开发
- 应用或者应用块共享其他应用块或者库
组成
容器
- 使用Module Federation时,每个应用块都是一个独立的构建,这些构建都将编译为容器
- 容器可以被其他应用或者其他容器应用
remote
- 一个被引用的容器被称为remote,remote暴露模块给host
host
- 引用者则为host,使用remote模块暴露出来的模块
关系图
模块是可以相互依赖
实践
初始化
-
文件结构
-
分别都初始化
npm init -y
yarn add webpack webpack-cli webpack-dev-server html-webpack-plugin babel-loader @babel/core @babel/preset-env @babel/preset-react style-loader css-loader --save-dev
yarn add react react-dom --save
脚本命令
- package.json(host和remote配置相同)
"scripts": {
"build": "webpack",
"start": "webpack serve"
},
脚本命令和webpack4的区别:
"start":"webpack-dev-server"
webpack.config
- require 内置plugin :ModuleFederationPlugin
- 实例化: new ModuleFederationPlugin
- 配置导出 模块
- name:输出模块名,被远程引用路径为
${name}/${expose}
- filename:构建输出的文件名
这个和项目自己独立打包的输出main.js是相互独立的,前者是打包出来给别人用的,后者是自己的独立构建时候的最终打包文件
- remotes :远程引用的应用名&其别名的映射,使用时以key值为name,,此处的remote 指向的就是 被引用者 remote 输出的模块名称
- shared :与其他应用之间可以共享的第三方依赖,减少代码中不用重复加载同一份公共依赖
remote里的模块的import依赖, 在被引用的时候 的公共依赖最后 引的是引用者host里的依赖
- exposes:被远程引用时可暴露的资源路径及其别名
- name:输出模块名,被远程引用路径为
- 核心代码
remote(webpack.config.js)
devServer: {
port: 3000,
},
plugins: [
new ModuleFederationPlugin({
filename: "remoteEntry.js",
name: "remote", //name string 必传值,
exposes: {
"./NewList": "./src/NewList",//要暴露出去的公共模块
},
shared: {
react: { singleton: true },
"react-dom": {
singleton: true,
},
},
}),
],
remote NewList组件
import React from 'react'
export default ()=>{
return <div>新闻列表</div>
}
host(webpack.config.js)
引入我们要引用的模块
plugins: [
new ModuleFederationPlugin({
remotes: {
remote: "remote@http://localhost:3000/remoteEntry.js",
},
}),
],
host(App.js)
import React from "react";
const RemoteNewList = React.lazy(() => import("remote/NewList"));
const App = () => {
return (
<div>
<h2>本地组件Slider</h2>
<Slider />
{/* Suspense 做一个loading*/}
<React.Suspense fallback={<div>加载中....</div>}>
<RemoteNewList />
</React.Suspense>
</div>
);
};
export default App;
测试结果:
- 成功渲染了remote项目里 NewList组件
实现双向依赖
remote 也可以是 引用者 作为host
host(webpack.config.js)
plugins: [
new HtmlWebpackPlugin({
template: "./public/index.html",
}),
new ModuleFederationPlugin({
filename: "remoteEntry.js",
name: "host",
remotes: {
remote: "remote@http://localhost:3000/remoteEntry.js",
},
exposes: {
"./Slider": "./src/Slider",
},
shared: {
react: { singleton: true },
"react-dom": {
//重复引用相同模块依赖
singleton: true,
},
},
}),
],
remote(App.js)
import React from "react";
import Slider from "./Slider";
const RemoteNewList = React.lazy(() => import("remote/NewList"));
const App = () => {
return (
<div>
<h2>本地组件Slider</h2>
<Slider />
{/* Suspense 做一个loading*/}
<React.Suspense fallback={<div>加载中....</div>}>
<RemoteNewList />
</React.Suspense>
</div>
);
};
export default App;
测试结果
最后 码字不易 如果觉得本文有帮助 记得点赞三连哦 十分感谢