【问题标题】:Using Angular 2+ in a Microservice environment在微服务环境中使用 Angular 2+
【发布时间】:2019-09-07 10:58:41
【问题描述】:

在过去的几年里,我已经构建了几个 Angular(2+ 打字稿)应用程序,并且已经习惯了。然而,在我参与的一个项目中,我们正在使用微服务架构,该架构鼓励将所有内容拆分为尽可能小的可用(和合理)部分,这些部分稍后会加载到主页中,并且可以彼此独立运行。

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

在一个经典的 Angular 应用程序中,我会使用模块和组件(它们反过来可以使用公共共享组件并且都可以延迟加载)在单个 Angular 应用程序中设置共享路由来构建它。但是如何在保持微服务标准/架构的同时做到这一点呢?这对前端来说是否可取?人们可以将 Angular 中的模块视为一种微服务,但这是否足够好?

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

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

【问题讨论】:

  • 你猜过角度应用程序是模块吗?也许您可以将应用程序封装到 Angular 模块中,并在需要时立即导入到您的应用程序中。
  • 但这真的能将模块彼此分离吗?这不是在单个 Angular 项目中完成的吗?

标签: angular microservices single-page-application


【解决方案1】:

总结

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


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

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

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

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

单模块

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

多个模块

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

多个应用程序

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

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 提供程序数组中。

【讨论】:

    【解决方案2】:

    我认为没有标准的方法可以做到这一点。而不是共享组件构建库来共享代码。应用程序将通过 REST(后端)相互交互。你甚至可以使用 Angular 元素。

    我发现这个关于企业应用程序的ppt by Manfred Steyer 非常有用。

    【讨论】:

      【解决方案3】:

      Angular 或其他框架不是为这种用途而设计的。这对我来说是一个糟糕的选择。将应用程序划分为多个模块并使用相同的代码库要容易得多。

      【讨论】:

        【解决方案4】:

        我已经尝试过Multiple Applications方法,

           MainApp { 
             projects:{
               App1,
               App2
               }
           }
        

        我的应用程序之间的路由和导航工作正常, 但是我找不到在我的主应用程序中重用子应用程序组件的方法。 可能相反(来自 MainApp sharedModule => Child App)。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-09-05
          • 1970-01-01
          • 2017-05-01
          • 1970-01-01
          • 2017-02-14
          • 2018-06-04
          • 2022-10-05
          • 2018-08-18
          相关资源
          最近更新 更多