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
330
Generative UI & AI-Assistants for Your Angular Solutions
manfredsteyer
PRO
0
160
Nostalgia Meets Technology: Super Mario with TypeScript
manfredsteyer
PRO
0
230
Signal Forms: Details & Live Coding @enterJS 2026 in Mannheim
manfredsteyer
PRO
0
250
Strategic Design in the Frontend: Moduliths & Micro Frontends @DDDEurope
manfredsteyer
PRO
0
180
Agentic UI
manfredsteyer
PRO
0
260
Signal Forms: Beyond the Basics @ngBaguette 2026 in Paris
manfredsteyer
PRO
0
310
Agentic UI beyond Chats Architecture Patterns & Open Standards @ngMunich 05/2026
manfredsteyer
PRO
0
260
Agentic AI in the Frontend: Architectures with Open Standards @iJS London 2026
manfredsteyer
PRO
0
190
Other Decks in Programming
See All in Programming
その節約、円になってますか?
isamumumu
1
710
作るコストが小さくなった時代 幸せに働くために改めて考えたいこと 〜エンジニアとして価値を出し続けるために注視している二分野〜
yuppeeng
0
190
OpenSpecのproposalにbrainstormingを持たせてみた
tigertora7571
1
210
FDEが実現するAI駆動経営の現在地
gonta
2
270
ここ半年くらいでAIに作らせたR用ツール
eitsupi
0
370
そこに3びきプロダクトがいるじゃろう——生成AI時代における“価値が届かない理由”の構造
kosuket
0
440
ルールを書いて終わらせないハーネスエンジニアリング
yug1224
4
1.9k
仕様駆動開発へのトライを機に チームに適合する手法を模索し続けている話
freee
PRO
0
450
壊れたパーサから始める関数型設計と構成的なパーサ #fp_matsuri
raiga0310
2
450
AWS DevOps AgentのAzure接続機能を検証して見えた活用法/Use Cases Verified for the AWS DevOps Agent's Azure Connectivity Feature
masakiokuda
1
220
PHP に部分適用が来るぞ!……ところで何それ?おいしいの? #phpcon / phpcon-2026
shogogg
0
600
生成AIで帳票OCRが「簡単に」作れる時代になった?
kon_shou
0
640
Featured
See All Featured
Build your cross-platform service in a week with App Engine
jlugia
234
19k
Darren the Foodie - Storyboard
khoart
PRO
3
3.6k
First, design no harm
axbom
PRO
2
1.2k
[RailsConf 2023] Rails as a piece of cake
palkan
59
6.9k
How to Align SEO within the Product Triangle To Get Buy-In & Support - #RIMC
aleyda
2
1.8k
Heart Work Chapter 1 - Part 1
lfama
PRO
8
36k
New Earth Scene 8
popppiees
3
2.5k
Are puppies a ranking factor?
jonoalderson
1
3.8k
Become a Pro
speakerdeck
PRO
31
6.2k
Typedesign – Prime Four
hannesfritz
42
3.1k
AI Search: Where Are We & What Can We Do About It?
aleyda
0
7.8k
Discover your Explorer Soul
emna__ayadi
2
1.2k
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