前言
由于公司有个项目是基于webpack5模块联邦搭建的微服务项目,之前对微前端项目接触的不是很多,那么借这个机会也了解了一个下模块联邦,目前微前端解决方案很多比如iframe,qiankun等等,微前端的好处有很多,官方的一些好处我就不说了,那么我认为最大的好处就是兼容历史应用,实现增量开发,今天主要记录一下自己使用Module Fedetation
https://github.com/songlindong/moduel-federations.git
模块联邦概述
Module Fedetation 即为模块联邦,是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方法挂在微应用
在容器应用加载微应用的时候,应该有权限决定微应用的挂载的位置,而不是微应用在代码运行时直接进行挂载,这时候我们就是在微应用中导出一个挂载方法供容器应用调用
原文:https://juejin.cn/post/7095238310620528670