博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
前端单页应用微服务化解决方案4 - 消息总线
阅读量:5937 次
发布时间:2019-06-19

本文共 3723 字,大约阅读时间需要 12 分钟。

文章转发自

微前端的消息总线,主要的功能是搭建模块与模块之间通讯的桥梁.

黑盒子

问题1:

应用微服务化之后,每一个单独的模块都是一个黑盒子, 里面发生了什么,状态改变了什么,外面的模块是无从得知的. 比如模块A想要根据模块B的某一个内部状态进行下一步行为的时候,黑盒子之间没有办法通信.这是一个大麻烦.

问题2

每一个模块之间都是有生命周期的.当模块被卸载的时候,如何才能保持后续的正常的通信?

ps. 我们必须要解决这些问题,模块与模块之间的通讯太有必要了.

打破壁垒

在github上,给出来一解决方案.

基于Redux实现前端微服务的消息总线(不会影响在编写代码的时候使用其他的状态管理工具).

大概思路是这样的:

每一个模块,会对外提供一个 Store.js.这个文件 里面的内容,大致是这样的.

import { createStore, combineReducers } from 'redux'const initialState = {  refresh: 0}function render(state = initialState, action) {  switch (action.type) {    case 'REFRESH':      return { ...state,        refresh: state.refresh + 1      }    default:      return state  }}// 向外输出 Reducerexport const storeInstance = createStore(combineReducers({ namespace: () => 'base', render }))复制代码

对于这样的代码,有没有很熟悉? 对,他就是一个普通的Reducer文件, 每一个模块对外输出的Store.js,就是一个模块的Reducer.

Store.js 如何被使用?

我们需要在模块加载器中,导出这个Store.js

于是我们对模块加载器中的Register.js文件 (该文件在上一章出现过,不懂的同学可以往回看)

进行了以下改造:

import * as singleSpa from 'single-spa';//全局的事件派发器 (新增)import { GlobalEventDistributor } from './GlobalEventDistributor' const globalEventDistributor = new GlobalEventDistributor();// hash 模式,项目路由用的是hash模式会用到该函数export function hashPrefix(app) {...}// pushState 模式export function pathPrefix(app) {...}// 应用注册export async function registerApp(params) {    // 导入派发器    let storeModule = {}, customProps = { globalEventDistributor: globalEventDistributor };    // 在这里,我们会用SystemJS来导入模块的对外输出的Reducer(后续会被称作模块对外API),统一挂载到消息总线上    try {        storeModule = params.store ? await SystemJS.import(params.store) : { storeInstance: null };    } catch (e) {        console.log(`Could not load store of app ${params.name}.`, e);        //如果失败则不注册该模块        return    }    // 注册应用于事件派发器    if (storeModule.storeInstance && globalEventDistributor) {        //取出 redux storeInstance        customProps.store = storeModule.storeInstance;        // 注册到全局        globalEventDistributor.registerStore(storeModule.storeInstance);    }    //当与派发器一起组装成一个对象之后,在这里以这种形式传入每一个单独模块    customProps = { store: storeModule, globalEventDistributor: globalEventDistributor };    // 在注册的时候传入 customProps    singleSpa.registerApplication(params.name, () => SystemJS.import(params.main), params.base ? (() => true) : pathPrefix(params), customProps);}复制代码

全局派发器 GlobalEventDistributor

全局派发器,主要的职责是触发各个模块对外的API.

GlobalEventDistributor.js

export class GlobalEventDistributor {    constructor() {        // 在函数实例化的时候,初始一个数组,保存所有模块的对外api        this.stores = [];    }    // 注册    registerStore(store) {        this.stores.push(store);    }    // 触发,这个函数会被种到每一个模块当中.便于每一个模块可以调用其他模块的 api    // 大致是每个模块都问一遍,是否有对应的事件触发.如果每个模块都有,都会被触发.    dispatch(event) {        this.stores.forEach((s) => {            s.dispatch(event)        });    }    // 获取所有模块当前的对外状态    getState() {        let state = {};        this.stores.forEach((s) => {            let currentState = s.getState();            console.log(currentState)            state[currentState.namespace] = currentState        });        return state    }}复制代码

在模块中接收派发器以及自己的Store

上面提到,我们在应用注册的时候,传入了一个 customProps,里面包含了派发器以及store. 在每一个单独的模块中,我们如何接收并且使用传入的这些东西呢?

import React from 'react'import ReactDOM from 'react-dom'import singleSpaReact from 'single-spa-react'import RootComponent from './root.component'import { storeInstance, history } from './Store'import './index.less'const reactLifecycles = singleSpaReact({  React,  ReactDOM,  rootComponent: (spa) => {    // 我们在创建生命周期的时候,把消息总线传入的东西,以props的形式传入组件当中    // 这样,在每个模块中就可以直接调用跟查询其他模块的api与状态了    return 
}, domElementGetter: () => document.getElementById('root')})export const bootstrap = [ reactLifecycles.bootstrap,]export const mount = [ reactLifecycles.mount,]export const unmount = [ reactLifecycles.unmount,]复制代码

未完待续 ...

相关文章

Demo

转载地址:http://wuttx.baihongyu.com/

你可能感兴趣的文章
timestamp的两个属性:CURRENT_TIMESTAMP 和ON UPDATE CURRENT_TIMESTAMP
查看>>
Hadoop HBase概念学习系列之HRegion服务器(三)
查看>>
nginx 配置https
查看>>
linux 给文件夹权限
查看>>
unity, Shader.Find的一个坑
查看>>
C语言 · 求矩阵各个元素的和
查看>>
Protocol buffers--python 实践(二) protocol buffers vs json
查看>>
V-rep学习笔记:机器人路径规划1
查看>>
free -m 内存
查看>>
branch prediction
查看>>
Python基础语法06--文件
查看>>
分布式系统唯一ID生成方案汇总【转】
查看>>
java----代理机制或动态类的生成
查看>>
windows下命令行终端使用rz上传文件参数详解
查看>>
信息隐藏技术
查看>>
nginx禁止未绑定域名访问返回444
查看>>
c++重载后置++和--
查看>>
PostgreSQL远端访问
查看>>
WIN7如何替换开机登录画面
查看>>
AAuto如何发布EXE文件
查看>>