1. 背景
本文将介绍“模块联邦”相关的内容。
1.1 什么是模块联邦
联邦模块是 webpack5 提供的一个新特性,它是通过 webpack 原生提供的 ModuleFederationPlugin 插件来实现的。
联邦模块主要是用来解决多个应用之间代码共享的问题,可以让我们的更加方便的实现跨应用的代码共享。
1.2 为什么要有模块联邦
组件复用
- 复制/粘贴
- 发布独立的 UI 库
-
微前端:
- 基于 single-spa 的微前端方案 qiankun
- 基于 web***ponent qiankun sandbox 的微前端方案 micro-app
- 基于 web***ponent 容器 iframe 沙箱的微前端方案 wujie
- 基于 webpack5 的微前端方案 module federation
2. 使用过程分析
配置项
2.1 示例
2.1.1 主项目(以 vue.config.js 为例)
const { defineConfig } = require('@vue/cli-service')
const { ModuleFederationPlugin } = require('webpack').container
const path = require('path')
module.exports = defineConfig({
transpileDependencies: true,
publicPath: 'http://localhost:8081/',
configureWebpack: {
plugins: [
new ModuleFederationPlugin({
name: 'main_app',
remotes: {
'sub-app': 'sub_app@http://localhost:8082/remoteEntry.js',
},
}),
],
optimization: { splitChunks: false },
devServer: {
static: {
directory: path.join(__dirname, 'public'),
},
***press: true,
port: 8081,
},
},
})
2.1.2 子项目(以 vue.config.js 为例)
const { defineConfig } = require('@vue/cli-service')
const { ModuleFederationPlugin } = require('webpack').container
const path = require('path')
module.exports = defineConfig({
transpileDependencies: true,
publicPath: 'http://localhost:8082/',
configureWebpack: {
plugins: [
new ModuleFederationPlugin({
name: 'sub_app',
filename: 'remoteEntry.js',
exposes: {
'./button': './src/***ponents/button.vue',
},
}),
],
optimization: { splitChunks: false },
devServer: {
static: {
directory: path.join(__dirname, 'public'),
},
***press: true,
port: 8081,
},
},
})
2.1.3 bootstrap.js
- 新建
bootstrap.js
- 修改
main.js
// src/bootstrap.js
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
// src/main.js
import('./bootstrap')
3. 副作用
- 运行时加载远程模块等逻辑,可能导致一定的性能问题
- 本地开发需要开启多个端口的服务
- 按需加载第三方依赖比较难实现
- 比起传统 spa 项目结构上有些复杂
- 迭代时的版本控制需要更多关注
4. 扩展
- vue + react
- vue2 + vue3
- vite
参考资料
中文官方资料