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

Angular Architecture: Monorepos and Micro Frontends

Angular Architecture: Monorepos and Micro Frontends

Manfred Steyer

October 17, 2023
Tweet

More Decks by Manfred Steyer

Other Decks in Programming

Transcript

  1. @BASTAcon & @ManfredSteyer

    View full-size slide

  2. @ManfredSteyer
    Typical Module Structure
    Page ▪ 3
    AppModule



    SharedModule
    Root Module Feature Modules Shared Modules
    SharedModule

    View full-size slide

  3. @ManfredSteyer
    Contents
    • Monorepos
    • Strategic Design and DDD
    • Nx & Incremental Compilation
    • Microfrontends

    View full-size slide

  4. @ManfredSteyer
    Manfred Steyer

    View full-size slide

  5. @ManfredSteyer
    Monorepos

    View full-size slide

  6. @ManfredSteyer
    Monorepo
    Structure

    View full-size slide

  7. @ManfredSteyer
    Advantages
    Everyone uses the latest versions
    No version conflicts
    No burden with distributing libs

    View full-size slide

  8. @ManfredSteyer
    Two Flavors
    • Like Workspaces/Solutions in different IDEs
    Project Monorepo
    • E. g. used at Google or Facebook
    Company-wide Monorepo

    View full-size slide

  9. @ManfredSteyer
    Moving back and forth
    Npm Registry

    View full-size slide

  10. @ManfredSteyer
    Tooling & Generator
    https://nrwl.io/nx

    View full-size slide

  11. @ManfredSteyer
    Visualize
    Module
    Structure

    View full-size slide

  12. @ManfredSteyer
    Further Selected Features of Nx
    • Restricting access b/w apps and libs
    • Just recompile changed apps
    • Parallel compilation in the cloud
    • Integration of tooling: Cypress, Playwright, Storybook, …

    View full-size slide

  13. @ManfredSteyer
    Creating a Workspace
    npm install -g @angular/cli
    ng new workspace
    cd workspace
    ng generate app my-app
    ng generate lib my-lib
    ng serve --project my-app
    ng build --project my-app

    View full-size slide

  14. @ManfredSteyer
    Creating a Workspace
    npm install -g @angular/cli
    npm init nx-workspace workspace
    cd workspace
    ng generate app my-app
    ng generate lib my-lib
    ng serve --project my-app
    ng build --project my-app

    View full-size slide

  15. @ManfredSteyer
    DEMO

    View full-size slide

  16. @ManfredSteyer
    DDD
    in a nutshell

    View full-size slide

  17. @ManfredSteyer
    Methodology for
    bridging the gap b/w
    requirements and
    architecture/ design

    View full-size slide

  18. @ManfredSteyer

    View full-size slide

  19. @ManfredSteyer
    Domain Driven Design
    Strategic Design Tactical Design
    Decomposing a System
    Design Patterns
    & Practices

    View full-size slide

  20. @ManfredSteyer
    Domain Driven Design
    Strategic Design Tactical Design
    Decomposing a System
    Design Patterns
    & Practices

    View full-size slide

  21. @ManfredSteyer

    View full-size slide

  22. @ManfredSteyer
    Example
    Flight System

    View full-size slide

  23. @ManfredSteyer
    Booking Check-in
    Boarding
    Luggage
    Example
    Sub-Domains

    View full-size slide

  24. @ManfredSteyer
    Finding Sub-Domains
    Book
    Flight
    Check-in
    Passenger
    Check-in
    Luggage
    Board
    Plane
    Pickup
    Luggage
    Passenger
    Travel Agency Check-in Agent Boarding Agent

    View full-size slide

  25. @ManfredSteyer
    Booking Boarding
    Bounded Context
    Ubiquitous Language
    Flight
    Price
    Seats
    Passenger
    Tickets
    Flight Ticket

    View full-size slide

  26. @ManfredSteyer
    Booking Luggage
    Boarding
    Check-in
    Context Map

    View full-size slide

  27. @ManfredSteyer
    Booking Boarding Shared
    Feature Feature Feature Feature Feature
    UI UI UI UI UI UI UI UI UI
    Domain Domain Domain Domain Domain Domain
    Util Util Util Util Util Util
    Enterprise Monorepo Patterns, Nrwl 2018: https://tinyurl.com/y2jjxld7
    @ManfredSteyer
    Shared Kernel (if really needed) & other libs
    Smart
    Comp.
    Dumb Comp.

    View full-size slide

  28. @ManfredSteyer
    DEMO

    View full-size slide

  29. @ManfredSteyer

    View full-size slide

  30. @ManfredSteyer
    Finegrained Libraries
    • Units for dep graph
    • Unit of recompilation*
    • Unit of retesting
    • Access restrictions
    • Information Hiding
    • Easy: Just ng g lib …

    View full-size slide

  31. @ManfredSteyer
    Restricting Access
    on a folder basis
    Rainer Hahnekamp,
    AngularArchitects
    @softarc/eslint-plugin-sheriff

    View full-size slide

  32. @ManfredSteyer
    Micro
    Frontends?
    Short outlook

    View full-size slide

  33. @ManfredSteyer
    Booking App Check-in App
    Boarding App
    Luggage App
    Microfrontends

    View full-size slide

  34. @ManfredSteyer
    Shopping Card
    App
    Payment
    App
    Recommender
    App
    Shipping
    App
    Microfrontends

    View full-size slide

  35. @ManfredSteyer

    View full-size slide

  36. @ManfredSteyer
    Booking Boarding Shared
    Feature Feature Feature Feature Feature
    … … … … … … … … …
    @ManfredSteyer
    Flight App
    Deployment Monolith

    View full-size slide

  37. @ManfredSteyer
    Booking Boarding Shared
    Feature Feature Feature Feature Feature
    … … … … … … … … …
    Booking App Boarding App
    Microfrontends

    View full-size slide

  38. @ManfredSteyer
    Booking Boarding Shared
    Feature Feature Feature Feature Feature
    … … … … … … … … …
    Booking App Boarding App
    Option 1: One App per Domain
    Monorepo

    View full-size slide

  39. @ManfredSteyer
    Booking Boarding Shared
    Feature Feature Feature Feature Feature
    … … … … … … … … …
    Booking App Boarding App
    Option 2: One Monorepo per Domain
    Publish shared libs
    seperately via npm
    Repository n
    Repository 2
    Repository 1

    View full-size slide

  40. @ManfredSteyer
    Benefits
    Autonomous Teams
    Separate Development
    Separate Deployment
    Own architecture decisions
    Own technology descisions

    View full-size slide

  41. @ManfredSteyer
    Integration via
    Hyperlinks

    View full-size slide

  42. @ManfredSteyer
    UI Composition
    w/ Hyperlinks
    µApp
    SPA
    µApp
    SPA
    µApp
    SPA

    View full-size slide

  43. @ManfredSteyer

    View full-size slide

  44. @ManfredSteyer

    View full-size slide

  45. @ManfredSteyer

    View full-size slide

  46. @ManfredSteyer
    ✓ Simple
     Loosing State
     Load a new Application

    View full-size slide

  47. @ManfredSteyer

    View full-size slide

  48. @ManfredSteyer
    Web
    Components
    for Shared
    Widgets?

    View full-size slide

  49. @ManfredSteyer
    Integration via
    Shell

    View full-size slide

  50. @ManfredSteyer
    µService
    Providing a (SPA based) Shell
    µApp
    µApp
    µApp
    Shell

    View full-size slide

  51. @ManfredSteyer

    View full-size slide

  52. @ManfredSteyer
    Idea
    const Component = import('other-app/xyz')
    Does not work with
    webpack/ Angular CLI
    Even lazy parts must be
    known at compile time!

    View full-size slide

  53. @ManfredSteyer
    Webpack 5 Module Federation
    Shell (Host) Microfrontend (Remote)
    // Maps Urls in
    // webpack config
    remotes: {
    mfe1: "http://..."
    }
    // Expose files in
    // webpack config
    exposes: {
    Cmp: './my.cmp.ts'
    }
    import('mfe1/Cmp')

    View full-size slide

  54. @ManfredSteyer
    Dynamic Module Federation
    Shell (Host) Microfrontend (Remote)
    remotes: {
    }
    exposes: {
    Cmp: './my.cmp.ts'
    }
    loadRemoteModule({
    type: 'module',
    remoteEntry: 'http://…',
    exposedModule: './Cmp'
    })

    View full-size slide

  55. @ManfredSteyer
    How to Get the Microfrontend's URL?
    Shell (Host) Microfrontend (Remote)
    RemoteEntrypoint.js

    View full-size slide

  56. @ManfredSteyer
    How to Share Libs?
    Shell (Host) Microfrontend (Remote)
    shared: [
    "@angular/core", "…"
    ]
    shared: [
    "@angular/core", "…"
    ]

    View full-size slide

  57. @ManfredSteyer

    View full-size slide

  58. @ManfredSteyer
    Default Behavior
    Selecting the highest compatible version
    ^10.0 ^10.1

    View full-size slide

  59. @ManfredSteyer
    Default Behavior
    Conflict: No highest compatible version
    ^11.0 ^10.1

    View full-size slide

  60. @ManfredSteyer
    Configuring Singletons
    shared: {
    "my-lib": {
    singleton: true
    }
    }
    11.0 10.1

    View full-size slide

  61. @ManfredSteyer
    Configuring Singletons
    shared: {
    "my-lib": {
    singleton: true,
    strictVersion: true // Error instead of warning!
    }
    }
    11.0 10.1

    View full-size slide

  62. @ManfredSteyer
    Relaxing Version Requirements
    shared: {
    "my-lib": {
    requiredVersion: ">=1.0.1 <11.1.1"
    }
    }

    View full-size slide

  63. @ManfredSteyer

    View full-size slide

  64. @ManfredSteyer
    ?

    View full-size slide

  65. @ManfredSteyer
    Custom Builder

    View full-size slide

  66. @ManfredSteyer

    View full-size slide

  67. @ManfredSteyer
    1) ng add @angular-architects/module-federation
    2) Adjust generated configuration
    3) ng serve

    View full-size slide

  68. @ManfredSteyer
    1) npm i @angular-architects/module-federation -D
    2) ng g @angular-architects/module-federation:init
    3) Adjust generated configuration
    4) ng serve

    View full-size slide

  69. @ManfredSteyer

    View full-size slide

  70. @ManfredSteyer

    View full-size slide

  71. @ManfredSteyer
    Wrap them into Web Components
    Angular App
    (MFE)
    React App
    (MFE)

    View full-size slide

  72. @ManfredSteyer

    View full-size slide

  73. @ManfredSteyer
    await import('other-app/web-cmp');

    View full-size slide

  74. @ManfredSteyer
    await import('other-app/web-cmp');
    const rootElm = document.createElement('web-cmp')
    document.body.appendChild(rootElm);

    View full-size slide

  75. @ManfredSteyer
    await import('other-app/web-cmp');
    const rootElm = document.createElement('web-cmp')
    document.body.appendChild(rootElm);
    WrapperComponent

    View full-size slide

  76. @ManfredSteyer

    View full-size slide

  77. @ManfredSteyer
    https://red-ocean-0fe4c4610.azurestaticapps.net

    View full-size slide

  78. @ManfredSteyer
    Free eBook (5th Edition)
    ANGULARarchitects.io/book
    Module Federation & Nx

    View full-size slide

  79. @ManfredSteyer
    Choosing a Solution

    View full-size slide

  80. @ManfredSteyer
    Some General Advice
    Shared state,
    navigation b/w
    apps
    Hyperlinks
    Legacy Apps or
    *very very* strong
    isolation?
    iframes
    Separate
    Deployment/ mix
    Technologies?
    Load Bundles on
    Demand
    Monolith
    little
    much
    yes
    no
    yes
    no
    Module Federation

    View full-size slide

  81. @ManfredSteyer
    d
    Slides & Examples Remote Company Workshops
    and Consulting
    http://angulararchitects.io

    View full-size slide