前端微应用之webpack5模块联邦用法
通过webpack5将 子应用B 需要导出的模块(b1,b2,...)打包后生成remoteEntry.js文件,在 应用A 中动态加载这个remoteEntry文件,同时导入b1,b2,...模块,就可以在应用A中直接使用了。
主要用法和配置如下。
1、主要项目结构
├── app-base # app基座应用(主应用)
│ ├── build # webpack配置、build相关、federation联邦配置
│ ├── federation # 模块联邦(消费组件、提供组件)配置目录
│ ├── package.json # node.js依赖配置
│ ├── yarn.lock # 项目依赖的具体版本信息锁定文件
├── app-child2 # app-child2子应用
│ ├── build
│ ├── federation
│ ├── package.json
│ ├── yarn.lock
├── app-child3 # app-child3子应用
│ ├── build
│ ├── federation
│ ├── package.json
│ ├── yarn.lock
├── common # 子应用公共模块
│ ├── assets # 静态资源(img,css,font,icon)
│ ├── build # webpack配置、build相关
│ ├── components # 公共组件
├── dist # 子应用构建产物目录
│ ├── app-base
│ ├── app-child2
│ ├── app-child3
├── public # 无需编译的静态资源
├── package.json # node.js依赖配置
├── yarn.lock # 项目依赖的具体版本信息锁定文件
...
2、介绍
主应用app-base(消费方)
1、提供项目主体框架、以及基础功能:登录、系统管理、路由配置等
2、加载子应用提供的业务组件
子应用app-child2、app-child3(提供方)
1、提供远程联邦组件:业务组件、业务页面
3、安装webpack5.x版本
yarn add webpack@^5
或
npm install webpack@^5
4、子应用配置(app-child2、app-child3、...)
1)子应用webpack配置
文件路径:/app-doc/build/app.conf.js
// 提供远程构建
const { exposes } = require('../federation/exposes/index')
module.exports = {
APP_NAME: 'app-child2', // 子应用名称
PORT: '8002', // 子应用端口号
// 联邦模块配置
FederationOption: {
name: 'child2', // 子应用模块名称(消费方引入远程模块的时候需要使用这个name)
library: { type: 'window', name: 'child2' },
filename: 'remoteEntry.js',
exposes
}
}
2)子应用提供组件--导出
文件路径:/federation/exposes/index.js
exports.exposes = {
'./PageDemo1': './src/views/PageDemo1/index.vue', // 业务组件路径
...
}
5、主应用配置(app-base)
1)主应用webpack配置
文件路径:/app-base/build/app.conf.js
引入联邦模块文件:http://xx/app-xx/remoteEntry.js
// 消费远程模块 (引入步骤4导出的配置)
module.exports = {
APP_NAME: 'app-base', // 子应用名称
PORT: '8001', // 子应用端口号
// 联邦模块配置
FederationOption: {
name: 'base', // 子应用模块名称(消费方引入远程模块的时候需要使用这个name)
filename: 'remoteEntry.js',
remotes: [
'child2': 'child2@http://xx/app-child2/remoteEntry.js',
'child3': 'child3@http://xx/app-child3/remoteEntry.js'
]
}
}
2)主应用引入远程模块--导入
文件路径:/app-base/federation/remoteModule/index.js
获取到远程模块后,可放入路由中配置,import('child2/xx')引入子应用对应导出模块
export const remoteDocModule = {
PageDemo1: () => import('child2/PageDemo1'),
PageDemo2: () => import('child3/PageDemo1'),
...
}
6、webpack5配置--公共配置
// 引入主应用配置(步骤5-1)
const appFederOptions = require('/app-base/build/app.conf.js')
// 或子应用配置(步骤4-1)
// const appFederOptions = require('/app-child2/build/app.conf.js')
// const appFederOptions = require('/app-child3/build/app.conf.js')
// webpack基本配置
const webpackBaseConf = {
output: {
library: `app_${APP_NAME}`,
libraryTarget: 'umd' // 把子应用打包成 umd 库格式
...
},
...
}
// 联邦配置
const federOptions = {
...appFederOptions,
// 子应用共享库
shared: {
vue: {
eager: true,
singleton: true,
requiredVersion: dependencies.vue
},
'vue-router': {
eager: true,
singleton: true,
requiredVersion: dependencies['vue-router']
},
vuex: {
eager: true,
singleton: true,
requiredVersion: dependencies.vuex
},
...
}
}
webpackBaseConf.plugins.push(new ModuleFederationPlugin(federOptions))
exports.webpackBaseConf
7、END
看起来是不是很简单,但是实际操作起来,还是有很多需要注意的地方,比如:导入导出模块的写法,webpack5联邦配置及共享库等等。