Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Better Angular Architectures: Architectures wit...
Search
Manfred Steyer
PRO
July 05, 2022
Programming
1k
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Better Angular Architectures: Architectures with Standalone Components @DWX2022
Manfred Steyer
PRO
July 05, 2022
More Decks by Manfred Steyer
See All by Manfred Steyer
Generative UI & AI-Assistants for Your Angular Solutions
manfredsteyer
PRO
1
470
Generative UI & AI-Assistants for Your Angular Solutions
manfredsteyer
PRO
0
200
Nostalgia Meets Technology: Super Mario with TypeScript
manfredsteyer
PRO
0
290
Signal Forms: Details & Live Coding @enterJS 2026 in Mannheim
manfredsteyer
PRO
0
290
Strategic Design in the Frontend: Moduliths & Micro Frontends @DDDEurope
manfredsteyer
PRO
0
200
Agentic UI
manfredsteyer
PRO
0
310
Signal Forms: Beyond the Basics @ngBaguette 2026 in Paris
manfredsteyer
PRO
0
350
Agentic UI beyond Chats Architecture Patterns & Open Standards @ngMunich 05/2026
manfredsteyer
PRO
0
290
Agentic AI in the Frontend: Architectures with Open Standards @iJS London 2026
manfredsteyer
PRO
0
230
Other Decks in Programming
See All in Programming
Hello, Hiroshima Geospatial Data! — Exploring DoboX with Python
ra0kley
0
160
バグを直したら useEffect が消えた
colorful12
3
830
Swift愛好会と私(ウホーイ) / Swift Fan Club and Uhooi
uhooi
0
120
Deep dive into the select statement (GopherCon UK)
jespino
0
170
まずはプロンプトガイドを読もう、話はそれからだ
kiakiraki
1
250
異なる設計思想のフレームワークを経験して得た学び
amekuhideki
2
1.5k
30年振りにコンパイラの定数整数除算を改善した
herumi
9
4.4k
思考垂れ流し開発 ~音声入力 × AIエージェント × 開発ハーネスによる試行錯誤~
npostring
0
810
tsc.rip を支える技術 / Kyoto.なんか #8
susisu
0
4.2k
【デモ】Kiroで体験する仕様駆動開発|設計からコーディングまでAIと進める開発フロー
cmkudo
0
560
PyO3 で既存 Python 評価器を Rust core 化する ー wasm-bindgen でブラウザにも配るための設計
kdash
1
340
PyConJP2026_wat_Python × Signal Processing: How to Draw Pictures with Sound Using Spectrogram Art
wat
0
650
Featured
See All Featured
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
Statistics for Hackers
jakevdp
799
230k
Test your architecture with Archunit
thirion
2
2.4k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
37
6.6k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
Why Your Marketing Sucks and What You Can Do About It - Sophie Logan
marketingsoph
0
400
Typedesign – Prime Four
hannesfritz
42
3.2k
Navigating Team Friction
lara
192
16k
Art, The Web, and Tiny UX
lynnandtonic
304
22k
Neural Spatial Audio Processing for Sound Field Analysis and Control
skoyamalab
0
450
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
16k
How Software Deployment tools have changed in the past 20 years
geshan
1
34k
Transcript
@ManfredSteyer Better Angular Architectures: Architectures with Standalone Components
@ManfredSteyer
@ManfredSteyer
@ManfredSteyer
@ManfredSteyer
@ManfredSteyer Angular 2 BETA, Feb 2016 @Component({ selector: 'app', directives:
[ROUTER_DIRECTIVES, MyComponent, NgIf, NgFor], templateUrl: 'app/app.html' }) @RouteConfig([ { path: '/', component: Home, … }, { path: '/voucher', component: Voucher, … }, ]) export class App { […] }
@ManfredSteyer Angular 2 RC.5, August 2016 import { NgModule }
from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { AppComponent } from './app.component'; […] @NgModule({ imports: [BrowserModule, OtherModule], declarations: [AppComponent, OtherComponent, OtherDirective], providers: [], bootstrap: [AppComponent], }) export class AppModule {}
@ManfredSteyer Angular 2 RC.5, August 2016 import { NgModule }
from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { AppComponent } from './app.component'; […] @NgModule({ imports: [BrowserModule, OtherModule], declarations: [AppComponent, OtherComponent, OtherDirective], providers: [], bootstrap: [AppComponent], }) export class AppModule {}
@ManfredSteyer Angular 2 RC.5, August 2016 import { NgModule }
from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { AppComponent } from './app.component'; […] @NgModule({ imports: [BrowserModule, OtherModule], declarations: [AppComponent, OtherComponent, OtherDirective], providers: [], bootstrap: [AppComponent], }) export class AppModule {} TypeScript Modules Angular Modules
@ManfredSteyer My Ivy Talk at ng-conf 2020
@ManfredSteyer @Component({ standalone: true, selector: 'app-root', imports: [ HomeComponent, AboutComponent,
HttpClientModule, ], templateUrl: '…' }) export class AppComponent { […] }
@ManfredSteyer bootstrapApplication(AppComponent);
@ManfredSteyer
@ManfredSteyer #1 Mental Model #2 Compatibility #3 Routing #4 Architecture
@ManfredSteyer Manfred Steyer
@ManfredSteyer
@ManfredSteyer Standalone Component = Component + NgModule (not implemented that
way!)
@ManfredSteyer @Component({ standalone: true, selector: 'app-root', imports: [ RouterModule, HomeComponent,
AboutComponent, ], templateUrl: '…' }) export class AppComponent { […] } @NgModule({ imports: [ RouterModule, HomeComponentModule, AboutComponentModule, ], declares: [ AppComponent ] }) export class AppModule { … } @Component({ selector: 'app-root', templateUrl: '…' }) export class AppComponent { […] }
@ManfredSteyer @Pipe({ standalone: true, name: 'city', pure: true }) export
class CityPipe implements PipeTransform { […] }
@ManfredSteyer @Directive({ standalone: true, selector: 'input[appCity]', providers: [ … ]
}) export class CityValidator implements Validator { […] }
@ManfredSteyer @Component({ standalone: true, imports: [ […], FlightCardComponent, CityPipe, CityValidator,
], selector: 'flight-search', templateUrl: '…' }) export class FlightSearchComponent { […] }
@ManfredSteyer
@ManfredSteyer It looks like you want to use NgIfDirective and
MyComponent. Shall I import it for you?
@ManfredSteyer
@ManfredSteyer
@ManfredSteyer → @Component({ standalone: true, selector: 'app-root', imports: [ […]
TicketsModule, ], templateUrl: '…' }) export class AppComponent { }
@ManfredSteyer → @Component({ standalone: true, selector: 'app-root', imports: [ […]
TicketsModule, ], templateUrl: '…' }) export class AppComponent { }
@ManfredSteyer → @NgModule({ imports: [ FlightCardComponent, ], declarations: [ MyTicketsComponent
], }) export class TicketsModule { }
@ManfredSteyer → @NgModule({ imports: [ FlightCardComponent, ], declarations: [ MyTicketsComponent
], }) export class TicketsModule { }
@ManfredSteyer bootstrapApplication(AppComponent, { providers: [ MyGlobalService, importProvidersFrom(HttpClientModule), importProvidersFrom(RouterModule.forRoot(APP_ROUTES)), ] });
@ManfredSteyer bootstrapApplication(AppComponent, { providers: [ MyGlobalService, importProvidersFrom(HttpClientModule), importProvidersFrom(RouterModule.forRoot(APP_ROUTES)), ] });
@ManfredSteyer
@ManfredSteyer
@ManfredSteyer
@ManfredSteyer bootstrapApplication(AppComponent, { providers: [ MyGlobalService, importProvidersFrom(HttpClientModule), importProvidersFrom(RouterModule.forRoot(APP_ROUTES)), ] });
@ManfredSteyer bootstrapApplication(AppComponent, { providers: [ MyGlobalService, importProvidersFrom(HttpClientModule), provideRoutes(APP_ROUTES), ] });
@ManfredSteyer export const APP_ROUTES: Routes = [ […], { path:
'flight-booking', loadChildren: () => import('@nx-example/booking/feature-book') .then(m => m.FLIGHT_BOOKING_ROUTES) }, { path: 'next-flight', loadComponent: () => import('@nx-example/booking/feature-tickets') .then(m => m.NextFlightComponent) }, ];
@ManfredSteyer export const APP_ROUTES: Routes = [ […], { path:
'flight-booking', loadChildren: () => import('@nx-example/booking/feature-book') .then(m => m.FLIGHT_BOOKING_ROUTES) }, { path: 'next-flight', loadComponent: () => import('@nx-example/booking/feature-tickets') .then(m => m.NextFlightComponent) }, ];
@ManfredSteyer export const FLIGHT_BOOKING_ROUTES: Routes = [{ path: '', component:
FlightBookingComponent, providers: [ MyService ], children: [ […] ] }];
@ManfredSteyer export const FLIGHT_BOOKING_ROUTES: Routes = [{ path: '', component:
FlightBookingComponent, providers: [ MyService ], children: [ […] ] }]; (Lazily) loaded with route config Scope: This route + all child routes
@ManfredSteyer export const FLIGHT_BOOKING_ROUTES: Routes = [{ path: '', component:
FlightBookingComponent, providers: [ ...configureMyLibrary() ], children: [ […] ] }];
@ManfredSteyer
@ManfredSteyer
@ManfredSteyer // index.ts == Public API export * from './flight-booking.component';
export * from './flight-card/flight-card.component';
@ManfredSteyer
@ManfredSteyer import * as booking from './booking'; […] @Component({ standalone:
true, imports: [ booking, […] ], […] }) export class MyComponent { […] } Wish List
@ManfredSteyer
@ManfredSteyer "paths": { "@demo/data": ["src/app/data/index.ts"], "@demo/shared": ["src/app/shared/index.ts"], "@demo/shell": ["src/app/shell/index.ts"], "@demo/booking":
["src/app/booking/index.ts"] }
@ManfredSteyer import * as booking from '@demo/booking'; […] @Component({ standalone:
true, imports: [ ...Object.values(booking) as any[], […] ], […] }) export class MyComponent { […] }
@ManfredSteyer
@ManfredSteyer + Generates path mappings + Generates initial barrel +
Prevents bypassing index.ts + much more
@ManfredSteyer
@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 @ManfredSteyer
@ManfredSteyer Free eBook (5th Edition) ANGULARarchitects.io/book Module Federation & Nx
@ManfredSteyer
@ManfredSteyer
@ManfredSteyer
@ManfredSteyer
@ManfredSteyer
@ManfredSteyer
@ManfredSteyer Lib A Lib B index.ts Comp1 Comp2 Today (with
NgModules) NgModule Comp3 NgModule
@ManfredSteyer Lib A Lib B index.ts Comp1 Comp2 Tomorrow (without
NgModules) Comp3
@ManfredSteyer Conclusion Mental Model Folders & Barrels Mapped Paths Nx,
Libs, and Constraints FTW!
@ManfredSteyer 2022
@ManfredSteyer d Slides & Examples Remote Company Workshops and Consulting
http://angulararchitects.io