Angular和Micro-Frontends

时间:2017-12-13 12:29:00

标签: javascript html angular microservices

我正在研究如何将巨大的单页整体分割成微前端架构。

想法:

  • 该页面由几个可自主运行的组件组成
  • 每个组件由一个开发团队管理
  • 每个团队都可以更改,更新和部署他们的组件,而不会破坏其他团队的组件
  • 每个团队选择自己的工具堆

原因

要有效地开发大型应用程序,您需要让很多人参与其中。但是,每个应用程序/团队的开发人员数量不能很好地扩展。然而,独立团队并行开发多个独立应用程序可以任意缩放

考虑到这一点,团队必须选择自己的工具堆,特别是执行第三方库的独立版本升级(如angular,react,jquery)。如果不是这种情况,框架更新需要与每个组件兼容才能将其部署到生产环境。

这是否适用于Angular?

虽然需要进行独立的版本升级,但将团队限制在一些受支持的框架(Angular,React,Vue,Polymer ......)是合理的,现在我尝试构建一个纯粹由Angular组成的演示 - 的应用程序。

然而,即使Angular 5被认为是支持大型多模块应用程序的平台框架,但在同一浏览器窗口中运行几个独立的角度应用程序几乎是不可能的。

我设法通过利用HTML-Imports在单个webapp上引导几个Angular-Apps(不同版本,每个版本都在自己的服务器上托管)。但是,有几个global依赖项需要在应用程序之间共享

  • zone.js只能启动一次
  • 路由需要网址更改
  • 像cookies,sessionstorage等浏览器......

网上有几篇关于如何引导多个角度模块的文章,但它们都引用同一个核心应用程序中的多个模块,这反过来意味着它们都在相同的框架版本上运行并且更新意味着你必须重建和部署整个巨石。

除了" iframes"还有其他解决方案吗?让多个Angular(5)应用程序在同一个页面上运行?

7 个答案:

答案 0 :(得分:9)

而不是完全建议反对这个想法主要是由于单独的堆栈要求,我将列出权衡并提供一些限制,这将使这成为可能。

  

该页面由几个可自动运行的组件组成

我们都知道这是在Angular组件中提供的,具有明确的输入和输出分界。

小CAVEAT:当/如果您传递@Input的对象并发出具有@Output()交互组件的事件对象时,必须事先就已定义的接口达成一致。

解决方法:创建另一个仅定义这些工件的TypeScript项目。所有其他"组件项目"将取决于具体版本。

  

每个组件由一个开发团队管理

Dev Teams可以像开源中的其他Angular项目一样分发组件。他们可以将他们的工件发布到某个npm存储库。要开发可归因组件,我建议您参考Angular Material2,这可能是压倒性的,或者您可能会使用每个组件团队使用的ngx-library-builder(基于Angular Team Member filipesilva/angular-quickstart-lib )。

CAVEAT:直到此日期,角度团队没有快速组件库共享项目设置,如Angular CLI中所示。但是,许多开发人员已经创建了某种类型的库构建器来填补Angular CLI中的空白。

  

每个团队都可以更改,更新和部署他们的组件,而不会破坏其他团队的组件

让您的主项目拉出所有组件,并在某个CI服务器上执行定期/更改触发的构建/部署。这主要是使用所有最新的组件版本生成AOT生产版本。 作为额外的奖励,您可以进行一些抽象的e2e测试,以进行一些自动化集成测试,确保一个组件的副作用不会破坏其他组件。

CAVEAT:很难控制每个团队如何开发组件,即他们正在对内存,CPU和其他资源进行最佳使用和处置。例如如果一个团队开始创建订阅并且不删除它们会怎么样?使用一些静态代码分析可能很有用,但您目前不会使用此源代码 - 除非他们也发布了源代码。

  

每个团队选择自己的工具堆

这是一个完整的交易破产者,除非你的意思是" toolstack"就像IDE和一些" devDependencies"等开发人员工具一样。虽然" devDependencies"的某些部分;每个团队必须具有相同的角度开发工具包版本,如编译器等。

