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

Angular Best Practices

Angular Best Practices

Thorsten Rinne

June 26, 2018
Tweet

More Decks by Thorsten Rinne

Other Decks in Programming

Transcript

  1. Angular Best
    Practices
    Thorsten Rinne - 26. Juni 2018

    View full-size slide

  2. Hallo, ich bin Thorsten.

    View full-size slide

  3. Software-Architekt

    View full-size slide

  4. https://github.com/thorsten

    https://twitter.com/ThorstenRinne

    View full-size slide

  5. PHP → TypeScript

    View full-size slide

  6. Best Practices?

    View full-size slide

  7. Unser Projekt

    View full-size slide

  8. Zahlen & Fakten
    • Web App mit verschiedenen Backend-Systemen

    • Branche: Energiemanagement

    • Start Mitte September 2016 mit Angular 2.0.0

    • bis zu sieben Frontend-Entwickler

    • über 70 fachliche und technische Module

    • über 300 Komponenten

    • über 2200 Unittests

    View full-size slide

  9. Angular
    • TypeScript

    • komponentenbasiertes Framework

    • kein $scope und keine Controller

    • modular aufgebaut

    • rxjs

    • angular-cli

    • feste Releasezyklen und Semantic Versioning

    View full-size slide

  10. Angular Versionen
    • September 2016: 2.0

    • März 2017: 4.0

    • November 2017: 5.0

    • Mai 2018: 6.0

    • aktuell: 6.0.5 und 6.1.0-beta

    View full-size slide

  11. Learnings der zwei Jahre

    View full-size slide

  12. angular-cli
    • entwickelt vom Angular Team

    • standardisierte Projektstruktur inkl Tests

    • Production Build

    • Webpack

    • ab v6: Updates und Libraries

    View full-size slide

  13. ng add
    $ ng add @angular/material
    • fügt Angular Material in die Applikation

    • fügt die CSS Themes hinzu

    • das Default Theme

    • alle nötigen Imports des Moduls

    $ ng generate @angular/material:material-nav —name=nav
    • erstellt eine NavComponent

    • erstellt den kompletten Boilerplate-Code


    View full-size slide

  14. ng update
    • aktualisiert Pakte und startet Migrationsskripte (wenn
    verfügbar)

    $ ng update @angular/cli --migrate-only --
    from=1.7.4
    • aktualisiert von v1.7.4 auf v6.0.5

    • fügt fehlende Abhängigkeiten hinzu

    • migriert zur neuen angular.json Datei

    View full-size slide

  15. Struktur
    Architektur

    View full-size slide

  16. Angular Architektur
    ngModule
    ngModule
    root Module
    ngModule
    Router
    Component
    Template
    Styles Service
    Pipe Directive
    imports
    PropertyBinding
    EventBinding
    DI

    View full-size slide

  17. Architektur-Vorschlag
    • CoreModule

    • SharedModule

    • Feature Module

    • fachlich

    • technisch

    View full-size slide

  18. CoreModule
    • Singleton Services

    • nur einmal pro Instanz

    • Beispiele

    • (Authentifizierung / User)

    • MediaQueries

    • Datum/Zeit

    View full-size slide

  19. modules/
    core/
    services/
    core.module.ts
    index.ts Re-Export von CoreModule

    View full-size slide

  20. SharedModule
    • beinhaltet „einfache“ Components

    • Pipes

    • Import und Re-Export von Angular Material Komponenten

    View full-size slide

  21. Feature Modules
    • Components

    • Components

    • Pages

    • Dialogs

    • Services

    • Konstanten

    • Models

    • Utilities

    View full-size slide

  22. modules/
    foo-bar/
    components/
    baz/
    baz.component.html
    baz.component.scss
    baz.component.spec.ts
    baz.component.ts
    constants/
    dialogs/
    directives/
    models/
    pages/
    pipes/
    services/
    utils/

    View full-size slide

  23. Faustregeln für Feature
    Modules
    • sind fachlich gekapselt

    • importieren Services nur aus dem CoreModule

    • Lazy loaded

    View full-size slide

  24. Lazy Loading
    AppRoutingModule
    Feature Module
    Routing Module Component

    View full-size slide

  25. const routes: Routes = [
    {
    path: 'feature',
    loadChildren: 'app/feature/feature.module#FeatureModule'
    },
    {
    path: '',
    redirectTo: '',
    pathMatch: 'full'
    }
    ];
    src/app/app-routing.module.ts

    View full-size slide

  26. import { NgModule } from '@angular/core';
    import { CommonModule } from '@angular/common';
    import { FeatureRoutingModule } from './feature-routing.module';
    import { FeatureComponent } from './feature/feature.component';
    @NgModule({
    imports: [
    CommonModule,
    FeatureRoutingModule
    ],
    declarations: [ FeatureComponent ]
    })
    export class FeatureModule { }
    src/app/modules/feature/feature.module.ts

    View full-size slide

  27. @app
    • konsistente Importe in der kompletten App

    • Beispiel


    import { 

    FooService 

    } from '../../../core/package/foo.service';
    • besser:


    import { FooService } from '@app/core';

    View full-size slide

  28. {
    "compilerOptions": {
    "...": "...",
    "baseUrl": "src",
    "paths": {
    "@app/*": ["app/*"],
    "@env/*": ["environments/*"]
    }
    }
    }
    tsconfig.json

    View full-size slide

  29. import { Component, OnInit } from '@angular/core';
    import { Observable } from 'rxjs/Observable';
    import { SingletonService } from '@app/core';
    import { environment } from '@env/environment';
    import { ExampleService } from './example.service';
    @Component({
    /* ... */
    })
    export class ExampleComponent implements OnInit {
    constructor(
    private SingletonService: SingletonService,
    private exampleService: ExampleService
    ) {}
    }
    example.component.ts
    Third Party
    App Globals
    Locally

    View full-size slide

  30. Typings
    interface User {
    firstName: string;

    lastName: string;

    age: number;

    createdDate: string | Date;

    }
    Response vom Server Rückgabewert eines Datepickers

    View full-size slide

  31. Typ Restriktionen (I)
    interface Order {
    state: 'pending' | 'approved' | 'rejected';
    }

    View full-size slide

  32. Typ Restriktionen (II)
    enum States {
    pending = 1,
    approved = 2,
    rejected = 3;
    }
    interface Order {
    state: States;
    }

    View full-size slide

  33. rxjs/observable

    View full-size slide

  34. class CountryService {
    private countries: Observable;
    constructor(private http: Http) {
    this.countries = this.http.get('/api/countries')
    .publishReplay(1)
    .refCount();
    }
    public getCountries(): Observable {
    return this.countries;
    }
    }
    country.service.ts
    rxjs cached den letzten Emittenten Wert.
    das Observable ist nutzbar, solange Subscriptions aktiv sind

    View full-size slide

  35. SCSS
    • SCSS ist ein CSS Präprozessor

    • Features

    • Variablen

    • Funktionen

    • Mixins

    • Angular Materials nutzt SCSS

    • Für neue Projekte: $ ng new --style scss

    View full-size slide

  36. Beispiel
    @import "config/colors";
    :host {
    display: flex;
    align-items: center;
    max-width: px-to-rem(200);
    }


    $rem-base: 16;
    @function px-to-rem($px-value) {
    @return $px-value / $rem-base * 1rem;
    }

    View full-size slide

  37. ng test
    • Testen von Angular Apps ist einfach


    $ ng test

    • Es wird Jasmine mit Karma und PhantomJS verwendet

    • Nachteile

    • langsam

    • PhantomJS hat eine veraltete Rendering Engine

    • PhantomJS wird nicht mehr weiter entwickelt

    View full-size slide

  38. ng test
    • Chrome 59 und später hat einen Headless Modus

    • Das geht einfach


    $ ng test --browser ChromeHeadless --single-run

    • Nachteile

    • es ist immer noch langsam

    View full-size slide

  39. Jest
    • „Delightful JavaScript Testing“ von Facebook

    • Jest ist fast API-kompatibel mit Jasmine

    • Fokus auf die Entwicklung (schnell und einfach zu nutzen)

    • abstrahiert den DOM über JSDOM

    • Code Coverage out of the box

    • TypeScript Support

    View full-size slide

  40. Jest Installation
    $ yarn add --dev jest jest-preset-angular @types/jest

    View full-size slide

  41. Vorteile von Jest
    • 300% schnellere Testausführung

    • ~2200 Tests laufen in etwa 60 Sekunden

    • Integration in WebStorm und VS Code

    • Snapshot Testing möglich

    View full-size slide

  42. Commit Messages
    +
    ChangeLog Generator

    View full-size slide

  43. • github.com/conventional-changelog/standard-version

    • definiert

    • Typ des Commits (Fix, Feature, Layout, usw.)

    • Optional den Scope (Component oder Module)

    • Commit Message

    • Optional Body

    • Ticket-ID

    View full-size slide

  44. fix(foo-bar): removes dependency of jQuery
    We don’t need jQuery, so it can be removed
    closes #4711

    View full-size slide

  45. 2.0.0 (2018-06-26)

    Bug Fixes

    • FooBar: removes dependency of jQuery (8a0f5aa), closes
    #4711

    Semantic Versioning
    SHA-1 Hash

    View full-size slide

  46. Development Build
    • $ yarn start
    • startet yarn serve


    "serve": "ng serve —sourcemaps --ssl --
    host=0.0.0.0 --disable-host-check --extract-css"

    • startet das Testbackend mit yarn test-backend


    "test-backend": "nodemon --watch test-backend -e
    js,ts,json -i '*.spec.ts' --exec \"cd test-
    backend && ts-node -r tsconfig-paths/register\"
    src/server.ts"


    View full-size slide

  47. Production Build
    • Unser Production Build


    "build:prod": "npm run version && npm run
    node-with-more-memory ./node_modules/
    @angular/cli/bin/ng build -- —build-
    optimizer --env=prod --sourcemaps"

    View full-size slide

  48. Debugging mit Augury

    View full-size slide

  49. Augury
    • Google Chrome Developer Tool Erweiterung

    • visualisiert Components

    • visuelles Debugging möglich

    • Change Detection und Performance Checks

    View full-size slide

  50. Danke für eure
    Aufmerksamkeit!

    View full-size slide