前端微应用之webpack5模块联邦用法

98 阅读3分钟

前端微应用之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联邦配置及共享库等等。