【问题标题】:Micro frontend application微前端应用
【发布时间】:2018-12-20 04:19:06
【问题描述】:

我有 1 个项目,分为多个 SPA,我有 5 个 SPA,其中 2 个用 Angular 编写,2 个用 react 编写,1 个用 vue js 编写。现在我有一个集成服务器,它将根据路由提供不同的文件。我需要以最少的数据库交互将数据从一个应用程序共享到另一个应用程序。这是微前端的场景。希望这能解决我的问题。

任何帮助将不胜感激。

【问题讨论】:

  • 您可以在他们之间共享公共商店。例如:mobx 兼容所有这些
  • 这个 mobx 在哪里存储数据,在 localstorage 或 cookie 或其他地方?它如何在不同的应用程序之间共享数据?这些是在项目实施之前最重要的问题。

标签: node.js angular reactjs vue.js single-page-application


【解决方案1】:

您可以通过三种方式共享数据:

  1. URL:查询参数/路径参数(仅适用于 ID、过滤器等小数据)
  2. 会话存储:仅当您不导航到其他选项卡/窗口时才使用此选项
  3. 本地存储:最方便和首选的方式

当然,如果您将状态持久化到本地存储,那么您必须在用户注销时自行处理状态刷新。

这是一个有点痛苦的处理过程。您必须编写代码来管理 JSON 到本地存储的序列化和反序列化。为了缓解这种情况,最好在所有微应用中使用相同的状态管理解决方案。我推荐使用 Redux/MobX 来做到这一点。但是如果你使用 Redux for React、Ng-Rx for Angular 和 Vuex for Vue,那么你将没有任何现成的解决方案。

此外,当您将状态保存到本地存储时,出于性能原因,要么对其进行去抖动,要么延迟执行,几乎没有延迟。

过去两年我们一直在使用微前端,我们使用本地和会话存储的组合来做我们的事情。幸运的是,对于我们使用 Redux 的所有应用程序,甚至使用 Vue,这允许我们使用 redux-localstorage

您也可以使用 Cookie,但通常最好避免使用它们。

【讨论】:

  • localstorage中保存的数据可能是jwt token。我认为将令牌和其他重要的东西放在本地存储上并不是一个好主意。我可以做一些操作,但是有没有一种方法不会在客户端公开令牌?
  • @Amit,它是 JWT 意味着它是加密的。没有解密密钥,任何人都无法阅读它。所以你不必担心。此外,在将令牌发送给客户端的那一刻,无论您是否存储它,令牌都会暴露出来。
  • 我知道 JWT 是加密的,可以通过解密密钥解密,但是由于敏感数据是开放的,因此容易受到 XSS 攻击,这意味着它可以被复制并向我们的网站发出请求,我们可能不知道。第三方JS库可以是一种方式。我不支持存储 JWT 或任何此类数据不应保存在本地存储中。任何其他可以替换本地存储的东西都可以解决我的问题。如果我错了,请告诉我。请提出任何其他选择。
  • 是的@Amit,我同意。如果您使用第三方,那么您对 ​​XSS 持开放态度。在这种情况下,除了 cookie,您无法使用其他任何东西。而且,您的 cookie 应该是 httpOnly cookie。您将不得不在客户端没有 JWT。没有其他方法可以不让服务器参与进来。
  • @IoneWolf 使用httpOnly 将您的令牌存储在 Cookie 中。这样它们就不容易出现 XSS 并且它们由浏览器透明地设置,即在单个会话中它们将可用于您所有不同的 SPA。
【解决方案2】:

另一种选择是使用像EEV 这样的前端事件总线。您的应用程序外壳将负责创建共享事件侦听器。然后每个微前端都可以在该共享通道上发出事件。

您还可以在您的 App Shell 中使用 RxJS 主题作为消息总线,并在微前端应用程序中订阅它。 Here's an example

我希望这能给你一些额外的想法。

【讨论】:

    【解决方案3】:

    我遇到了同样的情况,我必须将数据从一个微应用传递到另一个。 经过大量的研发后,我发现基于事件的通信是最好的,我将数据以事件对象的形式传输。 这是一些示例: 发送数据:

    var event = new CustomEvent('userData', { "detail": { "id": id, ...rec } });
    window.dispatchEvent(event);
    

    在其他应用程序上接收数据是:

    window.addEventListener("userData", function (e: CustomEvent) {
          this.id = e.detail.id;
          this.country = e.detail.country;
          this.contact = e.detail.contact;
          this.company = e.detail.company;
          this.changeDetectorRef.detectChanges();
    }.bind(this));
    

    这种方式不需要DB通信。

    希望这能解决您的问题!!!

    编码愉快!!!

    【讨论】:

      猜你喜欢
      • 2021-10-12
      • 2019-02-01
      • 1970-01-01
      • 2020-03-21
      • 2021-11-03
      • 2021-05-11
      • 2023-01-31
      相关资源
      最近更新 更多