likes
comments
collection
share

微前端解决方案-webpack5 模块联邦

作者站长头像
站长
· 阅读数 25

前言

由于公司有个项目是基于webpack5模块联邦搭建的微服务项目,之前对微前端项目接触的不是很多,那么借这个机会也了解了一个下模块联邦,目前微前端解决方案很多比如iframe,qiankun等等,微前端的好处有很多,官方的一些好处我就不说了,那么我认为最大的好处就是兼容历史应用,实现增量开发,今天主要记录一下自己使用Module Fedetation

github.com/songlindong…

模块联邦概述

Module Fedetation 即为模块联邦,是Webpack5 中新增的一项功能,可以实现跨应用共享模块 那么我这里就用一下这个插件,首先这里有三个模块分别为

微前端解决方案-webpack5 模块联邦

container容器应用,还有micro1、和micro2两个微应用,现在需要通过模块联邦在container中加载并运行micro1和micro2两个子应用 首先看一下micro1和micro中的配置

const HtmlWebpackPlugin = require("html-webpack-plugin")
// 导入模块联邦插件
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin")

module.exports = {
  mode: "development",
  devServer: {
    port: 8082
  },
  plugins: [
    new ModuleFederationPlugin({
    // 模块名称 具有唯一性
      name: "micro1",
      // 模块文件名称,其他应用引入当前模块时需要加载的文件的名字
      filename: "remoteEntry.js",
      // 当前模块具体导出的内容
      exposes: {
        "./Index": "./src/bootstrap"
      },
    }),
    new HtmlWebpackPlugin({
      template: "./public/index.html"
    })
  ]
}

那么container中的webpack.config.js

const HtmlWebpackPlugin = require("html-webpack-plugin")
// 也是需要导入模块插件
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin")

module.exports = {
  mode: "development",
  devServer: {
    port: 8080
  },
  plugins: [
    new ModuleFederationPlugin({
     // 容器应用也有可能导出之类的所以他也有名称
      name: "container",
      // 配置导入模块映射
      remotes: {
      // 字符串 “micro1/micro2” 和被导入模块的name属性对应
      // 属性 micro1/micro2是映射别名,是在当前应用中导入该模块时使用的名字
        micro2: "micro2@http://localhost:8081/remoteEntry.js",
        micro1: "micro1@http://localhost:8082/remoteEntry.js"
      }
    }),
    new HtmlWebpackPlugin({
      template: "./public/index.html"
    })
  ]
}

加载分析

micro2应用打包分析

其实是经历了两次打包流程,一个是正常的大包流程,一个是模块连板插件大包的流程分别为 正常打包流程 ->生成main.js 表示仍然可以单纯运行micro2

模块联邦插件 ->remoteEntry.js 包含模块中需要加载的文件列表 + 如何加载他们的代码

          ->src_index.js micro2 =>src/index.js
          
          ->fake.js  micro2 => faker
          

container应用打包分析

这里生成两个文件一个是main.js -〉仅仅包含了index.js文件中的内容

                bootstrap.js -> 包含了bootstrap.js文件中的内容

这里我们是看不到micro2中的内容,因为他是加载的远端的,不回打包成本地文件

文件加载顺序分析

在container加载和执行的时候,首先对main.js加载并执行,在这个时候需要加载和执行bootstrap.js,那么在加载bootstrap.js的时候,发现需要在micros2中加载文件,那么就加载remoteEntry.js可以知道怎样去加载,这时候需要src_index.js和fake.js,然后加载他们,最后执行bootstrap.js 那么在加载和执行micro1道理一样

模块联邦实现共享模块

这里是为了解决什么问题,就是在micro1和micro2两个应用中都加载了faker模块,在加载的时候会加载两次,这样是比较耗资源的,那么我们就通过shared就可以实现加载一个模块,但是这里有个问题,就是当两个应用中faker版本不一致的情况下,还是会加载两次,这时候就用singleton: true,来实现加载高版本

shared: {
        faker: {
          // 加载faker共享模块时以高版本为准
          singleton: true
        }
      }

container通过mount方法挂在微应用

在容器应用加载微应用的时候,应该有权限决定微应用的挂载的位置,而不是微应用在代码运行时直接进行挂载,这时候我们就是在微应用中导出一个挂载方法供容器应用调用