webpack5模块联邦的基本使用

2,031 阅读2分钟

模块联邦出现的动机

模块联邦的出现是为了不同开发小组共同开发一个或多个应用,应用可以被分为 更小的应用块,每个应用由不同的组开发,应用或应用块共享其他应用块或库。

使用Module Federation时,每个应用块都是一个独立的构建,这些构建都将编译为容器。被引用的容器称为remote,引用者称为host,remote暴露模块给host,host则可以使用这些暴露的模块。

模块联邦搭建

配置remote项目

首先在模块联邦目录下建两个项目,分别是host和remote,并在对应的webpack.config.js中,分别将host和remote的端口配置为8081和8080

image.png

在remote项目的src中,新建NewsList组件,并且在项目的入口处,需要使用dynamic-import

image.png

并在webpack.config.js中,进行如下配置模块联邦插件:

image.png

const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');

image.png 配置完成后,执行webpack打包,打包完成后在dist目录下多了remoteEntry.js文件

image.png

配置host项目

remote项目对外暴露NewsList组件,在host项目中消费。 在host项目中,首先配置webpack.config.js,

image.png 然后在App中,进行动态引入:

image.png

此时,在host环境中,就能成功使用remote项目下的组件了

image.png

多个项目共享依赖

分别在host和remote项目的webpack.config.js中配置shared,进行多个项目中的依赖的共享

image.png

双向依赖

host可以消费remote中的组件,同样的,remote也能消费host中的组件,只要在 host中暴露出Slide组件即可

在host环境的webpack.config.js中进行如下配置

image.png

在remote环境的webpack.config.js中进行如下配置

image.png 然后在remote环境中引用即可

image.png

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中配置才能使用。

image.png

配置完成后,就能如下所示动态引入模块了

image.png

最后,用一张图来总结模块联邦的基本使用

image.png