Front-end Microservices Architecture

Mykhailo Churilov
Lead Software Engineer
Preconditions

Application Scale

To-do App
Average Enterprise
Damn big app


Lead Developer
Middle Developer


Standalone App #1
Standalone splitting
Standalone App #1
Legacy Mono App
Redirect to external
Back-end
REST communication
JWT
Standalone splitting

Standalone splitting
- TypeScript
- Component structure
- Self generated docs
- UI library

Text
App #2

Requirements
- Divide Legacy system to multiple apps, to make possible split the Team
- Have consistent UI across all applications
- Make single authentication point to all applications, without code duplication




New Team
Shell keeper
App#1 Keeper
App#2 Keeper
App#3 Keeper
Research

Iframe
- Content Scroll
- Nesting level
- Bundle size


Downsides


StackOverflow

Polymer
Web Comonents
Polyfills



Theory

Shell
Header
Container
App #1
App #2
App #3
CSS, HTML
CSS, HTML
CSS, HTML
inners CustomElement depend on the route
/app1/root/route
changes route
Script Loader
Identity Service
defines
custom elements
UI lib
Header Component

Responsibilities:
- changes location url
Script Loader
Responsibilities:
Parses elements schema
Creates node for each item
Register custom DOM element for each node
const components = [{
name: 'vue',
scriptName: 'vue-bundle.min.js',
template: '<div id="app"></div>',
cssPath: null
}, {
name: 'angular',
scriptName: 'ng-bundle.min.js',
template: '<app-root id="app"></app-root>',
cssPath: null
}];
components.forEach((el) => {
const node = Object.create(HTMLElement.prototype);
node.attachedCallback = () => {
const remote = DEFAULT_PATH;
this.appendChild(
document.createRange()
.createContextualFragment(el.template)
);
$.getScript(remote + '/' + el.scriptName)
.done(() => {
window[el.name] = true;
});
};
document.registerElement(el.name + '-app', {
prototype: node
});
});
Container
1. Parses app name in the route
2. Inserts {{app_name}}-app to the DOM
Routing - single point of truth
/app1/products/12
/app2/products/12
/error_page
app1 loaded
app2 loaded
no app loaded
Apps communication
App #1
App #2
App #3
CSS, HTML
CSS, HTML
CSS, HTML
Wrapper
Shared Store
Real Battle


ROUTE: /angular/home

ROUTE: /vue/home


For what?


WTF?
App#1 Keeper
App#2 Keeper
App#3 Keeper
events leaks
CSS inject duplications
styles overriding
Resources Guard

Resource management service
Container Stage
Active app #cur
Store events for #cur
Release events for #last
OnAppActivated()
app #1
app #2
app #3
Resource management service
Micro-apps restrictions
Isolate own styles
Prevent app run on the different app in location
Keep tracking all listeners, so on Exit of app we can easily destroy them
Bootstrap application from JS code
Forget about document and window
Deployment
CDN for app #1
v_1
v_2
v_3
CDN for app #2
v_1
v_2
v_3
CDN for app #3
v_1
v_2
v_3
Shell
Script Loader
Server
{Config}
GET app#1 v_2
app_1_v_2
bundle
Testing
1. Unit Testing of micro-apps
2. E2E
3. Resources Guard
4. Visual testing
Q & A




@kobvel
Front-end Microservices Architecture
By Mikki Churilov
Front-end Microservices Architecture
Slides to public talk about building front-end microservices architecture for large enterprise apps.
- 951