# federation使用场景和样例说明

# 简介和项目改法

  1. 简介 Jsview-vue-federation 是一种host remote架构的,子模块(remote)独立打包,可动态加载的模式,区别于jsview-vue模式下,工程内容所有模块最总打包在一起一起输出的老模式。

    点击进入 基本介绍

  2. 现有工程改造成remote/host 对于已有的jsview-vue工程,
    改造成host时:
    npm run tool -- --module-federation --mode=host --jsview=shared -remote-domain=http://localhost:8088

    改造成remote时:
    npm run tool -- --module-federation --mode=remote --jsview=shared

    以上的tool指令都会包含install指令:
    npm install @originjs/vite-plugin-federation@1.3.4
    但是不包含
    npm run tool -- --config-app && npm run tool -- --gen-keypair

# 场景1: 子模块动态上线

用于活动组件做成动态上线的子模块,主模块EPG界面按需进行动态加载的场景。
可用的公开demo: https://gitlab.cluster.qcast.cn/mirror/jsview-vue-federation-demo.git
目录: host-remote-run

  1. 子模块(remote-app) 用来包装活动组件。一般是把所有活动打包到一个主入口中。也可以打包成多个remote工程,但是host那边需要针对每个remote配置一个引用入口(在host的federation.host.config.ts的remotes字段配置)。
    关注内容见git中,host-remote-run/remote-app的README

    1. remote的App.vue的所有jsview模块必须来源于 HostJsvShared.js, 此文件和 host 端共用一份
    后续增加时,需要host那边先改,然后把文件发给remote使用,并且remote运行在改完文件的host上才有这些模块可使用

    2. remote的vite.config.js中有如下处理,防止代码中误用 import {xxx} from 'jsview' 的写法
    'jsview': '', // 取消jsview的引用名

    3. federation.remote.config中的expose中的命名(MindMapMainApp)要和host端进行约定,用于host端对本模块引用

  2. 主模块(host-app) 为主EPG的代码工程host化。 关注内容见git中,host-remote-run/remote-app的README

    1. 加载remote模块通过 App.vue 的 defineAsyncComponent 来完成,模块名字(MindMapMainApp)与remote进行约定即可。

    2. defineAsyncComponent 调用中,通过 JsvFederationTools.alterModuleUrl 定义远程模块服务器位置。注意: 此alterModuleUrl接口只有模块未被加载时才能使用,加载后使用则无效。

    3. HostJsvShared.js的内容为共享给remote的jsview模块,没写到这里面的内容,remote无法使用。后续增加时,需要host那边先改,然后把文件发给remote使用,并且remote运行在改完文件的host上才有这些模块可使用。

    4. 远程入口可以是单个也可以是多个,每个remote(独立打包的工程)要对应一个入口(但单个remote可以有多个子模块),需要federation.host.config.ts的remotes资源来配置。

# 场景2: 子模块联调不开源的主模块

用于主模块不方便开源,但子模块调试时,和主模块有强烈的依存关系的场景,此场景,主模块临时改造成remote模块,供子模块作为工作环境启动起来,然后子模块调试时,启动remote主模块前,先把自己调试模块动态注入到全局中,在主模块启动时优先使用全局的注入模块以达到子模块的内容为npm start对应内容的调试目的。 可用的公开demo: https://gitlab.cluster.qcast.cn/mirror/jsview-vue-federation-demo.git 目录: debug-sub-module

  1. 主模块(main-module, 作为remote) 主模块修改为优先使用全局注入的子模块的逻辑。对于router跳转子模块的场景,可以参考以下单remote内含多子模块的代码:

    import blank from "./blank.vue"
    routerList {
        import("../../node modules/sub-provider/indexProxy.js").newEntry1?blank 
        import("../../node modules/sub-provider/indexProxy.js").newEntry2?blank 
        import("../../node modules/sub-provider/indexProxy.js").newEntry3?blank  
    }
    
    1
    2
    3
    4
    5
    6

    其余关注内容见git中,debug-sub-module/main-module的README

    1. 加载调试模块时,并不是直接加载,而是通过proxy加载,例如 itemProxy.js,在此Proxy中,判断是否存在注入内容(window.WrapItem),无注入则用自己代码中的模块。

    2. federation.remote.config中的expose中的命名(MainModule)要和host端进行约定,用于host端对本模块引用。

  2. 子模块(sub-module-debug,作为host) 目的是将main.tsx引入的App.vue的第一个入口替换成remote提供的主模块的App.vue,并在异步加载前全局声明本调试子模块。 其余关注内容见git中,debug-sub-module/main-module的README

    1. 使用 JsvFederationTools.alterModuleUrl 将remote加载地址指向服务器

    2. App.vue通过 defineAsyncComponent 对主场景(main-module)的app.vue进行引入,
    加载内容"RemoteEntry/MainModule"与主场景 federation.remote.config.js 的 exposes 相呼应

    3. 在 defineAsyncComponent 进行加载前, 通过 window.WrapItem 把主场景中的模块代码替换(注入) 成本地调试代码(DebugItem.vue),此处理和 main-module 的ItemProxy对window.WrapItem的处理相呼应

    4. 在template中只是使用 defineAsyncComponent => AsyncComp 内容来展示主场景

Last Updated: 3/11/2024, 10:21:05 AM