Slide 1

Slide 1 text

MICROFRONTENDS WebMontag Kassel, 3. Februar 2020

Slide 2

Slide 2 text

AGENDA ● Microfrontends ● Single SPA ● Learnings

Slide 3

Slide 3 text

MICROFRONTENDS

Slide 4

Slide 4 text

BACK IN TIME Application “The monolith” Frontend SPA “Rise of the SPAs” Backend API Frontend SPA “Microservices everywhere” Service A API Service C API Service B API Backend for Frontend 2000 2011 2015

Slide 5

Slide 5 text

MICROFRONTENDS Service A SPA “Verticals” Service A API Service C API Service B API Service B SPA Service C SPA

Slide 6

Slide 6 text

Service B Frontend Service C /service-b INTEGRATION “Separate Apps” Service A Frontend Service B /service-a Service C Frontend /service-c

Slide 7

Slide 7 text

Service B Frontend /service-b INTEGRATION “Partials” Service A Frontend /service-a Service C Frontend /service-c Template Service B Frontend

Slide 8

Slide 8 text

DUDE, I’M DOING SPA!

Slide 9

Slide 9 text

SINGLE SPA

Slide 10

Slide 10 text

single-spa is a top level router. When a route is active, it downloads and executes the code for that route. index.js /service-a Service A Frontend /service-a https://single-spa.js.org

Slide 11

Slide 11 text

{ "imports": { "service-a": "http://localhost:3001/index.js", "single-spa": "https://cdn.jsdelivr.net/npm/single-spa@4.4.1/lib/system/single-spa.min.js" } } IMPORT MAPS

Slide 12

Slide 12 text

System.import('single-spa').then(function (singleSpa) { singleSpa.registerApplication( 'service-a',//applicationName () => System.import('service-a'), //applicationOrLoadingFn location => location.pathname.startsWith('/service-a') //activityFn ); singleSpa.start(); })

Slide 13

Slide 13 text

TARGETED FRONTEND LAYOUT Navigation bar Footer Menu Service-A

Slide 14

Slide 14 text

Slide 15

Slide 15 text

import React from ‘react’; import ReactDOM from ‘react-dom’; import App from ‘./App.js’; import singleSpaReact from ‘single-spa-react’; const reactLifecycles = singleSpaReact({ React, ReactDOM, App, domElementGetter: () => { let main = document.getElementById(‘main’); let serviceA = document.getElementById(‘service-a’); if(!serviceA} { serviceA = document.createElement(‘div’); serviceA.id = ‘service-a’; main.appendChild(serviceA); } return serviceA; } ) // export reactLifecycles.bootstrap, mount, unmount ANY SERVICE

Slide 16

Slide 16 text

ADAPTERS

Slide 17

Slide 17 text

LEARNINGS ● Every building block (e.g. navbar, footer, menu) should be treated as service ● Everything (JavaScript, CSS, HTML) has to be contained in the entry file ○ Some optimizations fall short (e.g. chunking) ○ Create React App is PITA in this case ● Images should be stored in a CDN, or use Webpacks base64-inline-loader ● Put as much dependencies into root import map as possible (e.g. React, Axios, lodash, momentjs, ...) ○ … and make use of Webpack externals

Slide 18

Slide 18 text

RESOURCES ● https://single-spa.js.org/ ● https://single-spa.js.org/docs/getting-started-overview/ ● https://single-spa.js.org/docs/api ● https://single-spa.js.org/docs/ecosystem

Slide 19

Slide 19 text

THANK YOU! eMail: w.biller@betterspace360.com Twitter: @wbiller