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

Structure for Enterprise-Scale Angular Applications: Nx Monorepos, Micro Frontends, and Module Federation

Structure for Enterprise-Scale Angular Applications: Nx Monorepos, Micro Frontends, and Module Federation

Manfred Steyer
PRO

March 21, 2023
Tweet

More Decks by Manfred Steyer

Other Decks in Programming

Transcript

  1. @BASTAcon & @ManfredSteyer

    View Slide

  2. @ManfredSteyer
    Contents
    • (npm-)Packages
    • Nx Monorepos
    • Strategic Design and DDD
    • Microfrontends

    View Slide

  3. @ManfredSteyer
    Manfred Steyer

    View Slide

  4. @ManfredSteyer
    Monorepos

    View Slide

  5. @ManfredSteyer
    Monorepo
    Structure

    View Slide

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

    View Slide

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

    View Slide

  8. @ManfredSteyer
    Visualize
    Module
    Structure

    View Slide

  9. @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 Slide

  10. @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 Slide

  11. @ManfredSteyer
    DEMO

    View Slide

  12. @ManfredSteyer
    DDD
    in a nutshell

    View Slide

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

    View Slide

  14. @ManfredSteyer

    View Slide

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

    View Slide

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

    View Slide

  17. @ManfredSteyer

    View Slide

  18. @ManfredSteyer
    Example
    Flight System

    View Slide

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

    View Slide

  20. @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 Slide

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

    View Slide

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

    View Slide

  23. @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 Slide

  24. @ManfredSteyer
    DEMO

    View Slide

  25. @ManfredSteyer

    View Slide

  26. @ManfredSteyer
    Finegrained Libraries
    • Unit of recompilation*
    • Unit of retesting
    • Access restrictions
    • Information Hiding
    • Easy: Just ng g lib …
    • Replacement for NgModules?

    View Slide

  27. @ManfredSteyer
    Micro
    Frontends?
    Short outlook

    View Slide

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

    View Slide

  29. @ManfredSteyer

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  33. @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 Slide

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

    View Slide

  35. @ManfredSteyer
    Integration via
    Hyperlinks

    View Slide

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

    View Slide

  37. @ManfredSteyer

    View Slide

  38. @ManfredSteyer

    View Slide

  39. @ManfredSteyer
    Integration via
    Shell

    View Slide

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

    View Slide

  41. @ManfredSteyer

    View Slide

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

    View Slide

  43. @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 Slide

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

    View Slide

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

    View Slide

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

    View Slide

  47. @ManfredSteyer

    View Slide

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

    View Slide

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

    View Slide

  50. @ManfredSteyer
    Example
    • Shell: my-lib: ^10.0
    • MFE1: my-lib: ^10.1
    • MFE2: my-lib: ^9.0
    • MFE3: my-lib: ^9.1
    Result:
    • Shell and MFE1 share ^10.1
    • MFE2 and MFE3 share ^9.1

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  54. @ManfredSteyer

    View Slide

  55. @ManfredSteyer
    ?

    View Slide

  56. @ManfredSteyer
    Custom Builder

    View Slide

  57. @ManfredSteyer

    View Slide

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

    View Slide

  59. @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 Slide

  60. @ManfredSteyer

    View Slide

  61. @ManfredSteyer

    View Slide

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

    View Slide

  63. @ManfredSteyer

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  67. @ManfredSteyer

    View Slide

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

    View Slide

  69. @ManfredSteyer
    Challanges
    • Bundle Size
    • Multiple Routers
    • Bootstrapping Several Angular Instances
    • Share Platform-Object when same version is reused
    • Share ngZone

    View Slide

  70. @ManfredSteyer

    View Slide

  71. @ManfredSteyer
    Free eBook (5th Edition)
    ANGULARarchitects.io/book
    Module Federation, Nx, DDD
    12 chapters

    View Slide

  72. @ManfredSteyer
    Choosing a Solution

    View Slide

  73. @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 Slide

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

    View Slide