模块联邦出现的动机
模块联邦的出现是为了不同开发小组共同开发一个或多个应用,应用可以被分为 更小的应用块,每个应用由不同的组开发,应用或应用块共享其他应用块或库。
使用Module Federation时,每个应用块都是一个独立的构建,这些构建都将编译为容器。被引用的容器称为remote,引用者称为host,remote暴露模块给host,host则可以使用这些暴露的模块。
模块联邦搭建
配置remote项目
首先在模块联邦目录下建两个项目,分别是host和remote,并在对应的webpack.config.js中,分别将host和remote的端口配置为8081和8080
在remote项目的src中,新建NewsList组件,并且在项目的入口处,需要使用dynamic-import
并在webpack.config.js中,进行如下配置模块联邦插件:
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');
配置完成后,执行webpack打包,打包完成后在dist目录下多了remoteEntry.js文件
配置host项目
remote项目对外暴露NewsList组件,在host项目中消费。 在host项目中,首先配置webpack.config.js,
然后在App中,进行动态引入:
此时,在host环境中,就能成功使用remote项目下的组件了
多个项目共享依赖
分别在host和remote项目的webpack.config.js中配置shared,进行多个项目中的依赖的共享
双向依赖
host可以消费remote中的组件,同样的,remote也能消费host中的组件,只要在 host中暴露出Slide组件即可
在host环境的webpack.config.js中进行如下配置
在remote环境的webpack.config.js中进行如下配置
然后在remote环境中引用即可
React.lazy原理
本次使用到了React.lazy,就讲一下React.lazy的原理
React.lazy = (fn) => {
return class extends React.Component {
state = {Component: null}
componentDidMount() {
//fn返回一个promise
fn().then((result) => {
this.setState({Component: result.default})
});
}
render() {
let {Component} = this.state;
return (
Component ? <Component />: null
)
}
}
}
此外:webpack还提供了Top-Level-Await的的实验性语法,当在顶层使用 await 时,它使模块成为异步模块。需要在webpack.config.js中配置才能使用。
配置完成后,就能如下所示动态引入模块了
最后,用一张图来总结模块联邦的基本使用