Slide 1

Slide 1 text

@BASTAcon & @ManfredSteyer Structure For Your Huge Angular Solutions: Packages, Monorepos and Micro Frontends

Slide 2

Slide 2 text

@ManfredSteyer Typical Module Structure Page ▪ 2 AppModule … … … SharedModule Root Module Feature Modules Shared Modules SharedModule

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

@ManfredSteyer Manfred Steyer

Slide 5

Slide 5 text

@ManfredSteyer npm Packages

Slide 6

Slide 6 text

@ManfredSteyer Create Library with CLI >= 6 npm install -g @angular/cli ng new lib-project cd lib-project ng generate library logger-lib ng generate application playground-app ng serve --project playground-app ng build --project logger-lib

Slide 7

Slide 7 text

@ManfredSteyer Folder Structure

Slide 8

Slide 8 text

@ManfredSteyer Create Library with CLI >= 6 npm install -g @angular/cli ng new lib-project --create-application false cd lib-project ng generate library logger-lib ng generate application playground-app ng serve --project playground-app ng build --project logger-lib

Slide 9

Slide 9 text

@ManfredSteyer Publishing

Slide 10

Slide 10 text

@ManfredSteyer Publishing to npm Registry • Increment version in package.json • ng build --project logger-lib • npm publish --registry http://localhost:4873 • npm install --registry http://localhost:4873

Slide 11

Slide 11 text

@ManfredSteyer Alternatives for setting the Registry • Global: npm set registry http://localhost:4873 • Default: registry.npmjs.org • npm get registry • Project: .npmrc in project root

Slide 12

Slide 12 text

@ManfredSteyer npm Registries Nexus Artifactory Team Foundation Server Verdaccio npm i -g verdaccio verdaccio

Slide 13

Slide 13 text

@ManfredSteyer DEMO

Slide 14

Slide 14 text

@ManfredSteyer Advantages • Distribution • Versioning

Slide 15

Slide 15 text

@ManfredSteyer Disadvantages • Distribution • Versioning ;-)

Slide 16

Slide 16 text

@ManfredSteyer Disadvantages Distribution • Annoying within project • Prevents gritting further libs Versioning • Old versions • Conflicts • How to force devs to use latest version?

Slide 17

Slide 17 text

@ManfredSteyer Monorepos

Slide 18

Slide 18 text

@ManfredSteyer Monorepo Structure

Slide 19

Slide 19 text

@ManfredSteyer Advantages Everyone uses the latest versions No version conflicts No burden with distributing libs Creating new libs: Adding folder Experience: Successfully used at Google, Facebook, …

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

@ManfredSteyer Moving back and forth Npm Registry

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

@ManfredSteyer Visualize Module Structure

Slide 24

Slide 24 text

@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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

@ManfredSteyer DEMO

Slide 27

Slide 27 text

@ManfredSteyer LAB

Slide 28

Slide 28 text

@ManfredSteyer DDD in a nutshell

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

@ManfredSteyer

Slide 31

Slide 31 text

@ManfredSteyer

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

@ManfredSteyer

Slide 35

Slide 35 text

@ManfredSteyer Example Flight System

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

@ManfredSteyer Booking Luggage Boarding Check-in Context Map

Slide 38

Slide 38 text

@ManfredSteyer Luggage Booking Context Map Check-in Boarding Shared Kernel

Slide 39

Slide 39 text

@ManfredSteyer Booking Check-in API

Slide 40

Slide 40 text

@ManfredSteyer Lots of approaches for cross-domain communication and more …

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

@ManfredSteyer Booking Boarding Shared Feature API 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 @ManfredSteyer

Slide 43

Slide 43 text

@ManfredSteyer Booking Boarding Shared Feature API 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 @ManfredSteyer

Slide 44

Slide 44 text

@ManfredSteyer Application Domain Model Infrastructure Isolate your domain! Domain e. g. data access Use case specific facades, state management Entities, biz logic

Slide 45

Slide 45 text

@ManfredSteyer Alternatives to layering • e. g. Hexagonal Architecture, Clean Architecture • Anyway: We need to restrict access b/w libraries

Slide 46

Slide 46 text

@ManfredSteyer DEMO

Slide 47

Slide 47 text

@ManfredSteyer Finegrained Libraries • Unit of recompilation • Unit of retesting • Access restrictions • Information Hiding • Easy: Just ng g lib … • Future replacement for NgModules?

Slide 48

Slide 48 text

@ManfredSteyer Micro Frontends? Short outlook

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

@ManfredSteyer

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

@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

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

@ManfredSteyer Integration via Hyperlinks

Slide 57

Slide 57 text

@ManfredSteyer

Slide 58

Slide 58 text

@ManfredSteyer

Slide 59

Slide 59 text

@ManfredSteyer Integration via Shell

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

@ManfredSteyer Loading Separately Compiled SPAs const script = document.createElement('script'); script.src = 'assets/micro-app.bundle.js'; document.body.appendChild(script); const clientA = document.createElement('client-a'); clientA['visible'] = true; document.body.appendChild(clientA);

Slide 62

Slide 62 text

@ManfredSteyer

Slide 63

Slide 63 text

@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!

Slide 64

Slide 64 text

@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')

Slide 65

Slide 65 text

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

Slide 66

Slide 66 text

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

Slide 67

Slide 67 text

@ManfredSteyer DEMO

Slide 68

Slide 68 text

@ManfredSteyer

Slide 69

Slide 69 text

@ManfredSteyer Well … Webpack 5 is currently beta Shown examples: PoC w/ custom webpack conf + patched CLI lib CLI: Not before version 11 (fall 2020) Custom Builder (e. g. ngx-build-plus)

Slide 70

Slide 70 text

@ManfredSteyer Free eBook ANGULARarchitects.io/book Updated for Module Federation and Alternatives

Slide 71

Slide 71 text

@ManfredSteyer Choosing a Solution

Slide 72

Slide 72 text

@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 Not a good fit for public web sites