Share
Embed
Transcript
19 slides
-
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 -
MICROFRONTENDS Service A SPA “Verticals” Service A API Service C
API Service B API Service B SPA Service C SPA -
Service B Frontend Service C /service-b INTEGRATION “Separate Apps” Service
A Frontend Service B /service-a Service C Frontend /service-c -
Service B Frontend /service-b INTEGRATION “Partials” Service A Frontend /service-a
Service C Frontend /service-c Template Service B Frontend -
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 -
<!DOCTYPE html> <html> <head> <script type="systemjs-importmap"> { "imports": { "service-a":
"http://localhost:3001/index.js", "single-spa": "https://cdn.jsdelivr.net/npm/[email protected]/lib/system/single-spa.min.js" } } </script> <link rel="preload" href="https://cdn.jsdelivr.net/npm/[email protected]/lib/system/single-spa.min.js" as="script" crossorigin="anonymous" /> <!-- systemjs --> </head> IMPORT MAPS -
<body> <script> 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(); }) </script> </body> </html> REGISTER APPS -
<body> <!-- config --> <header> <div id=”navbar”></div> <div id=”menu”></div> </header>
<div id=”main”></div> <div id=”footer”></div> </body> </html> LAYOUT -
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 -
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