基于 React 的微前端:Piral 简析

近年来,“微前端”一词已进入了主流技术领域。虽说实践中实现微前端的模式有很多,但我们认为可能存在一个“理想”的解决方案——这种方案既能具备单体架构的优势,又能结合使用隔离模块的某些优秀特性。

在这篇文章中,我们将研究基于React的微前端解决方案,其可以无限制地扩展开发工作、渐进部署并基于无服务器基础架构。我们的解决方案由一个应用外壳和一些独立开发的模块组成,这些模块动态地集成到应用外壳中。

我们将使用的解决方案称为Piral,这是我们的模块化前端架构的参考实现。这一前端架构的定义则基于我们在过去三年中从多个客户项目中获得的实际经验。

Modulith

我们的方法是单体应用与微应用(称为Modulith)之间的一个交集,其优点在于我们可以做到以下很多事情:

  • 渐进采用(通过简单的迁移路径),
  • 共享库(例如模式库),或
  • 共享现有的布局/应用程序框架。

所有这些都只是可能性。不利之处在于采用此类选项时需要担负的职责,例如,在应用外壳中包含共享库将带来经典的依赖项管理问题。

Modulith与微前端之间有什么关系呢?下图中展示了一个可行的微前端设计——每个服务都有一个关联的微前端。每个微前端都代表一个孤立的单元,可能带有自己的模式库和技术。

相比之下,Modulith尝试重用负责UX的重要部分。因此这里的一致性至关重要。显然,使用这种方法也会遇到一些挑战,但一致性和冗余之间的考虑才是创建前端UI与后端服务不同的原因。

上图加入了Modulith,它给出了与总体责任相关的边界框。入口点是应用程序外壳。

应用程序外壳

通常来说,要创建一个使用微前端的新应用程序,第一步就是制作应用外壳的骨架。应用外壳包含共享布局、一些核心业务功能(如果有)以及共享依赖关系。应用外壳还负责设置所有模块都必须遵循的基本规则,这些模块在Piral(https://github.com/smapiot/piral)的上下文中称为“Pilet”。

在一个最简单的示例中,应用外壳可能如下所示:

import * as React from "react";
import { render } from "react-dom";
import { Redirect } from "react-router-dom";
import { createPiral, Piral, SetRoute } from "piral";

const piral = createPiral({
  requestPilets() {
    return fetch("https://feed.piral.io/api/v1/pilet/mife-demo")
      .then(res => res.json())
      .then(res => res.items);
  }
});

const app = <Piral instance={piral} />;

render(app, document.querySelector("#app"));

这将创建一个空白的应用外壳,其代码已允许将不同的页面和片段缝合在一起。 太好了,那么我们应该如何部署这个应用程序呢?这里有两件事要做:

  1. 构建(即打包)该应用程序,并将其推送到某些存储上。
  2. 打包源代码并将其推送到一个(私有)存储库。或者:共享压缩包。

第一步是为了确保可以从Internet访问我们的应用程序。第二步需要具体解释一下。处理微前端时的一个问题是“我如何开发这些东西”?毕竟,我们手中只有一个大型应用程序的模块。如果我们想研究这些模块之间的交互,该怎么办?如果我们想看看我们的样式是否适合较大的UX,又该怎么办?

这些问题的答案都可以在原生移动应用的开发过程中找到:我们也不是凭空开发原生移动应用的。实际上我们有一个模拟器——一款外观和行为与我们将要部署到的系统类似的软件。用微前端术语来说,我们需要在开发流程中使用应用外壳。但是我们怎样获得这个外壳?尤其需要考虑的是我们想要在离线状态下继续开发工作。于是,我们需要一种共享应用外壳的方法以获得一个“仿真”的外壳,从而实现快速的开发流程。

深入解析Pilet

应用外壳是非常重要的,而所有那些Pilet更为关键。大多数时候,基于Piral的应用外壳仅处于维护模式——所有特性都是在Pilte中独立开发的。

Pilet只是一个NPM包,其中包含一个JavaScript文件(“main bundle”主包,用于 UMD 生成)。它还可能包含其他文件(例如CSS文件和图像等),以及更多JavaScript文件(“side bundles”附加包)。

从编程的角度来看,一个Pilet仅有一个约束——它输出一个称为setup的函数。该函数接收API,后者允许Pilet的开发人员确定模块中要使用的技术和函数。

简而言之,一个Pilet可能会像下面这样简单:

import * as React from "react";
import { PiletApi } from "app-shell";

export function setup(app: PiletApi) {
  app.registerPage("/sample", () => (
    <div>
      <h1>Hello World!</h1>
      <p>Welcome to your personal pilet :-).</p>
    </div>
  ));
}

