how to embed an angular app into another app?
Asked Answered
V

3

39

My team develop an angular 5 application that has been in production for a while, but we've been tasked recently with making the app work in other 3 sites the company owns. One site is a SPA built with Angular6, other is also a SPA but uses Angular5, while the other is using some older libraries such as jQuery.

Management wanted us to integrate with the Angular5 SPA right away so we just exported the whole application as a module with child routes and let the other application do the bootstrap.

But I'm afraid the above approach will not work for the non-angular site. This also tight couple both applications since the 'host' app needs to know about all dependencies of our application which is not a trivial app (I'd say is pretty big) and install them, this caused problems when both applications needed different versions of the same dependency, no to mention that we will need to sync when upgrading dependencies or the framework itself. I don't think this approach will scale when embedding the app into more sites.

My first idea for a more general implementation was to upgrade our app to Angular 6 and create a web component with a custom element, but we need to support IE11 and Edge which do not support native encapsulation, so we would need to test our app in every site where it is used, to make sure they are not breaking our styles, also I don't know whether a web component can manage child routes or not.

Other idea is to use an iframe but my problem here is the iframe resizing to adapt to the content and how to add child routes in the 'host' app from the 'resident' app inside the iframe.

Is there a better way to achieve what we need to do?

The ideal solution should allow our application to be used in multiple sites (each one providing specific configuration) without us having to know about the site using our app.

Thanks for your help.

Vengeance answered 2/10, 2018 at 7:59 Comment(2)
Does the app needs to be on same url? Does it need same style as host app? Is this authenticated app? Does it support SSO?Skiver
Yes, ideally the app should be in the same url but we need to control a portion of it. Eg. This is controlled by the main app -> companysite.com/myapp our app should control a child route: companysite.com/myapp/this/portion/is/ours The app is authenticated in one site but authentication is optional in the others, anonymous users are ok. We don't control the authentication in any site, and the authentication works differently on each site like one site it could be a cookie while in other it is an Authorization : Bearer tokenVengeance
J
46

UPDATE 2020

You can also use the new Webpack 5 Module federation.

following examples show how to use module federation with Angular and other technologies.

Original answer

I've been very busy with the topic lately, because many have the same problem again and again (me, of course). Nowadays, you often hear the concept of micro-frontends. The concept is about designing the frontend to be extensible and scalable. Especially in the time when many companies have both Angular and React and Vue developers. The following approaches came out of my research:

Links :

You can create your new app and have a hyperlink from your legacy app. (You must have a page reload when you switch beetween the both apps.)

Iframes :

a Software architect builded a meta router to deal with iframes and single page application:
Take a look at this:

Metaframeworks:

Metaframeworks allow you to have a communication beetween differents apps builded using differents frameworks:
here some example of metaframeworks for microfrontend purposes.

Web Components i.e Angular elements:

In order to deal with npm packages you can use as the other answerer mentioned the concept of Angular elements. You have to create a shell app and another independently apps that will be registred as elements in your shell app. Take a look at this example.: Building micro frontends — angular elements

Mosaiq: Layout service

The online shop Zalando faced to the same problem and created a framework in order to deal with the problem:

Espacially the part Tailor.js, an open source system for the assembling the components on-demand on a backend layer written in Go.

PS. Tailor was inspired by BigPipe: Pipelining web pages for high performance from Facebook.

Plugin Architecture

A plugin architecture is an architecture that will call external code at certain points without knowing all the details of that code in advance.

This Stackoverflow question explain more about it in case of single page application:

Angular libraries

I Think a right way is to have in a app the same framework and the same version of this framework (e.g Angular 7). I will prefer to take a time a do a upgrade to a typescript version of angular. I hope the answer can be usefull for others.

Other Stackoverflow related Q & A:

Vue.JS - micro frontend approach
Micro frontend architecture advice

Micro frontends examples

List of ressources about micro frontends

https://github.com/billyjov/microfrontend-resources

Jawbone answered 9/10, 2018 at 10:44 Comment(0)
D
14

I think the solution of your problem resides in Angular Elements. It is pretty cool and provided by angular team.

Angular Elements lets you package your Angular components as custom web elements, which are part of the web components set of web platform APIs. Web components are technologies to help create reusable, encapsulated elements. Right now, that includes the shadow DOM, HTML templates, HTML imports, and custom elements. The custom elements technology powers Angular Elements.

Here are some reference links from which you can learn more about Angular Elements.

https://angular.io/guide/elements

https://www.telerik.com/blogs/getting-started-with-angular-elements

Thanks!

Dubious answered 8/10, 2018 at 7:29 Comment(4)
Only Chrome, Safari and Opera supports it natively. Details: angular.io/guide/elements#browser-support-for-custom-elementsDurative
Yeah, I've seen the angular elements thing, but it does not work natively in IE11 or Edge. This is an issue because non-native encapsulation allow styles to filter from the parent app, also, what about routing?Vengeance
Yeah that's true @JorgeRiv, But they are constantly improving it day by day. So, there are chances of lot of functionalities to be added! May be the routing also.Dubious
As per doc link, angular now lists as 'Edge (Chromium-based)' as natively supported browser.Abort
G
0

I believe the Angular 6 Elements is going to be your only option for the non-angular apps. That is the only method that I am aware of that allows components to be executed outside of angular.

In order to maintain your style encapsulation, you can use the css prefix:

:host

in your component's .css or .scss files.

If you can get rid of the non-angular requirement, I would recommend the Angular CDK PortalHost and DomPortalHost.

Gruelling answered 6/10, 2018 at 2:38 Comment(2)
Yes this will avoid styles to leak from inside the element to the outside but it does not prevent styles from outside to leak into the component, at least not with non-native encapsulation and IE11 and Edge do not support native encapsulation.Vengeance
and how to deal with routing ??Lorentz

© 2022 - 2024 — McMap. All rights reserved.