Angular, React, Vue.Js and Co. peacefully united thanks to Micro Apps and Web Components



Source Code

In my article Micro Apps With Web Components Using Angular Elements I'm showing how to leverage Angular Elements and Web Components to implement a modern Micro Apps architecture. It shows a shell that loads individual Micro Apps that can be developed as well as deployed separately. Those Micro Apps are provided as Web Components and loaded dynamically at runtime.

In this article I'm going one step further: I'm using different technologies for different micro apps.

Of course, you don't do something like this just for fun. It's rather necessary if your application evolves for a long time like one decade or more and if you have several UI teams. In this case, each team can go with the "best" technology for their part and you have not to stick with your original technology decision for ten years or longer.

Case Study

To show how to mix and match technologies, I'm using an extend version of the case study from my last post:

Using several technologies in one app

Here, you see a shell application with an Angular-based Micro App containing a Vue-based and a VanillaJS-based widget.

You can also mix and match technologies at macro-level for providing different micro apps:

Mixing technologies at macro level

Besides this, each Micro App can also run standalone:

Micro Apps in standalone mode

This is important because it allows for separate development, testing and deployment or to put it in another way: You are minimizing dependencies between different UI teams.

Wrapping a Micro App in a Web Component

For wrapping the Angular parts of my example in Web Components, I'm using Angular Elements. Further information about this can be found in my article here.

For the Vue.JS part, I'm directly using the native Custom Elements API. As an alternative, you could also use the build-in option for providing Web Components which is available since version 3. However, while it seems to be a good fit for widgets, I felt I needed more flexibility for wrapping a whole micro app which also uses the router or other libraries.

The next listing shows how to use the Custom Elements API for wrapping the Micro App:

import Vue from 'vue' import Booking from '../components/Booking.vue' import initRouter from '../initRouter.js'; import store from '../SimpleStore.js'; export default class FlightBooking extends HTMLElement { get appState() { return this._appState; } set appState(value) { this._appState = value; this.vue.$data.appState = value; } static get observedAttributes() { return ['app-state']; } attributeChangedCallback(name, oldValue, newValue) { this.appState = JSON.parse(newValue); } constructor() { super(); this.attachShadow({ mode: 'open' }); this.render(); } render() { const cssBase = require('!to-string-loader!css-loader!../assets/css/bootstrap.min.css'); const cssTheme = require('!to-string-loader!css-loader!../assets/css/paper-dashboard.css') this.shadowRoot.innerHTML = ` <style>${cssBase}</style> <style>${cssTheme}</style> <div id="component"></div> `; const router = initRouter(); const handleMessageEvent = (msg) => { this.dispatchEvent(new CustomEvent('message', { detail: msg })); } this.vue = new Vue({ router, data: { store, appState: this.appState }, render(r) { return r(Booking, { props: { appState: this.appState }, on: { message: handleMessageEvent } }); } }); const comp = this.shadowRoot.getElementById('component'); this.vue.$mount(comp); } }

The Web Component is just a subclass of HtmlElement. For the communication with the shell, all my Micro Apps come with an appState property and a message event. For instance, the appState contains the passenger and flight in question and the message event informs the system when a flight has been booked.

I'm also syncing the app-state attribute with the appState property. Every time the appState changes, I'm passing it to the current Vue object.

By means of attachShadow I'm using Shadow DOM which isolates the component's layout from the rest of the application. Simply spoken, this prevents a global CSS from destroying the component's layout.

The render method displays the component by leveraging Vue. To load some CSS instructions just for the component, it creates an own style tag. The CSS itself is loaded using webpack's to-string-loader and css-loader. They have to be npm-installed separately.

The Vue object gets a configured router, a data object with values for the component (e. g. the appState) and a render method.

The latter one is a bit confusing. If you would rewrite it using a html element with data binding expressions it would look like this:

<booking :app-state="appState" @message="handleMessageEvent"></booking>

For using such a template, we'd need the Vue template compiler at runtime.

However, to get the best performance, it's a best practice to precompile Vue-templates. Hence, we don't need not to put the Vue compiler into our bundles.

While the Vue CLI automatically precompiles all template in vue files we have to provide this render function in our wrapping Web Component instead of the template to get rid of the compiler at runtime.

Registering Web Components

To register this web component alongside another one wrapping the basked shown above, we just call customElements.define in the application's entry point which is normally called main.js:

import Vue from 'vue' import FlightBookingCE from './custom-elements/FlightBookingCE.js' import FlightBasketCE from './custom-elements/FlightBasketCE.js' import VueRouter from 'vue-router' Vue.use(VueRouter); customElements.define('flight-booking', FlightBookingCE); customElements.define('flight-basket', FlightBasketCE);

We can also use this entry point to register plugins like the router.

To get the bundles, just call the VUE.js CLI: vue-cli-service build.

This command gives us two bundles we need to load together. To load them, we can dynamically create script tags and tags for the web components as shown here.

Summary

Micro Apps and Web Components allow for mixing different technologies. This can be important for applications developed over a long time and/or by different UI teams. You can use the "best" technology for each part of the application and you don't need to stick with your technology decision forever.

[1] https://www.softwarearchitekt.at/post/2018/05/04/microservice-clients-with-web-components-using-angular-elements-dreams-of-the-near-future.aspx

 

 
Hier können Sie eine Anfrage für eine unverbindliche Schulung ode Beratung bzw. einen Workshop erstellen.
 
Unverbindliche Anfrage
 
 

Schulungen

Angular Schulung: Strukturierte Einführung

Lernen Sie in dieser interaktiven Schulung anhand einer Beispielanwendung den Einsatz von Angular für Ihre erfolgreichen Projekte kennen. Sie durchdringen die Hintergründe und bauen von der ersten Minute an auf Best Practices auf.

Details

Advanced Angular Schulung: Enterprise-Anwendungen und Architektur

In dieser Schulung erfahren Sie alles für die Entwicklung großer Anwendungen mit Angular: Mono-Repos, Micro-Apps, State Management, Performance und mehr

Details

Migration von AngularJS 1.x auf Angular (2+)

Seit der Ankündigung von Angular (2+) fragen sich Entwicklungs-Teams, welche Migrationspfade für AngularJS-1.x-Anwendungen vorliegen werden. Das im Lieferumfang von Angular enthaltene ngUpgrade bietet eine Antwort darauf. Es erlaubt einen Parallelbetrieb von AngularJS 1.x und Angular (2+) und stellt somit die Grundlage für eine schrittweise Migration dar.

Details

Progressive Web-Apps mit Angular

Progressive Web Apps bieten den Komfort nativer Anwendungen, indem sie auf moderne Browser APIs, wie Service Worker, setzen. Sie sind installierbar sowie offlinefähig und nutzen Hintergrundprozesse für Datensynchronisation und Push-Notifications. Diese Schulung zeigt anhand eines durchgehenden Beispiels was sich genau hinter diesem neuen Konzept verbirgt, wie solche Anwendungen mit Angular entwickelt werden und wie Sie in Ihren Projekten von den dahinterstehenden Ideen profitieren.

Details

Reaktive Architekturen mit Angular und Redux

Dieses interaktive Seminar vermittelt, wie Sie reaktive Anwendungen mit Angular entwickeln können.

Details

TypeScript

TypeScript gibt Ihnen alle Möglichkeiten der neuen JavaScript-Standards und zusätzlich ein statisches Typsystem, das dabei hilft, Fehler möglichst früh zu erkennen. Außerdem ist TypeScript die Grundlage für Angular. In diesem interaktiven Seminar lernen Sie diese mächtige Sprache anhand einer Fallstudie kennen.

Details

Weitere Schulungen ...