Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Angular's Future Without NgModules: What Does That Mean for Our Architecture?

Angular's Future Without NgModules: What Does That Mean for Our Architecture?

15934fa2aa7b2ce21f091e9b7cffa856?s=128

Manfred Steyer
PRO

January 19, 2022
Tweet

More Decks by Manfred Steyer

Other Decks in Programming

Transcript

  1. @ManfredSteyer Angular's Future Without NgModules What Does That Mean for

    Our Architecture?
  2. @ManfredSteyer

  3. @ManfredSteyer

  4. @ManfredSteyer

  5. @ManfredSteyer

  6. @ManfredSteyer Angular 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 {
  7. @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 {}
  8. @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 {}
  9. @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
  10. @ManfredSteyer My Ivy Talk at ng-conf 2020

  11. @ManfredSteyer @Component({ standalone: true, selector: 'app-root', imports: [ HomeComponent, AboutComponent,

    HttpClientModule, ], templateUrl: '…' }) export class AppComponent { […] }
  12. @ManfredSteyer bootstrapComponent(AppComponent);

  13. @ManfredSteyer

  14. @ManfredSteyer #1 Mental Model #2 Compatibility #3 Architecture

  15. @ManfredSteyer Manfred Steyer

  16. @ManfredSteyer

  17. @ManfredSteyer Standalone Component = Component + NgModule (not implemented that

    way!)
  18. @ManfredSteyer @Component({ standalone: true, selector: 'app-root', imports: [ HomeComponent, AboutComponent,

    HttpClientModule, ], templateUrl: '…' }) export class AppComponent { […] } @NgModule({ imports: [ HttpClientModule ], declares: [ HomeComponent, AboutComponent ] }) export class AppModule { … } @Component({ selector: 'app-root', templateUrl: '…' }) export class AppComponent { […] } @Component({ selector: 'app-root', templateUrl: '…' }) export class AppComponent { […] }
  19. @ManfredSteyer @Pipe({ standalone: true, name: 'city', pure: true }) export

    class CityPipe implements PipeTransform { […] }
  20. @ManfredSteyer @Pipe({ standalone: true, name: 'city', pure: true }) export

    class CityPipe implements PipeTransform { […] }
  21. @ManfredSteyer @Directive({ standalone: true, selector: 'input[appCity]', providers: [ … ]

    }) export class CityValidator implements Validator { […] }
  22. @ManfredSteyer @Component({ standalone: true, imports: [ […], FlightCardComponent, CityPipe, CityValidator,

    ], selector: 'flight-search', templateUrl: '…' }) export class FlightSearchComponent { […] }
  23. @ManfredSteyer

  24. @ManfredSteyer It looks like you want to use NgIfDirective and

    MyComponent. Shall I import it for you?
  25. @ManfredSteyer (… using a shim for Standalone Blocks NOT intented

    for production)
  26. @ManfredSteyer

  27. @ManfredSteyer → @Component({ standalone: true, selector: 'app-root', imports: [ […]

    HttpClientModule, RouterModule.forRoot([ { path: 'home', component: HomeComponent }, […] ]) ], templateUrl: '…' }) export class AppComponent { }
  28. @ManfredSteyer → @Component({ standalone: true, selector: 'app-root', imports: [ […]

    HttpClientModule, RouterModule.forRoot([ { path: 'home', component: HomeComponent }, […] ]) ], templateUrl: '…' }) export class AppComponent { }
  29. @ManfredSteyer → @NgModule({ imports: [ FlightCardComponent, ], declarations: [ MyTicketsComponent

    ], }) export class TicketsModule { }
  30. @ManfredSteyer → @NgModule({ imports: [ FlightCardComponent, ], declarations: [ MyTicketsComponent

    ], }) export class TicketsModule { }
  31. @ManfredSteyer

  32. @ManfredSteyer (… using a shim for Standalone Blocks NOT intented

    for production)
  33. @ManfredSteyer

  34. @ManfredSteyer

  35. @ManfredSteyer // index.ts == Public API export * from './flight-booking.component';

    export * from './flight-card/flight-card.component';
  36. @ManfredSteyer import * as booking from './booking'; […] @Component({ standalone:

    true, imports: [ ...Object.keys(booking) as any[], […] ], […] }) export class MyComponent { […] }
  37. @ManfredSteyer import * as booking from './booking'; […] @Component({ standalone:

    true, imports: [ ...Object.values(booking) as any[], […] ], […] }) export class MyComponent { […] } Not beautiful!
  38. @ManfredSteyer import * as booking from './booking'; […] @Component({ standalone:

    true, imports: [ ...all(booking), […] ], […] }) export class MyComponent { […] } Custom Helper Function
  39. @ManfredSteyer

  40. @ManfredSteyer

  41. @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"] }
  42. @ManfredSteyer import * as booking from '@demo/booking'; […] @Component({ standalone:

    true, imports: [ ...Object.values(booking) as any[], […] ], […] }) export class MyComponent { […] }
  43. @ManfredSteyer (… using a shim for Standalone Blocks NOT intented

    for production)
  44. @ManfredSteyer

  45. @ManfredSteyer + Generates path mappings + Generates initial barrel +

    Prevents bypassing index.ts + much more
  46. @ManfredSteyer

  47. @ManfredSteyer Booking Booking Boarding Boarding Shared Shared Feature Feature Feature

    Feature Feature Feature Feature Feature Feature Feature UI UI UI UI UI UI UI UI UI UI UI UI UI UI UI UI UI UI Domain Domain Domain Domain Domain Domain Domain Domain Domain Domain Domain Domain Util Util Util Util Util Util Util Util Util Util Util Util @ManfredSteyer
  48. @ManfredSteyer Free eBook ANGULARarchitects.io/book Updated for Module Federation and Alternatives

  49. @ManfredSteyer (… using a shim for Standalone Blocks NOT intented

    for production)
  50. @ManfredSteyer Angular Architektur Workshop (100% Online, Interaktiv) 16.2. bis 18.2.2022

    https://angulararchitects.io/next
  51. @ManfredSteyer Conclusion Mental Model Mental Model Folders & Barrels Folders

    & Barrels Mapped Paths Mapped Paths Nx, Libs, and Constraints FTW! Nx, Libs, and Constraints FTW!
  52. @ManfredSteyer 2022

  53. @ManfredSteyer d Slides & Examples Remote Company Workshops and Consulting

    http://angulararchitects.io