webpack5之模块联邦

时间:2025-02-07 13:02:43

文章目录

  • 1. 背景
    • 1.1 什么是模块联邦
    • 1.2 为什么要有模块联邦
      • 组件复用
  • 2. 使用过程分析
    • 2.1 示例
      • 2.1.1 主项目(以 为例)
      • 2.1.2 子项目(以 为例)
      • 2.1.3
  • 3. 副作用
  • 4. 扩展
  • 参考资料

1. 背景

本文将介绍“模块联邦”相关的内容。

1.1 什么是模块联邦

联邦模块是 webpack5 提供的一个新特性,它是通过 webpack 原生提供的 ModuleFederationPlugin 插件来实现的。
联邦模块主要是用来解决多个应用之间代码共享的问题,可以让我们的更加方便的实现跨应用的代码共享。

1.2 为什么要有模块联邦

组件复用

  • 复制/粘贴
  • 发布独立的 UI 库
  • 微前端:
    • 基于 single-spa 的微前端方案 qiankun
    • 基于 webcomponent qiankun sandbox 的微前端方案 micro-app
    • 基于 webcomponent 容器 iframe 沙箱的微前端方案 wujie
    • 基于 webpack5 的微前端方案 module federation

2. 使用过程分析

配置项

2.1 示例

2.1.1 主项目(以 为例)

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/',
        },
      }),
    ],
    optimization: { splitChunks: false },
    devServer: {
      static: {
        directory: path.join(__dirname, 'public'),
      },
      compress: true,
      port: 8081,
    },
  },
})

2.1.2 子项目(以 为例)

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: '',
        exposes: {
          './button': './src/components/',
        },
      }),
    ],
    optimization: { splitChunks: false },
    devServer: {
      static: {
        directory: path.join(__dirname, 'public'),
      },
      compress: true,
      port: 8081,
    },
  },
})

2.1.3

  • 新建
  • 修改

// src/

import { createApp } from 'vue'
import App from './'

createApp(App).mount('#app')

// src/

import('./bootstrap')

3. 副作用

  • 运行时加载远程模块等逻辑,可能导致一定的性能问题
  • 本地开发需要开启多个端口的服务
  • 按需加载第三方依赖比较难实现
  • 比起传统 spa 项目结构上有些复杂
  • 迭代时的版本控制需要更多关注

4. 扩展

  • vue + react
  • vue2 + vue3
  • vite

参考资料

中文官方资料