angular - 在微服务环境中使用Angular 2+

标签 angular microservices single-page-application

在过去的几年中,我已经构建了多个 Angular (2 + typescript )应用程序,并且已经习惯了。但是,在一个我参与的项目中,我们使用的是微服务架构,该架构鼓励将所有内容分解为尽可能小的可用(和明智)部分,然后将这些部分加载到主页中,并且可以彼此独立地工作。

如果这是一个没有交互内容的常规HTML页面,那将很容易做到。但是在这种情况下,我们可以创建一个页面,其中包含:搜索功能,列表功能和详细信息模式。这些东西都需要能够彼此交互并对事件使用react,并且最好充当SPA,并且在导航时不需要页面加载。

在经典的Angular应用程序中,我会使用模块和组件(依次可以使用公用的共享组件,并且可以全部懒加载)构建该组件,并在单个Angular应用程序中设置共享路由。但是,如何在保持微服务标准/体系结构的同时做到这一点呢?前端是否还需要它?可以将Angular中的模块视为一种微服务,但这足够好吗?

我发现了诸如https://single-spa.js.org/之类的库。这是解决这个问题的方法吗?创建多个小型应用程序并将它们与上方的另一个框架缝合在一起?但是,这将需要大量带宽,因为前端需要多次下载多个内容,而不是一次下载。

乍一看,这似乎使任务复杂化,几乎没有 yield 。特别是因为在常规的Angular应用程序中,该应用程序的一部分可以停止工作而不会真正影响Angular SPA的另一部分(这是MS的主要目标之一)。是否有一些标准化的指标可以用来查看何时创建单个SPA或更好地使用拆分的微服务变体?

最佳答案

摘要

微服务后端不需要微服务前端。除非您有一个非常大的应用程序,它可能会比多个较小的独立应用程序更好,否则您可能希望按模块组织 Angular 应用程序。在这种情况下,Angular可能不是您的最佳框架。

您不应该仅仅因为服务器端应用程序是这样构建的,而选择以某种方式构建前端应用程序。在后端使用微服务,在前端使用单个Angular应用程序是完全可行的。但是,如果要对其进行划分并且这样做很有意义,则应首先考虑使用多个模块。

您已经在使用诸如HttpClientModule之类的模块(这些模块已添加到app.module文件的导入中),因此创建自己的模块并不是一个大步骤。模块将包含与应用程序的一部分有关的组件,例如特定功能或一组UI组件。

模块不会立即提供任何技术优势,但是从开发人员的 Angular 来看,它们有助于组织大型代码库。但是,您可以选择延迟加载这些以加快应用程序的初始加载时间,并预加载延迟加载的模块,这样应用程序将在加载初始页面后加载其他模块。最初,您可能希望将所有模块都保存在单个代码库中,这使得管理代码更加容易。随着应用程序的增长,如果您觉得这是个好主意,则可以将模块拆分为单独的存储库。然后可以将它们与您的软件包管理器(NPM)一起安装并导入,就像导入其他第三方模块一样,但是您仍然有一个应用程序。

使用这种方法,您仍然可以享受单页应用程序的好处,但是它更具模块化。在极端情况下,您可以将其拆分为由不同服务器路由提供服务的完全不同的应用程序。选择哪个选项取决于您的要求,但以下内容可能会有所帮助。

单个模块

  • 一个应用程序,一个代码库,一个模块。
  • 对于功能有限的小型简单应用程序,请使用此选项。

  • 多个模块
  • 一个应用程序,但有多个模块。
  • 代码更加井井有条,使其对开发人员更友好
  • 模块可以独立加载,从而减少了初始加载时间。
  • 对于较大的应用程序或该应用程序至少有两个不同的部分,请使用此选项。

  • 多种应用程序
  • 多个应用程序,每个应用程序可以用一个或多个模块构建。
  • 模块可以作为外部依赖项在应用程序之间共享。
  • 如果应用程序的各个部分完全分开,请使用此选项。
  • 您将需要在此处合并传统多页应用程序的各个方面,并将服务器用于(某些)路由。您将拥有其他非 Angular 复杂性;一个应用程序将如何与另一应用程序共享数据?
  • 如果您不知道是否需要此功能,则可能不需要。

  • 99%的Angular项目应该是组织为多个模块的单个应用程序。鉴于您的问题是特定于Angular的,因此我创建了一个带有路由的简单应用,然后将其拆分为多个延迟加载的模块,以便您进行比较。

    Here's the standard single module app.

    Here's a fork of it with exactly the same functionality but split into modules.

    我使用了功能模块,以及一个共享模块。

    功能模块

    与功能有关的所有组件,指令等都包含在功能模块中。您可以看到AppModule在多模块版本中更加精益。

    每个模块应具有自己的路由器(如果功能具有路由)。应该从AppModule中删除对延迟加载的模块的所有引用,以防止Webpack将它们包含在主捆绑包中,这将导致它们立即被加载。然后,可以使用模块路径的字符串表示形式来指向模块:
    const appRoutes: Routes = [
      { path: '', component: HomeComponent },
      { path: 'places', loadChildren: './places/places.module#PlacesModule' },
      { path: 'products', loadChildren: './products/products.module#ProductsModule' }
    ]
    

    有不同的预加载策略来确定如何加载延迟加载的模块。 PreloadAllModules将在加载初始模块后加载所有延迟加载的模块。
    imports: [
      RouterModule.forRoot(appRoutes, { preloadingStrategy: PreloadAllModules })
    ],
    

    共享模块

    共享模块用于使组件指令等可用于多个模块。他们需要导出将由其他模块以及CommonModule使用的任何声明:
    exports: [
      CommonModule,
      LegalComponent
    ]
    

    服务

    服务也可以提供到各个模块中。当提供给延迟加载的模块或延迟加载的模块中使用的共享模块时,您将获得该服务的其他实例。为了使示例简单,我将服务保留在AppModule提供程序数组中。

    关于angular - 在微服务环境中使用Angular 2+,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55723434/

    相关文章:

    Angular2 注入(inject)的路由器未定义

    filter - 使用微服务架构进行分页或过滤数据的策略有哪些?

    SPA 的 PHP 框架?

    angular - 在 Angular 2 及更高版本中访问 Azure Web App 设置的最佳方法

    angular - ngOnDestroy 不销毁 localStorage token

    angular - 错误 - 此命令只能在 CLI 项目中运行

    spring - 通过 Eureka Server 访问微服务

    mysql - 如何从 Spring Boot Docker 服务连接远程 MySQL DB?

    javascript - Knockout-Kendo Grid 中的服务器分页绑定(bind)到 viewmodel 中的本地(服务器填充)ko.observableArray 属性

    azure - 如何使用 Azure AD 身份验证限制 Multi-Tenancy 应用程序中的租户