所以,Pilet应该尽可能地“懒惰“。因此,任何较大的(甚至可能不需要立即使用的部件)都应该仅在需要时加载。

可以使用我们标准工具包中的方法进行简单的转换:

// index.tsx
import * as React from "react";
import { PiletApi } from "app-shell";

const Page = React.lazy(() => import("./Page"));

export function setup(app: PiletApi) {
  app.registerPage("/sample", Page);
}

// Page.tsx
import * as React from "react";

export default () => (
  <div>
    <h1>Hello World!</h1>
    <p>Welcome to your personal pilet :-).</p>
  </div>
);

这些在Piral里都没问题。重要的是要记住,在上面的(非常简单的)代码库中,仅在根模块中提到了Piral。这是一个不错的设计。作为Pilet的作者,你可能会决定将Piral整合到怎样的深度上。我们的建议是仅将根模块用于这里的集成。 到目前为止一切都很好,但是如何将这个Pilet带入我们的(已部署的)应用外壳呢?答案是feed服务。我们注意到,我们的应用外壳从“https://feed.piral.io/api/v1/pilet/mife-demo”中获取了一些数据。对此请求的响应包含一些元数据,这些元数据允许Piral通过接收到一个指向其主包的链接来检索不同的Pilet。

每个人都可以自由开发或推出定制的feed服务。有了相应的规范和基于Express的Node.js示例,我们认为基础工作已经准备就绪了。此外,我们在线托管了一个灵活的feed服务。它包含了快速入门所需的所有内容。

Piral CLI

以上所有“魔法“都可以在Piral CLI中找到。Piral CLI是一个简单的命令行工具,它负责:

  • 搭建骨架(piral new用于新的应用外壳,pilet new用于新的pilet)
  • 调试(使用piral debug来调试一个应用外壳;对于pilet,使用pilet debug)
  • 构建(使用piral build或pilet build)
  • 发布pilet(pilet publish)

在整个高层架构中,Piral CLI恰好位于开发人员和feed服务之间的位置。如上所述,feed服务是这一架构中唯一需要的后端组件。它使应用程序外壳程序与特定模块解耦,并允许使用更高级的用例,例如用户特定的模块交付。

Piral CLI在内部使用Parcel。因此所有用于Parcel的插件(以及它们的配置-如果需要)都可以正常工作。

Piral CLI还支持个人的插件。

了解更多

更多关于Piral的文章:

此外,Piral的文档也很有用,它包含所有类型的见解、一个手把手教程以及一个可用扩展的列表。

获取Piral

如果你正在考虑采用微前端,那么Piral可能很适合你。它只需很少的基础架构即可工作,而且可以为用户带来很大的价值。 Piral旨在提供一流的开发体验,包括渐进采用的能力(例如,从现有应用程序开始——先做好加载Pilet的功能,再开始开发Pilet)。

还可以通过选择“转换器”(例如Angular和Vue)来进行多种现有技术或传统技术的移植。所有官方扩展(包括转换器)的最新列表可在我们的文档页面上访问(https://docs.piral.io/reference/extensions)。

我们期盼得到你的反馈!????

原文链接

https://dev.to/florianrappl/microfrontends-based-on-react-4oo9

  • 发表于:
  • 本文为 InfoQ 中文站特供稿件
  • 首发地址https://www.infoq.cn/article/YH5mO2bVjmwLNYmXJeEP
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券