# 前言

前面的章节针对微前端的框架做了简单的介绍,已经可以满足我们初学者的开发了,但是应用之间的通信还是存在问题的,假设我是一个 a 应用,基于 a 应用的某种动作或者某种状态,需要对象 b 应用进行更新,这个时候就需要我们想一个比较合理的方案来解决该问题来

一个好的体系结构是将微前端解耦,并且不需要频繁通信。基于路由的single-spa应用程序本质上需要较少的应用程序间通信。

微前端直接通信的可能有三样东西:

  • 方法,组件,逻辑,全局状态
  • API数据
  • UI状态

# 通信状态

# 方法,组件,逻辑,全局状态

这里,single-spa 官方有提供一个案例,大家可以参考一下:

你可以在不同git仓库或JS包的微前端之间导入或导出方法,组件,逻辑,全局状态:

// @org-name/auth
export function userHasAccess(permission) {
  return loggedInUser.permissions.some(p => p === permission);
}
import { userHasAccess } from '@org-name/auth'
// 在 single-spa应用程序中,从不同的微前端导入并使用util函数
const showLinkToInvoiceFeature = userHasAccess('invoicing');

# API数据

这里,single-spa 官方有提供一个案例,大家可以参考一下:

API数据通常不需要在 microfrontend 之间共享,因为每个 single-spa 应用程序控制不同的路由,而不同的路由通常有不同的数据。然而,有时您确实需要在 microfrontend 之间共享API数据。API对象的内存中的JavaScript缓存是一些公司用来解决这个问题的解决方案。对于React用户,这类似于带 Suspense 的数据获取,其中路由的获取逻辑是从使用数据的组件代码中分离出来的。

// 在api实用程序模块内部,您可以在另一个微前端调用导出的函数时延迟获取数据,或者在路由更改时急于获取数据。
let loggedInUserPromise = fetch('...').then(r => {
  if (r.ok) {
    return r.json()
  } else {
    throw Error(`Error getting user, server responded with HTTP ${r.status}`)
  }
})
export function getLoggedInUser() {
  return loggedInUserPromise;
}
import { getLoggedInUser } from '@org-name/api';
// 在app1内部,您可以从“ api”实用程序模块中导入某些内容
getLoggedInUser().then(user => {
  console.log('user', user);
});

# UI状态

如果两个微前端经常在彼此之间传递状态,可以考虑合并它们。当你的microfrontend不是孤立的模块时,它的缺点就会被放大

比如“是模态打开的”、“输入的当前值是多少”等等的UI状态,基本上不需要在微前端之间共享。如果您发现自己需要不断共享UI状态,那么您的微前端可能拆分的太多了。考虑将它们合并。

在极少的情况下在需要在 single-spa 应用程序之间共享UI状态,可以使用event emitter来实现。下面是一些event emitter的例子,可能会对你有所帮助。

  • Observables / Subjects (rxjs) - 一个微前端发布一个新值到一个可以被其他微前端消费的流对象,它可以向所有的微前端应用暴露出来以便其他应用可以订阅。
  • CustomEvents - 浏览器有一个内置的事件发射器系统,允许你触发自定义事件。查看此文档 (opens new window)以获得更多信息。window.dispatchEvent 事件允许任何其他的微前端通过 window.addEventListener 订阅。
  • 其他订阅发布系统。

# 结束语

我目前用的最多的就是 systemjs-webpack-interop ,通过 setPublicPath 一个公共的组件或者状态,然后 import 过去,微前端最主要的概念就是解耦,所以如果出现耦合性太高的业务时,是不建议做应用拆分的

这一章东西其实不多,但是我还是单独拿出来一章来写来,目的是希望大家对于通信的处理写的更简单,更干净一些,不要把太多的工作量放在通信方面,要记住微前端的目的是为了合理的 **解偶

阅读全文