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

Architectures for big Enterprise Applications w...

Architectures for big Enterprise Applications with Angular -- Talk from JAX 2018 in Mainz

Avatar for Manfred Steyer

Manfred Steyer

April 25, 2018
Tweet

More Decks by Manfred Steyer

Other Decks in Programming

Transcript

  1. @BASTAcon & @ManfredSteyer About me… • Manfred Steyer • SOFTWAREarchitekt.at

    • Angular Trainings and Consultancy • Google Developer Expert (GDE) Page ▪ 2 Manfred Steyer
  2. Typical Module Structure Page ▪ 3 AppModule … … …

    SharedModule Root Module Feature Modules Shared Module
  3. Idea behind Barrels • ES Module: File == Modul •

    Far too fine-grained for consumers of a lib • Barrel == Façade for those files == Public API
  4. index.ts as Barrel export * from './src/demo.service'; export { OtherDemoService

    } from './src/other-demo.service'; export { DemoModule } from './src/demo.module';
  5. Simple Module @NgModule({ imports: [ CommonModule ], declarations: [ DemoComponent

    ], providers: [ DemoService, ConfigService ], exports: [ DemoComponent ] }) export class DemoModule { }
  6. Providers @NgModule({ imports: [ CommonModule ], declarations: [ DemoComponent ],

    providers: [ DemoService, ConfigService ], exports: [ DemoComponent ] }) export class DemoModule { } Not tree-shakable Lazy Loading: Duplication
  7. Providers @NgModule({ imports: [ CommonModule ], declarations: [ DemoComponent ],

    providers: [ DemoService, ConfigService ], exports: [ DemoComponent ] }) export class DemoModule { }
  8. Providers for Module Configuration @NgModule({ imports: [ CommonModule ], declarations:

    [ DemoComponent ], providers: [ /* no services */ ], exports: [ DemoComponent ] }) export class DemoModule { }
  9. Providers for Module Configuration @NgModule({ imports: [ CommonModule ], declarations:

    [ DemoComponent ], providers: [ /* no services */ ], exports: [ DemoComponent ] }) export class DemoModule { static forRoot(config: ConfigService): ModuleWithProviders { […] } }
  10. Providers for Module Configuration @NgModule({ imports: [ CommonModule ], declarations:

    [ DemoComponent ], providers: [ /* no services */ ], exports: [ DemoComponent ] }) export class DemoModule { static forRoot(config: ConfigService): ModuleWithProviders { return { ngModule: DemoModule, providers: [ { provide: ConfigService, useValue: config } ] } } } + forChild or similar to setup Child-Modules
  11. Remaining Providers (Angular < 6) @NgModule({ imports: [ CommonModule ],

    declarations: [ DemoComponent ], providers: [ /* no services */ ], exports: [ DemoComponent ] }) export class DemoModule { static forRoot(config: ConfigService): ModuleWithProviders { return { ngModule: DemoModule, providers: [ { provide: ConfigService, useValue: config }, LoggerService ] } } }
  12. Remaining Providers (Angular >= 6) @Injectable({ providedIn: 'root' }) export

    class LoggerService { […] } Treeshakable Provider
  13. Create Library with CLI >= 6 npm install -g @angular/cli

    ng new lib-project cd lib-project ng generate library my-lib ng generate application playground-app ng build
  14. Publishing to npm Registry • Increment version in package.json •

    npm version [patch | minor | major | version] • ng build • npm publish --registry http://localhost:4873 • npm install --registry http://localhost:4873
  15. Alternatives for setting the Registry • Global: npm set registry

    http://localhost:4873 • Default: registry.npmjs.org • npm get registry • Project: .npmrc in project root
  16. Locale npm-Registry • Nexus • Artifactory • Team Foundation Server

    • Verdaccio • Very lightweight • npm i -g verdaccio • Start: verdaccio
  17. @ManfredSteyer Disadvantages Distribution • Annoying within project • Prevents gritting

    further libs Versioning • Old versions • Conflicts • How to force devs to use latest version? Decoupling • What if lib authors == app authors?
  18. @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, …
  19. @ManfredSteyer Two Flavors • Like Workspaces/Solutions in different IDEs Project

    Monorepo • E. g. used at Google or Facebook Company-wide Monorepo
  20. @ManfredSteyer Usage npm install -g @nrwl/schematics npm install -g @angular/cli

    create-nx-workspace myworkspace ng generate app myapp ng generate lib mymodule ng serve --app=myapp ng generate component myButton --app=mymodule ng build --app=myapp
  21. Further Features of Nx • Just recompile changed apps •

    Format Code/ check format • Restrict which apps/libs can access which other libs • Visualize module structure and dependencies
  22. @ManfredSteyer Some Options for Shell iframes • Strong Isolation •

    Straight forward • Overlapping Elements? • Lot's of page requests? Web Components • Standard • Custom Elements • <app-a></app-a> • <app-b></app-b> • Shadow DOM: CSS Isolation • Nesting • Framework Support? Bootstrapping different SPAs • Similar to Web Components • No Standard • Nesting isn’t possible
  23. @ManfredSteyer MicroApp with Angular Elements @NgModule({ imports: [BrowserModule], declarations: [MicroAppComponent],

    bootstrap: [], entryComponents: [MicroAppComponent] }) export class AppModule { }
  24. @ManfredSteyer MicroApp with Angular Elements @NgModule({ imports: [BrowserModule], declarations: [MicroAppComponent],

    bootstrap: [], entryComponents: [MicroAppComponent] }) export class AppModule { }
  25. @ManfredSteyer MicroApp with Angular Elements @NgModule({ imports: [BrowserModule], declarations: [MicroAppComponent],

    bootstrap: [], entryComponents: [MicroAppComponent] }) export class AppModule { constructor(private injector: Injector) { } ngDoBootstrap() { } }
  26. @ManfredSteyer MicroApp with Angular Elements @NgModule({ imports: [BrowserModule], declarations: [MicroAppComponent],

    bootstrap: [], entryComponents: [MicroAppComponent] }) export class AppModule { constructor(private injector: Injector) { } ngDoBootstrap() { const MicroAppElement = createNgElementConstructor( MicroAppComponent, { injector: this.injector }); customElements.define('micro-app', MicroAppElement); } }
  27. @ManfredSteyer Some General Advice for "Macro-Architecture" Shared state, communication/ navigation

    b/w apps Hyperlinks Legacy Apps or *very very* strong isolation needed? iframes Need separate Deployment/ mix Technologies Web Components "Majestic Monolith" w/ Libs and Monorepo little much yes no yes no Not best fit when customer facing Fallback: Bootstrap several frameworks/ Spa Micro-Architecture: Mix and match options: • Libs/ npm packages • Monorepo • Web Components • (Service Side Includes) • Separate Ways
  28. @ManfredSteyer Blog • A Software Architect's Approach Towards Using Angular

    (And SPAs In General) For Microservices Aka Microfrontends • A Lightweight And Solid Approach Towards Micro Frontends (Micro Service Clients) With Angular And/Or Other Frameworks • Microservice Clients With Web Components Using Angular Elements: Dreams Of The (Near) Future?