我正在研究如何将巨大的单页整体分割成微前端架构 .
这个想法:
-
该页面由几个可自动运行的组件组成
-
每个组件由一个开发团队管理
-
每个团队都可以更改,更新和部署他们的组件,而不会破坏其他团队的组件
-
每个团队选择自己的工具堆栈
原因
要有效地开发大型应用程序,您需要让很多人参与其中 . 但是,每个应用程序/团队的开发人员数量不能很好地扩展 . 然而,独立团队并行开发多个独立应用程序可以任意缩放
考虑到这一点,团队必须选择自己的工具堆栈,尤其是执行第三方库的独立版本升级(如angular,react,jquery) . 如果不是这种情况,框架更新需要与每个组件兼容,然后才能将其部署到 生产环境 环境中 .
这对Angular有用吗?
虽然需要进行独立的版本升级,但将团队限制在一些支持的框架(Angular,React,Vue,Polymer ......)是合理的,现在我尝试构建一个纯粹由Angular-Apps组成的演示 .
然而,即使Angular 5被认为是支持大型多模块应用程序的平台框架,但在同一浏览器窗口中运行几个独立的角度应用程序几乎是不可能的 .
我设法通过利用HTML-Imports在单个webapp上引导几个Angular-Apps(不同版本,每个版本都在自己的服务器上托管) . 但是,有几个 global
依赖项需要在应用程序之间共享
-
zone.js只能启动一次
-
路由需要更改网址
-
浏览器 - 像cookies,sessionstorage等...
网上有几篇关于如何引导多个角度模块的文章,但它们都引用同一个核心应用程序中的多个模块,这反过来意味着它们都在相同的框架版本上运行,并且更新意味着你必须重建和部署整个巨石 .
Is there any solution other than "iframes" to get multiple Angular (5) Apps running on the same Page?
6 回答
Yes you can.
However 在编写Web组件时,您真的不想陷入框架,因为Web组件的重点可能在任何地方都可以重用 .
我与您分享您的愿景,对于软件的质量以及开发人员在实施时处理重点功能而非大型应用程序的效率肯定更好 .
Finally ,你现在正在寻找的不是Angular,而是 StencilJS . Stencil是Web组件的编译器,它还在组件内部生成虚拟DOM,以提高其UI性能 . 看看这个 ;-)
看一下Angular Elements(自定义元素) . https://moduscreate.com/blog/angular-elements-ngcomponents-everywhere/
新的Ionic版本(4)完全基于它,可以在每个版本的Angular和每个JS框架上使用 .
为此,他们创建了https://stenciljs.com/,它将帮助您创建自定义元素 .
但是如果所有团队都在使用Angular,那么每个团队都可以使用ngm创建一个库 .
除了IFrame和通过postMessage进行通信之外,集成不同Angular应用程序的唯一方法是“深度链接”它们并使用URL-Parameter交换信息 . 然后,所有Angular应用程序都位于自己的浏览器选项卡上 . 但是对于常见服务和组件,您可能希望实现所有Angular应用程序使用的“共享内核”,因此您可能会陷入某个Angular版本范围 . 当您需要此共享内核时,建议使用NGModule方法 . 您可以在一个应用程序中混合Angular 2和Angular 5版本,因为它们是向后兼容的 . 在Angular团队引入重大变化之前,团队并没有迫切需要坚持使用相同的版本 . 尽管您的技术债务增长,但是当您没有更新时 . Angular / Javascript区域中技术更新的频率明显更高 .
而不是完全建议反对这个想法主要是由于单独的堆栈要求,我将列出权衡并提供一些限制,这将使这成为可能 .
我们都知道这是在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和其他资源进行最佳使用和处置 . 例如如果一个团队开始创建订阅并且不删除它们会怎么样?使用一些静态代码分析可能很有用,但此时您不会使用此源代码 - 除非他们也发布了源代码 .
这是一个完整的交易破坏者,除非你的意思是“工具堆”,如IDE和一些“devDependencies”等开发人员工具 . 虽然每个团队的“devDependencies”的某些部分必须具有相同的角度开发工具包的确切版本,例如编译器等 .
至少每个团队必须使用相同的Angular,RxJS等 .
最重要的是,应该注意每个团队都不会引导任何组件 - 只有主项目将有一个引导模块,并将引导根组件 . 这有助于解答您的_201448问题
如果你认识到这些限制并提供治理,我建议你去做 .
我们问自己同样的问题 . 不幸的是,似乎问题的答案
Is there any solution other than "iframes" to get multiple Angular (5) Apps running on the same Page (edit: where each Angular app can use a different Angular version)?
目前是
No, unfortunately not, as long as you want to use Angular‘s change detection (which uses zone.js).
由于zone.js Angular污染了全局范围 . 更糟糕的是,zone.js修补了大量的浏览器API(https://github.com/angular/zone.js/blob/master/STANDARD-APIS.md)以检测区域何时完成 .
如果框架不接触全局范围,则只能在一个页面中使用不同版本的框架而没有副作用(这似乎适用于React和Vue) . 然后,您可以通过Webpack将不同的框架版本与每个应用程序捆绑在一起(具有独立的范围和每个应用程序包大小增加的缺点) .
因此,如果您想使用Angular构建一个网页,其中不同的应用程序/模块应集成在一个页面上,目前唯一可行的解决方案是创建一个部署整体(例如,通过CI在一个Angular应用程序中捆绑来自不同团队的不同模块) / CD系统正如bhantol在他的回答中所解释的那样) .
似乎Angular团队也意识到了这个问题,他们可能会通过以下主要版本来解决它 . 请参阅robwormwald关于Angular Elements路线图的以下Github问题的答案:https://github.com/angular/angular/issues/20891
希望在下一个主要版本Angular 6在3月底发布时,Angular团队会就该主题提供更多信息 .
除了iframe之外,目前还有一个选项是SPA框架,您可以从这里获取示例代码
https://github.com/PlaceMe-SAS/single-spa-angular-cli-examples https://github.com/joeldenning/simple-single-spa-webpack-example