01 Angular Architecture MonoRepo
01 Angular Architecture MonoRepo
AppModule … SharedModule
SharedModule
Page ▪ 2 @ManfredSteyer
Contents
• (npm-)Packages
• Nx Monorepos
• Strategic Design and DDD
@ManfredSteyer
npm Packages
@ManfredSteyer
Create Library with CLI >= 6
npm install -g @angular/cli
ng new lib-project
cd lib-project
@ManfredSteyer
Folder
Structure
@ManfredSteyer
Create Library with CLI >= 6
npm install -g @angular/cli
cd lib-project
@ManfredSteyer
Publishing
@ManfredSteyer
Publishing to npm Registry
• Increment version in package.json
@ManfredSteyer
Alternatives for setting the Registry
• Global: npm set registry http://localhost:4873
• Default: registry.npmjs.org
• npm get registry
registry=http://localhost:4873/
@my-company:registry=http://my-server:4873/
@ManfredSteyer
npm Registries
Nexus Artifactory
Team
Foundation Verdaccio
npm i -g verdaccio
Server verdaccio
@ManfredSteyer
Advantages
• Distribution
• Versioning
@ManfredSteyer
Disadvantages
• Distribution
• Versioning
;-)
@ManfredSteyer
Disadvantages
Distribution Versioning
@ManfredSteyer
Monorepos
@ManfredSteyer
Monorepo
Structure
@ManfredSteyer
Advantages
Everyone uses the latest versions
No version conflicts
@ManfredSteyer
Two Flavors
Project Monorepo
Company-wide Monorepo
@ManfredSteyer
Moving back and forth
Npm Registry
@ManfredSteyer
Tooling & Generator
https://nrwl.io/nx
@ManfredSteyer
Visualize
Module
Structure
@ManfredSteyer
Creating a Workspace
npm install -g @angular/cli
ng new workspace
cd workspace
@ManfredSteyer
Creating a Workspace
npm install -g @angular/cli
cd workspace
@ManfredSteyer
DEMO
@ManfredSteyer
LAB
@ManfredSteyer
DDD
in a nutshell
@ManfredSteyer
Methodology for
bridging the gap b/w
requirements and
architecture/ design
@ManfredSteyer
@ManfredSteyer
@ManfredSteyer
Domain Driven Design
Design Patterns
Decomposing a System
& Practices
Flight System
@ManfredSteyer
Example
Booking Check-in
Sub-Domains
Luggage Boarding
@ManfredSteyer
Context Map
Check-in
@ManfredSteyer
Context Map
Booking Check-in
Shared Kernel
Boarding Luggage
@ManfredSteyer
API
Booking Check-in
@ManfredSteyer
Lots of approaches
for cross-domain
communication and
more …
@ManfredSteyer
Shared Kernel (if really needed) & other libs
Smart
Comp. Booking Boarding Shared
Dumb Comp.
Feature Feature Feature Feature Feature
UI UI UI UI UI UI UI UI UI
UI UI UI UI UI UI UI UI UI
@ManfredSteyer @ManfredSteyer
Booking Boarding Shared
UI UI UI UI UI UI UI UI UI
@ManfredSteyer @ManfredSteyer
Isolate your domain! Use case specific facades,
state management
Infrastructure
e. g. data access
@ManfredSteyer
Alternatives to • e. g. Hexagonal Architecture, Clean Architecture
layering • Anyway: We need to restrict access b/w libraries
@ManfredSteyer
DEMO
@ManfredSteyer
Finegrained Libraries
• Unit of recompilation
• Unit of retesting
• Access restrictions
• Information Hiding
• Easy: Just ng g lib …
• Future replacement for
NgModules?
@ManfredSteyer
Where‘s the Catch?
Inofficial Solution
@ManfredSteyer
Micro
Frontends?
Short outlook
@ManfredSteyer
Microfrontends
@ManfredSteyer
@ManfredSteyer
Deployment Monolith
Flight App
… … … … … … … … …
@ManfredSteyer @ManfredSteyer
Microfrontends
… … … … … … … … …
@ManfredSteyer
Option 1: One App per Domain
… … … … … … … … …
Monorepo
@ManfredSteyer
Option 2: One Monorepo per Domain
… … … … … … … … …
Repository 1 Repository 2
@ManfredSteyer Repository n
Benefits
Autonomous Teams
Separate Development
Separate Deployment
@ManfredSteyer
Integration via
Hyperlinks
@ManfredSteyer
UI Composition
w/ Hyperlinks
@ManfredSteyer
@ManfredSteyer
@ManfredSteyer
Integration via
Shell
@ManfredSteyer
Providing a (SPA based) Shell
Shell
µApp µService
µApp µApp
@ManfredSteyer
@ManfredSteyer
Idea
Does not work with
webpack/ Angular CLI
@ManfredSteyer
Webpack 5 Module Federation
import('mfe1/Cmp')
@ManfredSteyer
How to Get the Microfrontend's URL?
@ManfredSteyer
How to Share Libs?
shared: [ shared: [
"@angular/core", "…" "@angular/core", "…"
] ]
@ManfredSteyer
@ManfredSteyer
Default Behavior
Selecting the highest compatible version
10.0 10.1
@ManfredSteyer
Default Behavior
Conflict: No highest compatible version
11.0 10.1
@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
@ManfredSteyer
Configuring Singletons
shared: {
"my-lib": {
singleton: true
}
}
11.0 10.1
@ManfredSteyer
Configuring Singletons
shared: {
"my-lib": {
singleton: true,
strictVersion: true // Error instead of warning!
}
}
11.0 10.1
@ManfredSteyer
Relaxing Version Requirements
shared: {
"my-lib": {
requiredVersion: ">=1.0.1 <11.1.1"
}
}
@ManfredSteyer
@ManfredSteyer
?
@ManfredSteyer
Custom Builder
@ManfredSteyer
@ManfredSteyer
1) ng add @angular-architects/module-federation
2) Adjust generated configuration
3) ng serve
@ManfredSteyer
@ManfredSteyer
@ManfredSteyer
Well …
Webpack 5: final
@angular-architects/module-federation: final
@ManfredSteyer
Choosing a Solution
@ManfredSteyer
Some General Advice
Module Federation
little
Hyperlinks
Shared state,
navigation b/w yes iframes
apps Legacy Apps or
yes Load Bundles on
*very very* strong
much Demand
isolation? Separate
no Deployment/ mix
Technologies?
no Monolith
@ManfredSteyer