微服务通信的解决方案-无界

675 阅读3分钟

参考链接

wujie-micro.github.io/doc/guide/s…

微前端

  • 独立开发、独立部署、独立运行 不同的团队可以独立开发不同的微服务,彼此之间松耦合,这加快了开发速度和迭代周期。拆包减小项目体积,提供项目运行性能。
  • 技术异构 不同的微服务可以使用不同的技术栈,如 React、Vue、Angular 等,这让我们可以选择最合适的技术来解决不同的问题,不受某一技术的限制。
  • 高可用性 微服务互相隔离,一个微服务发生故障不会影响其他微服务,这提高了系统整体的高可用性。

iframe 方案

  • 优点 原生,上手简单 web应用隔离的非常完美,无论是js、css、dom都完全隔离开来
  • 缺点 路由状态丢失,刷新一下,iframe的url状态就丢失了 dom割裂严重,弹窗只能在iframe内部展示,无法覆盖全局 web应用之间通信非常困难 每次打开白屏时间太长,对于SPA 应用来说无法接受

无界

优点
  • 1.上手简单
  • 2.web应用隔离的非常完美,无论是js、css、dom都完全隔离开来
  • 3.开启路由同步后,刷新浏览器或者将url分享出去子应用的路由状态都不会丢失
  • 4.dom割裂不严重,弹窗可以在全局展示
  • 5.通信简单
  • 6.不需要针对vite额外处理
底层原理

使用shadowDom 隔离css,js使用空的iframe隔离

无界入门

1.根据主应用的框架,在主应用中安装对应版本的插件

npm i wujie-vue2 -S
npm i wujie-vue3 -S
npm i wujie-react -S

2.主应用的main.js

import Wujie from 'wujie-vue3'

const app = createApp(App);
app.use(Wujie)

3.主应用引入子应用页面

  • 前提, 子应用的资源和接口的请求都在主域名发起,所以会有跨域问题,子应用必须做cors 设置
// 子应用开发环境资源允许被主应用访问
  devServer: {
    headers:{
        "Access-Control-Allow-Origin":  "*",
     }
   },
  • 载入子应用
<!-- http://localhost:1234/# 和 http://127.0.0.1:5173/ 分别对应两个子应用的访问地址-->

<WujieVue width="100%" height="100%" name="vue_test" url="http://localhost:1234/#/" :props="{ user }" :sync="true" v-if="childPageKey==='vue_test'"></WujieVue>
<WujieVue width="100%" height="100%" name="vue3_demo" url="http://127.0.0.1:5173/" :props="{ user }" :sync="true" v-if="childPageKey==='vue3_demo'"></WujieVue>

无界常用配置项

  • name: string; 唯一性用户必须保证[必须]
  • url: string; 需要渲染的url [必须]
  • sync?: boolean; 路由同步开关,默认值: false
// sync
// true: 刷新浏览器或者将url分享出去子应用的路由状态都不会丢失';
// false: 刷新无效,但是前进后退依然有效 
  • prefix?: { [key: string]: string }; 用途: 缩短子应用同步到主应用的路径(sync:true 时生效)
// 示例
<WujieVue width="100%" height="100%" alive name="vue_test" url="http://localhost:1234/#/" :props="{ user }" :sync="true" v-if="childPageKey==='vue_test'"  :prefix="{ vue_test: '/#/vue_test/page', }"></WujieVue>

//  /vue_test/page/hello  => {vue_test}/hello
//  /vue_test/page/about  => {vue_test}/about
  • alive?: boolean;子应用是否开启保活模式,默认值: false; 用途:解决子应用切换白屏问题;如果主应用上有多个菜单栏跳转到子应用的不同页面,此时不建议采用保活模式

  • props?: { [key: string]: any }; 注入给子应用的数据

// 主应用
<WujieVue name="xxx" url="xxx" :props="{ data: xxx, methods: xxx }"></WujieVue>
// 子应用
const props = window.$wujie?.props; // {data: xxx, methods: xxx}

无界提供三种方式进行通信

  • props 通信
  • window 通信
  • eventBus 通信
window 通信

主应用调用子应用的全局数据

// 子应用中 main.js
window.pageName = 'VueTest'

// 主应用获取pageName
window.document.querySelector("iframe[name=子应用id]").contentWindow.pageName;

子应用调用主应用的全局数据

window.parent.xxx;
eventBus 通信

主应用使用方式:

// 如果使用wujie
import { bus } from "wujie";

// 如果使用wujie-vue
import WujieVue from "wujie-vue";
const { bus } = WujieVue;

// 如果使用wujie-react
import WujieReact from "wujie-react";
const { bus } = WujieReact;

// 主应用监听事件
bus.$on("事件名字", function (arg1, arg2, ...) {});
// 主应用发送事件
bus.$emit("事件名字", arg1, arg2, ...);
// 主应用取消事件监听
bus.$off("事件名字", function (arg1, arg2, ...) {});

子应用使用方式:

// 子应用监听事件
window.$wujie?.bus.$on("事件名字", function (arg1, arg2, ...) {});
// 子应用发送事件
window.$wujie?.bus.$emit("事件名字", arg1, arg2, ...);
// 子应用取消事件监听
window.$wujie?.bus.$off("事件名字", function (arg1, arg2, ...) {});