# @originjs/vite-plugin-federation

# 简介

模块联邦 是一种前端的类微服务架构,它允许不同应用程序在运行时共享模块。

在传统的模块化开发中,应用程序通常被拆分为多个模块,每个模块有自己的代码和功能。然而,这些模块通常是在构建时静态地组合在一起的。模块联邦通过在运行时动态加载和共享模块,提供了更灵活的模块化解决方案。

联邦模块的关键概念包括:

  • 独立开发和部署: 不同的团队可以独立地开发和部署其自己的模块。每个模块可以拥有自己的代码库、开发流程和版本管理。

  • 动态加载: 在运行时,应用程序可以动态地加载和卸载模块。这使得应用程序能够根据需要动态地获取和使用特定的模块,而不需要在构建时静态地将它们组合在一起。

  • 共享模块: 不同的应用程序可以共享彼此的模块。这意味着一个应用程序的模块可以被另一个应用程序动态地使用,实现了更高程度的代码复用。

  • Remote: 远程服务端上的模块,本地模块运行时进行导入使用,不参与当前构建流程。
  • Host: 项目中的普通模块,参与当前项目的构建流程。
  • Shared: 共享模块是指既可重写的又可作为向嵌套容器提供重写的模块。它们通常指向每个构建中的相同模块,例如相同的库。

所以使用 Module Federation 通常需要2个以上的工程,一个作为Remote端,一个作为Host端。

  • Remote 端一般用于暴露组件,这些组件共同组成一个组件库。
  • Host 端一般用于引入并使用远程模块提供的组件。

对于 Remote端和 Host 端共同依赖的模块(如 vue, jsview):

  • 如果希望使用集成在 Host端的模块,可以通过Shared方式,这样 Remote 端就不会进行该模块的的打包。
  • 如果希望使用集成在 Remote 端的模块,可以在 Remote 端暴露出来,然后 Host 端引入 Remote 暴露的模块。

提示

注意: 一般来说,共同依赖的模块只能存在一份,如果同时引入了 Remote 端和 Host 端的共同模块,会出现一些未知错误。

# 集成到 JsView

注意

由于JsView需要对 @originjs/vite-plugin-federation 做一些源码级调整,所以需要安装指定版本 v1.3.4,其他版本暂不支持

参考工程源码: jsview-module-federation-demo (opens new window)

JsView 可以选择 shared 或 expose 其中一种方式,需要 Remote 端和 Host 端配合使用,即要么两者都是 shared 方式,要么两者都是 expose 方式。

可以选择 JsView 提供的命令行自动配置或自行手动配置

# 1. 自动配置

  • Remote 端

(1) 参考 创建 HelloWorld 工程 新建一个可运行的基础工程,例如 jsview-federation-remote。

如何你已经有一个基础工程,忽略此步骤。

(2) 配置

    (3) 编译并运行 Remote Server

    由于 Remote 端不支持开发模式,所以必须先进行编译。

    提示

    第一次编译前需要先进行App配置和生成签名,可以使用命令生成一个临时版本:

    npm run tool -- --config-app && npm run tool -- --gen-keypair
    
    1
    npm run build
    
    npx serve -C -p 8088 ./dist # 启动一个Http服务器
    
    1
    2
    3

    • Host 端

    (1) 参考 创建 HelloWorld 工程 新建一个可运行的基础工程,例如 jsview-federation-host。

    如何你已经有一个基础工程,忽略此步骤。

    (2) 配置和引入Remote组件

      (3) 运行 Host 开发服务

      npm start
      
      1


      # 2. 手动配置

      • Remote 端

      (1) 参考 创建 HelloWorld 工程 新建一个可运行的基础工程,例如 jsview-federation-remote。

      如何你已经有一个基础工程,忽略此步骤。

      (2) 安装 @originjs/vite-plugin-federation

      npm install @originjs/vite-plugin-federation@1.3.4
      
      npm ci
      
      1
      2
      3

      执行后会有一个打补丁成功的log如下图。

      (3) 修改 vite.config.ts

      import { setFederationRemoteConfig } from './federation.remote.config'
      import federation from '@originjs/vite-plugin-federation'
      
      const viteConfig = ({
        ... // 既有配置
      })
      
      setFederationRemoteConfig(viteConfig, federation)
      
      export default defineConfig(viteConfig)
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10

      (4) 新建 federation.remote.config.ts

        (5) 编译并运行 Remote Server

        由于 Remote 端不支持开发模式,所以必须先进行编译。

        提示

        第一次编译前需要先进行App配置和生成签名,可以使用命令生成一个临时版本:

        npm run tool -- --config-app && npm run tool -- --gen-keypair
        
        1
        npm run build
        
        npx serve -C -p 8088 ./dist # 启动一个Http服务器
        
        1
        2
        3

        • Host 端

        (1) 参考 创建 HelloWorld 工程 新建一个可运行的基础工程,例如 jsview-federation-host。

        如何你已经有一个基础工程,忽略此步骤。

        (2) 安装 @originjs/vite-plugin-federation

        npm install @originjs/vite-plugin-federation@1.3.4
        
        npm ci
        
        1
        2
        3

        执行后会有一个打补丁成功的log如下图。

        (3) 修改 vite.config.ts

        import { setFederationHostConfig } from './federation.host.config'
        import federation from '@originjs/vite-plugin-federation'
        
        const viteConfig = ({
          ... // 既有配置
        })
        
        setFederationHostConfig(viteConfig, federation)
        
        export default defineConfig(viteConfig)
        
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10

        (4) 新建 federation.host.config.ts

          (5) src/appConfig/jsview.config.mjs 使用 Remote 端 JsViewLoader。

            (6) src/main.tsx 引入 Remote 端组件 (所有从 jsview 导入的组件均改成'RemoteEntry/JsViewVue')

              (7) 引入自定义 Remote 组件, 例如:

              • src/main.tsx
              import App from './App.vue'
              改为
              import App from 'RemoteEntry/App.vue'
              
              1
              2
              3

              (8) 删除本地组件(可选,防止相同组件出现混淆)

              rm -r src/components/
              
              1

              (9) 运行 Host 开发服务

              npm start
              
              1

              # 查看运行结果

              采用 expose 方式或 shared 方式的 JsView 区别在于 JsView Loader 和 JsView 组件是从 Remote 加载还是从 Host 加载,通过 DevTools 可以看出结果。

                Last Updated: 1/30/2024, 6:22:18 AM