The Microfrontend Revolution Module Federation with Angular

The Microfrontend Revolution Module Federation with Angular

15934fa2aa7b2ce21f091e9b7cffa856?s=128

Manfred Steyer

May 25, 2020
Tweet

Transcript

  1. 11.

    @ManfredSteyer About me… Manfred Steyer, ANGULARarchitects.io (Remote) Angular Workshops and

    Consulting Google Developer Expert for Angular Trusted Collaborator in the Angular Team Manfred Steyer
  2. 18.

    @ManfredSteyer Module Federation Solves Some of Them! UI Composition UI

    Consistency Bundle Size/ Sharing Dependencies Version Conflicts between Microfrontends …
  3. 22.

    @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!
  4. 23.

    @ManfredSteyer Webpack 5 Module Federation Shell (Host) Microfrontend (Remote) //

    Maps Urls in // webpack config remotes: { mfe1: "mfe1" } // Expose files in // webpack config exposes: { Cmp: './my.cmp.ts' } import('mfe1/Cmp')
  5. 24.

    @ManfredSteyer How to Get the Microfrontend's URL? Shell (Host) Microfrontend

    (Remote) RemoteEntrypoint.js <script src="…"></script>
  6. 25.

    @ManfredSteyer How to Share Libs? Shell (Host) Microfrontend (Remote) shared:

    [ "@angular/core", "…" ] shared: [ "@angular/core", "…" ]
  7. 26.

    @ManfredSteyer Conflicting Shared Libs Option A: Reuse it anyway Option

    B: Load own Both might be bad Prevent organizationally (e. g. conventions, contracts, monorepos) Integration-Testing
  8. 31.

    @ManfredSteyer Challenge • Create a proper snake strategy • Publish

    it as a Module Federation Remote • Award Ceremony: ngCopenhagen Online Meetup • June 23th, 2020 • https://www.meetup.com/de-DE/ngCopenhagen/ • All Details • https://github.com/manfredsteyer/snake
  9. 33.

    @ManfredSteyer Well … Webpack 5 is currently beta Shown examples:

    PoC w/ custom webpack conf + patched CLI lib CLI: Not before version 11 (fall 2020) Squeeze federation config into CLI's webpack config Custom Builder (e. g. ngx-build-plus)
  10. 36.

    @ManfredSteyer Request Product Specify Order Approve Order Send Order Budget

    Hierarchy Employee IT-Expert Manager Buying Agent Product
  11. 37.

    @ManfredSteyer "Right" Domain Size Should mirror a real-world domain Large

    enough: Most use cases don't overlap domains Small enough: One team per domain
  12. 38.

    @ManfredSteyer Domain Driven Design gives a lot of advice! Also

    see blog at: http://angulararchitects.io
  13. 40.

    @ManfredSteyer Catalog Approval Shared Feature Feature Feature Feature Feature …

    … … … … … … … … @ManfredSteyer Catalog App Approval App Option 1: One Monorepo w/ several Domains
  14. 41.

    @ManfredSteyer Consequences Easy to share code Decoupling b/w domains: Conventions

    or Tools (Linting) Easy to enforce one version policy Different technologies: possible
  15. 42.

    @ManfredSteyer Catalog Approval Shared Feature Feature Feature Feature Feature …

    … … … … … … … … @ManfredSteyer Catalog App Approval App Option 2: One Repo per Domains Publish shared libs seperately via npm
  16. 43.

    @ManfredSteyer Consequences Enforces decoupling b/w domains Allows different versions (good

    or bad?) Allows different technologies Needs lots of automation Sharing Code via npm and versioning might be a pain
  17. 44.

    @ManfredSteyer Recommentation, if you are not sure Start with a

    monorepo Enforce decoupling via linting Reconsider splitting into several repos later
  18. 48.
  19. 49.

    @ManfredSteyer Very Simple Message Bus @Injectable({ providedIn: 'root' }) export

    class MessageBus { events$ = new ReplaySubject<DomainEvent>(1); }
  20. 52.

    @ManfredSteyer Well … Don't directly share state b/w sub-domains (coupling!)

    You might use Redux for eventing (like a Message Bus)
  21. 54.

    @ManfredSteyer Sharing Widgets is a Trade-Off too Decoupled Sub-Domains Shared

    Widgets Prevent duplicate code (DRY) Separate Ways
  22. 55.

    @ManfredSteyer Recommentation Technical Widgets (e. g. Design System): Sharing ok

    Use Case-specific widgets: Try to avoid (coupling!)
  23. 62.

    @ManfredSteyer Recommentation Try to stick with one technology (e. g.

    Angular) --> Share framework-specific components Works in the short and mid run Eventually, when needed, export them as web components (e. g. w/ Angular Elements)
  24. 64.

    @ManfredSteyer Possibilities HTTP Only Cookie: Tunnel through one origin (+XSRF

    Token) Token via Header: Different origins (consider OAuth2/OIDC) • Share token via message bus or session storage
  25. 67.

    @ManfredSteyer Backend for Frontend (BFF) BFF µFrontend BFF µFrontend BFF

    µFrontend µServices µServices µServices µServices
  26. 71.

    @ManfredSteyer Approaches Dashboard loads widgets from each sub-domain • Flexibility

    • Needs stable contracts • Agreements on common look and feel • Lots HTTP Calls Dashboard as a own sub-domain • Pros and Cons are inversed
  27. 72.

    @ManfredSteyer Backend for Frontend (BFF) Dashboard µBFF Dashboard µFrontend BFF

    µFrontend BFF µFrontend µServices µServices µServices µServices Messaging
  28. 74.

    @ManfredSteyer Conclusion Main Purpose of µFrontends: Scaling Teams Decoupling Federation:

    Import From Other App Sharing Libs Take Care of Conflicts Know your Architecture Goals
  29. 75.

    @ManfredSteyer Be like Bonnie and think first! Evaluate whether you

    need µFrontends No: Majestic Monolith Yes: Consider Module Federation