至少每个团队必须使用相同的Angular,RxJS等。

最重要的是,应该注意每个团队都不会引导任何组件 - 只有主项目会有一个引导模块,并且会引导根组件。这有助于解答您的zone.js问题

  

这是否适用于Angular?

如果你认识到这些限制并提供治理,我建议你去做。

答案 1 :(得分:4)

我们问自己同样的问题。不幸的是,这似乎是问题的答案

除了" iframes"还有其他解决方案吗?让多个Angular(5)应用程序在同一个页面上运行(编辑:每个Angular应用程序可以使用不同的Angular版本)?

目前正在

不,不幸的是,只要你想使用Angular的变化检测(使用zone.js)。

由于zone.js Angular污染了全局范围。更糟糕的是,zone.js修补了大量的浏览器API(https://github.com/angular/zone.js/blob/master/STANDARD-APIS.md)以检测区域何时完成。

如果框架不接触全局范围,那么只能在一个页面中使用不同版本的框架而没有副作用(这似乎适用于React和Vue)。然后,您可以通过Webpack将不同的框架版本与每个应用程序捆绑在一起(具有独立的范围和每个应用程序包大小增加的缺点)。

因此,如果您想使用Angular构建一个网页,其中不同的应用程序/模块应集成在一个页面上,目前唯一可行的解​​决方案是创建一个部署整体(例如,在一个Angular应用程序中捆绑来自不同团队的不同模块)通过CI / CD系统,正如bhantol在他的回答中所解释的那样)。

似乎Angular团队也意识到了这个问题,他们可能会使用以下主要版本来解决它。请参阅robwormwald关于Angular Elements路线图的以下Github问题的答案:https://github.com/angular/angular/issues/20891

希望在下一个主要版本的Angular 6在3月底发布时,Angular团队会就该主题提供更多信息。

答案 2 :(得分:2)

查看角度元素(自定义元素)。 https://moduscreate.com/blog/angular-elements-ngcomponents-everywhere/

新的Ionic版本(4)完全基于它,可以在每个版本的Angular和每个JS框架上使用。

为此,他们创建了https://stenciljs.com/,可以帮助您创建自定义元素。

但是如果所有团队都在使用Angular,那么他们每个人都可以使用ngm来创建一个库。

答案 3 :(得分:1)

是的,你可以。

然而在撰写Web组件时,您并不想陷入框架,因为Web组件的重点可能在任何地方重用。

我与您分享您的愿景,对于软件的质量以及开发人员在实施时处理重点功能而非大型应用程序的效率肯定更高。

最后,您现在正在寻找的不是Angular,而是 StencilJS 。 Stencil是Web组件的编译器,它还在组件内部生成虚拟DOM,以提高其UI性能。看看吧; - )

答案 4 :(得分:0)

除了IFrame和通过postMessage进行通信之外,集成不同Angular应用程序的唯一方法是“深度链接”它们并使用URL-Parameter交换信息。然后,所有Angular应用程序都位于自己的浏览器选项卡上。但是对于常见的服务和组件,您可能希望实现所有Angular应用程序使用的“共享内核”,因此您可能会陷入某个Angular版本范围。当您需要此共享内核时,建议使用NGModule方法。您可以在一个应用程序中混合Angular 2和Angular 5版本,因为它们是向后兼容的。在Angular团队引入重大变革之前,团队并没有迫切需要坚持使用相同的版本。尽管您的技术债务增长,但是当您没有更新时。 Angular / Javascript区域中技术更新的频率明显更高。

答案 5 :(得分:0)

除了Iframe之外,SPA框架目前还有一个可供选择的选项,您可以从此处获取示例代码

https://github.com/PlaceMe-SAS/single-spa-angular-cli-examples https://github.com/joeldenning/simple-single-spa-webpack-example

答案 6 :(得分:0)

似乎已经有一段时间可以满足您的需求了。看看Single-SPA项目HERE

这是您的微型SPA项目的包装SPA项目。