Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Microfrontends

W. Biller
February 03, 2020

 Microfrontends

W. Biller

February 03, 2020
Tweet

More Decks by W. Biller

Other Decks in Programming

Transcript

  1. 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
  2. MICROFRONTENDS Service A SPA “Verticals” Service A API Service C

    API Service B API Service B SPA Service C SPA
  3. Service B Frontend Service C /service-b INTEGRATION “Separate Apps” Service

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

    Service C Frontend /service-c Template Service B Frontend
  5. 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
  6. <!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
  7. <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
  8. <body> <!-- config --> <header> <div id=”navbar”></div> <div id=”menu”></div> </header>

    <div id=”main”></div> <div id=”footer”></div> </body> </html> LAYOUT
  9. 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
  10. 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