javascript 角度和微前端
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/47793065/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Angular and Micro-Frontends
提问by H W
I am doing some research on how to split a huge single-page-monolith into a micro-frontend architecture.
我正在研究如何将巨大的单页单体拆分为微前端架构。
The idea:
想法:
- the page consists of several components which would be running autonomously
- each component is managed by one dev-team
- each team can change, update and deploy their components without breaking components of other teams
- each team chooses its own toolstack
- 该页面由几个独立运行的组件组成
- 每个组件都由一个开发团队管理
- 每个团队都可以更改、更新和部署他们的组件,而不会破坏其他团队的组件
- 每个团队选择自己的工具栈
The reason
原因
To efficiently develop large applications you need to have many people working on it. However the number of developers per app/team does not scale well. Parallel development of multiple independent apps by independent teams however can be scaled arbitrarily
为了有效地开发大型应用程序,您需要有很多人来处理它。然而,每个应用程序/团队的开发人员数量并不能很好地扩展。由独立团队并行开发多个独立应用程序,但可以任意扩展
With this in mind it is imperative that teams can choose their own toolstack and especially perform independent version-upgrades of third party-libraries (like angular, react, jquery). If this was not the case a framework-update would need to be compatible with every single component before you could deploy it to production.
考虑到这一点,团队必须可以选择自己的工具堆栈,尤其是执行第三方库(如 angular、react、jquery)的独立版本升级。如果不是这种情况,框架更新将需要与每个组件兼容,然后才能将其部署到生产中。
Does this work with Angular?
这适用于 Angular 吗?
While independent version-upgrades are necessary, it would be reasonable to restrict the teams to a few supported frameworks (Angular, React, Vue, Polymer...) and for now I try to build a demo purely consisting of Angular-Apps.
虽然独立的版本升级是必要的,但将团队限制在几个受支持的框架(Angular、React、Vue、Polymer...)是合理的,现在我尝试构建一个纯粹由 Angular-Apps 组成的演示。
However even though Angular 5 is supposedly a platform-framework which supports huge multi-module apps, it seems to be almost impossible to have several independent angular-apps running in the same browser window.
然而,尽管 Angular 5 据说是一个支持庞大的多模块应用程序的平台框架,但在同一个浏览器窗口中运行多个独立的 Angular 应用程序似乎几乎是不可能的。
I managed to bootstrap several Angular-Apps (different versions, each hosted on its own server) on a single webapp by utilizing HTML-Imports. However there are several globaldependencies which need to be shared between apps
我设法通过使用 HTML 导入在单个 web 应用程序上引导多个 Angular 应用程序(不同版本,每个都托管在自己的服务器上)。但是有几个global依赖项需要在应用程序之间共享
- zone.js can only be started once
- routing requires url-changes
- Browser-stuff like cookies, sessionstorage, etc...
- zone.js 只能启动一次
- 路由需要更改 url
- 浏览器的东西,如 cookie、sessionstorage 等...
There are several articles in the net on how to bootstrap multiple angular-modules but they all refer to multiple modules in the same core-app, which in turn means they all are running on the same framework-version and an update means you have to rebuild and deploy the whole monolith.
网上有几篇关于如何引导多个角度模块的文章,但它们都指的是同一个核心应用程序中的多个模块,这反过来意味着它们都运行在相同的框架版本上,更新意味着你必须重建和部署整个单体。
Is there any solution other than "iframes" to get multiple Angular (5) Apps running on the same Page?
除了“ iframes”之外,还有其他解决方案可以让多个 Angular (5) 应用程序在同一页面上运行吗?
回答by bhantol
Instead of outright suggesting AGAINST this idea mainly due to separate stack requirements I will lay out the trade offs and provide some restrictions which will make this possible.
主要是由于单独的堆栈要求,而不是直接建议反对这个想法,我将进行权衡并提供一些限制,这将使这成为可能。
the page consists of several components which would be running autonomously
该页面由几个独立运行的组件组成
We all know this is offered out of box in Angular components with clear demarcation of inputs and output.
我们都知道这是在 Angular 组件中开箱即用的,具有明确的输入和输出界限。
Small CAVEAT: When/If you pass objects for @Inputand emit event objects with @Output()interacting components must agree on a defined interface upfront.
小警告:当/如果您为交互组件传递对象@Input并发出事件对象时,@Output()必须预先就定义的接口达成一致。
Workaround: Create another TypeScript project which just defines these artifacts. All other "component projects" would depend on a specific version of this.
解决方法:创建另一个仅定义这些工件的 TypeScript 项目。所有其他“组件项目”将取决于此的特定版本。
each component is managed by one dev-team
每个组件都由一个开发团队管理
Dev Teams can distribute the components just like other Angular projects in the opensource are doing. They can publish their artifacts to some npm repository. To develop attributable components I recommend you refer to Angular Material2which may be overwhelming or you may use something like ngx-library-builder(based on Angular Team Member filipesilva/angular-quickstart-lib ) that each component team uses.
开发团队可以像开源中的其他 Angular 项目一样分发组件。他们可以将他们的工件发布到某个 npm 存储库。要开发可归属的组件,我建议您参考Angular Material2,它可能会让人不知所措,或者您可以使用每个组件团队都使用的ngx-library-builder(基于Angular 团队成员 filipesilva/angular-quickstart-lib)之类的东西。
CAVEAT: Till this date angular team does not have a quick component library sharing project setup as evident in Angular CLI. But numerous developers have created some sort of library builders to fill the gap in Angular CLI.
警告:到目前为止,Angular 团队还没有像 Angular CLI 那样的快速组件库共享项目设置。但是许多开发人员已经创建了某种库构建器来填补 Angular CLI 的空白。
each team can change, update and deploy their components without breaking components of other teams
每个团队都可以更改、更新和部署他们的组件,而不会破坏其他团队的组件
Have your main project pull all the components and perform a periodic/change triggered build/deploy on some CI server. This is essentially producing AOT production builds with all the latest component releases. As an added bonus you can have some abstract e2e tests built to do some automated integration testing ensuring side effects of one component does not break other components.
让您的主项目拉取所有组件并在某些 CI 服务器上执行定期/更改触发的构建/部署。这实质上是使用所有最新的组件版本生成 AOT 生产版本。作为额外的好处,您可以构建一些抽象的 e2e 测试来执行一些自动化集成测试,以确保一个组件的副作用不会破坏其他组件。
CAVEAT: It will be difficult to govern how each team develops the components i.e. they are doing optimal usage and disposition of memory, CPU, and other resources. e.g. what if one team starts creating subscriptions and does not remove them. Using some static code analysis can be useful but you will not have this source code available at this time - unless they also publish their source code.
警告:很难控制每个团队如何开发组件,即他们正在优化内存、CPU 和其他资源的使用和配置。例如,如果一个团队开始创建订阅并且不删除它们会怎样。使用一些静态代码分析可能很有用,但此时您将无法获得此源代码 - 除非他们也发布了他们的源代码。
each team chooses its own toolstack
每个团队选择自己的工具栈
This is a complete deal breaker unless if you mean "toolstack" as in developer tools such as IDEs and some of the "devDependencies". Although certain parts of "devDependencies" of each team must have the same exact versions of angular dev kits such as compilers etc.
这是一个完整的交易破坏者,除非您的意思是“工具堆栈”,如 IDE 和一些“devDependencies”等开发人员工具。尽管每个团队的“devDependencies”的某些部分必须具有完全相同的 Angular 开发工具包版本,例如编译器等。
At the least each team must use same Angular, RxJS etc.
至少每个团队必须使用相同的 Angular、RxJS 等。
Most importantly care should be taken that each of the team does not bootstrap any components - only the main projects will have a bootstrap module and that will bootstrap the root component. This will help answer your zone.jsissue
最重要的是,应该注意团队中的每个人都不会引导任何组件——只有主项目才会有引导模块,这将引导根组件。这将有助于回答您的zone.js问题
Does this work with Angular?
这适用于 Angular 吗?
If you recognize the limitations and provide governance I suggest go for it.
如果您认识到局限性并提供治理,我建议您去尝试。
回答by Philip
We asked ourselves the same question. Unfortunately, it seems that the answer to the question
我们问自己同样的问题。不幸的是,似乎问题的答案
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)?
除了“iframes”之外,是否还有其他解决方案可以让多个 Angular (5) 应用程序在同一页面上运行(编辑:每个 Angular 应用程序可以使用不同的 Angular 版本)?
currently is
目前是
No, unfortunately not, as long as you want to use Angular‘s change detection (which uses zone.js).
不,不幸的是不是,只要您想使用 Angular 的更改检测(使用 zone.js)。
Due to zone.js Angular pollutes the global scope. Even worse zone.js patches an awful lot of browser APIs (https://github.com/angular/zone.js/blob/master/STANDARD-APIS.md) to detect when a zone is completed.
由于 zone.js Angular 污染了全局范围。更糟糕的是 zone.js 修补了大量浏览器 API ( https://github.com/angular/zone.js/blob/master/STANDARD-APIS.md) 以检测区域何时完成。
It's only possible to use different versions of a framework in one page without side effects if the framework does not touch global scope (this seems to be true for React und Vue). Then you can bundle different framework versions with each application via Webpack (with separated scope and the downside that the size of each application bundle increases).
如果框架不涉及全局范围,则只能在一个页面中使用不同版本的框架而不会产生副作用(这对于 React 和 Vue 来说似乎是正确的)。然后您可以通过 Webpack 将不同的框架版本与每个应用程序捆绑在一起(具有分离的范围和每个应用程序捆绑包的大小增加的缺点)。
So, if you want to build a web page with Angular where different applications/modules should be integrated on one page, the only feasible solution currently is to create a deployment monolith (e.g. bundle different modules from different teams in one Angular application by a CI/CD system as bhantol explained in his answer).
所以,如果你想用 Angular 构建一个网页,其中不同的应用程序/模块应该集成在一个页面上,目前唯一可行的解决方案是创建一个部署单体(例如,通过 CI 将来自不同团队的不同模块捆绑在一个 Angular 应用程序中/CD 系统如 bhantol 在他的回答中解释的那样)。
It seems that the Angular team is also aware of the problem and that they might tackle it with following major versions. See robwormwald's answer on the following Github issue regarding the Angular Elements roadmap: https://github.com/angular/angular/issues/20891
Angular 团队似乎也意识到了这个问题,他们可能会通过以下主要版本来解决这个问题。有关 Angular Elements 路线图的以下 Github 问题,请参阅 robwormwald 的回答:https: //github.com/angular/angular/issues/20891
Hopefully there will be more information by the Angular team on that topic when the next major version Angular 6 is release at the end of march.
希望 Angular 团队在 3 月底发布下一个主要版本 Angular 6 时会提供有关该主题的更多信息。
回答by Gilsdav
Take a look at Angular Elements (Custom Elements). https://moduscreate.com/blog/angular-elements-ngcomponents-everywhere/
看一看 Angular Elements(自定义元素)。https://moduscreate.com/blog/angular-elements-ngcomponents-everywhere/
The new Ionic version (4) is totally based on it to be able to be used on every version of Angular and on every JS frameworks.
新的 Ionic 版本 (4) 完全基于它,能够在每个版本的 Angular 和每个 JS 框架上使用。
For that, they created https://stenciljs.com/that will help you to create Custom Elements.
为此,他们创建了https://stenciljs.com/来帮助您创建自定义元素。
But if all teams are using Angular, each of them can create a library using ngm for exemple.
但是如果所有团队都在使用 Angular,他们每个人都可以使用 ngm 来创建一个库,例如。
回答by eddyP23
回答by Aji
Other than Iframe there is one more option is currently available is SPA framework, you can get the sample code from here
除了 Iframe 之外,目前还有一个可用的选项是 SPA 框架,您可以从这里获取示例代码
https://github.com/PlaceMe-SAS/single-spa-angular-cli-exampleshttps://github.com/joeldenning/simple-single-spa-webpack-example
https://github.com/PlaceMe-SAS/single-spa-angular-cli-examples https://github.com/joeldenning/simple-single-spa-webpack-example
回答by Guillaume Le Mière
Yes you can.
是的你可以。
Howeveryou don't really want to get stuck in a framework when you are writing web components, because the whole point of a web component is to be reused possibly anywhere.
然而,当您编写 Web 组件时,您真的不想陷入框架中,因为 Web 组件的全部意义在于可能在任何地方重用。
I share your vision, it's definitely better for the quality of the software as well as the productivity of developers to work on focused features rather than large apps when it comes to implementation.
我同意您的看法,在实施时,对于软件的质量以及开发人员的生产力来说,在重点功能而不是大型应用程序上工作肯定会更好。
Finally, what you are looking for right now is not Angular, but StencilJS. Stencil is a compiler for web components who also generate a virtual DOM inside your component to improve it's UI performances. Check it out ;-)
最后,你现在要找的不是 Angular,而是StencilJS。Stencil 是 Web 组件的编译器,它还会在您的组件内生成虚拟 DOM 以提高其 UI 性能。看看这个 ;-)
回答by Dirk Lammers
The only way to integrate different Angular Apps apart from IFrames and communication via postMessage is by "Deep-Linking" them and exchanging information using URL-Parameter. All Angular apps are then located on their own browser tab. But for common services and components you may want to implement a "Shared Kernel" used by all of your Angular apps, therefore your a stuck on a certain Angular version range. When you want this shared kernel the NGModule approach is the recommended way to go. You can mix Angular 2 and Angular 5 versions in one app because they are backward compatible. There ist no urgent need for the teams to stuck on the same version, until the Angular Team introduces breaking changes. Despite of that your technical debts grow, when you are not updating. The frequency for technical-updates is definitly higher in the Angular/Javascript area.
除了 IFrames 和通过 postMessage 通信之外,集成不同 Angular 应用程序的唯一方法是“深度链接”它们并使用 URL 参数交换信息。然后所有 Angular 应用程序都位于它们自己的浏览器选项卡上。但是对于通用服务和组件,您可能希望实现所有 Angular 应用程序都使用的“共享内核”,因此您会被困在某个 Angular 版本范围内。当你想要这个共享内核时,NGModule 方法是推荐的方法。您可以在一个应用程序中混合使用 Angular 2 和 Angular 5 版本,因为它们向后兼容。在 Angular 团队引入突破性更改之前,团队并不迫切需要坚持使用相同的版本。尽管如此,当您不更新时,您的技术债务会增加。

