JavaScript-Frameworks: Wieso überhaupt, und dann welches?

Oliver Zeigermann / @DJCordhose

Online-Version: http://bit.ly/1Ot8Mkg

Code auf Github: https://github.com/DJCordhose/javascript-web-frameworks

Anleitung: ESC drücken für eine Übersicht über alle Folien, Blättern mit den Cursor-Tasten

Teil I

Was ist eine Single-Page-Applikation?

... und warum möchte ich eine haben

Klassiche Webanwendung

jeder Boot tut gut, jeder Roundtrip setzt Zustand zurück

Single Page Applications (SPAs) verschieben eure Anwendung in den Browser

  • UI/UX in klassischen Webanwendungen ist grunsätzlich eingeschränkt
  • Nutzer erwartet Bedienbarkeit wie im Desktop
  • klassische Webanwendung in seiner Reinform längst so gut wie ausgestorben
  • selbst in vermeintlich klassischen Anwendungen verstecken sich SPAs oft als Teile
  • z.B. JSF Komponenten mit einem komplexen UI

SPA Lean

SPA Fat

Und wieso dann ein JavaScript Web Framework?

Anfordernugen an Client Code wachsen bei SPAs dramatisch

Entweder nimmt man ein Standard-Framework

... oder man schreibt sein eigenes (manchmal ohne es zu merken)

Standard-Framework bietet

  • einen erprobten Rahmen
  • Community, Dokumentation
  • neue Mitarbeiter finden sich zurecht

Teil II

Komponenten basierte SPA Frameworks

Unsere Kandidaten

  1. Der Klassiker: Angular 1.x
  2. Von Antipatterns zu Best-Practices: React
  3. kgV (Vereinigungsmenge): Angular 2
  4. ggT (Schnittmenge): Web Components

Vorgehen

Mit allen Frameworks implementieren wir dasselbe Hello, World

Angular 1

  • Der Klassiker von Google
  • Massig Developer, Foren, Anbindungen, usw
  • 3 Ds
    • Data Binding (2-Wege)
    • Dependency Injection
    • Directives (=== Komponenten)

Hello World AngularJS 1.5

https://toddmotto.com/exploring-the-angular-1-5-component-method/


<input ng-model="greeter.greeting" id="in">
<p>{{greeter.greeting}}, World!</p>
<input type="button" value="Clear" ng-click="greeter.clear()">

<body ng-app="hello">
  <greeter greeting="Hello">
</body>

@hollandben

Komponente

angular.module('hello', [])
    .component('greeter', {
        bindings: {
            greeting: "@"
        },
        controller: function () {
            var vm = this;
            vm.clear = function () {
                vm.greeting = '';
                document.getElementById('in').focus();
            };
        },
        templateUrl: 'greeter.html'
    });
Run

2-Wege Databindung mit veränderlichem Zustand

Eine gute Idee?

React

  • Framework für Facebook und viele andere
  • Komponenten kapseln Template und Logik
  • Minimales API
  • Templates sind JavaScript plus HTML artige JSX-Syntax
  • Ein-Weg-Data-Binding: Zustandsänderungen stellen Komponente neu dar
  • Kann im Browser und auf dem Server rendern
  • viel Inspiration aus der funktionalen Ecke (Immutable, pure functions, stateless)

Hello World React

class HelloMessage extends React.Component {
  render() {
    return 
<input value={this.state.greeting} ref="in" onChange={this.updateModel.bind(this)} />

{this.state.greeting}, World

<button onClick={this.reset.bind(this)}>Clear</button>
; }
  constructor(props) {
    this.state = {greeting: this.props.greeting};
  }
  updateModel(event) {
    this.setState({greeting: event.target.value});
  }
  reset() {
    this.setState({greeting: ""});
    this.refs.in.focus();
  }
}

Aufruf


// index.html
<body>
  
</body>

// main.js
import HelloMessage from './HelloMessage';

var mountNode = document.getElementById('mount');
ReactDOM.render(<HelloMessage greeting="Hello"/>, mountNode);
Run

React Stack

React in der Praxis

  • React wird meist mit anderen Tools und Techniken zusammen eingesetzt
  • React-Router: Was wird bei welcher URL dargestellt?
  • Architektur-Muster
    • Universal Rendering: Server- und Client-Rendering kombiniert
    • Flux: UI-Architektur-Muster
    • Controller-/Child-Komponenten-Hierarchien
  • Build
    • Babel: Übersetzer
    • Webpack: Bundler
    • Flow: Statischer Type Checker

React Native

A framework for building native apps using React

Native Apps für Android und iOS mit React

Angular 2

  • Nachfolger von Angular 1
  • Ankündigung (Herbst 2014) hat zu Verunsicherung geführt
    • Konzepte deutlich anders als Angular 1
    • Kein Migrationspfad absehbar
  • Entwickelt in Microsofts TypeScript (ES5, ES6 und Dart auch unterstützt)
  • Deutlich schneller als Angular 1
  • Server side rendering wird unterstützt

Hello World AngularJS 2.x

@Component({
  selector: 'greeter'
  template:
  `<input [(ngModel)]="greeting" #in>
   <p>{{greeting}}, World</p>
   <button (click)="reset(in)">Clear</button>`
})
class Greeter {
    @Input() greeting: string;
    reset(input: HTMLInputElement) {
        this.greeting = '';
        input.focus();
    }
}

Aufruf

@Component({
    selector: 'hello-app',
    directives: [Greeter],
    template: ''
})
class App {
}
bootstrap(App);

<body>
    <hello-app></hello-app>
    <script>System.import('app');</script>
</body>

npm start

https://daveceddia.com/angular-2-should-you-upgrade/

Von Angular 1 zu Angular 2

  • Angular 2 ist seit Dezember 2015 in beta
  • sanfter Migrationspfad inklusive Mischen 1 und 2 mit ngUpgrade
  • Angular 1.5 enthält Component Router
    • funktioniert mit Angular 1 und 2
    • flexibel genug für alle Einsatzgebiete (inkl. nested Routes)

Web Components

  • Standard-Erweiterungen für Komponenten im Browser
    1. Custom Elements: man kann eigene Tags definieren
    2. HTML Templates: einfache Templates innerhalb einer HTML-Seite (jetzt im HTML-Standard)
    3. Shadow DOM: Lokale Kapselung von DOM und CSS
    4. HTML Imports: Inkludieren von HTML/Web Components

ACHTUNG

Web Components erlauben viele Spielarten

Die folgende Spielart ist meine Empfehlung

ACHTUNG #2

Die aktuellste Spec vom 8.4.2016 enthält Neuerungen, die jedoch bisher nicht umgesetzt sind

Hello World Web Components and ES6


<greeter-element greeting="Hello"></greeter-element>

// document.define in latest version of spec
document.registerElement('greeter-element', Greeter);

class Greeter extends HTMLElement {
    // constructor in latest version of spec, plus more callbacks
    createdCallback() {
        this.render();
        this.bind();
        this.setModel(this.getAttribute("greeting"));
    }

    attributeChangedCallback(name, oldValue, newValue) {
        if (name === "greeting") {
            this.setModel(newValue);
        }
    }
    // ...
}

Details


// just plain HTML using ES6 import
import template from './template.html';

render() {
  // this.attachShadow({mode: 'closed'}).innerHTML = template;
  this.createShadowRoot().innerHTML = template;
  this.input = this.shadowRoot.querySelector("#in");
  this.span = this.shadowRoot.querySelector("#log");
  this.button = this.shadowRoot.querySelector("#btn");
}

bind() {
  this.input.addEventListener("keyup", event => this.setModel(event.target.value));
  this.button.addEventListener("click", event => {
    this.setModel("");
    this.input.focus();
  });
}

setModel(value) {
  this.span.textContent = value;
  this.input.value = value;
}
Run

https://twitter.com/hichaelmart/status/667749535440084992/photo/1

Web Components: Unterstützung

Teil III

Querschnittsthemen und Bewertung

Build-Prozess

  • Angular 1
    • Optional, einfach angular.js einbinden
  • React
    • Notwendig (wegen JSX)
    • Babel und Webpack Standard
  • Angular 2
    • Notwendig für ES6 oder TypeScript
    • SystemJS kompiliert für Dev direkt im Browser
  • Web Components
    • Optional, funktioniert mit allem
    • HTML-Import schwierig für statisches Build

Router

Was wird bei welcher URL gerendert?

React-Router und Component Router können verschachtelte Routen rendern

Data-Bindung

  • Angular 1
    • 2-Wege
  • React
    • 1-Weg
    • Controller-/Child-View
  • Angular 2
    • 1-Weg
    • Controller-/Child-View
    • optional simuliertes 2-Wege-Binding
  • Web Components
    • Keine Vorgabe
    • Natürlicherweise Observer

Optimiale Sprachvariante

  • Angular 1
    • ES5
  • React
    • ES6/7/8 / flow
  • Angular 2
    • TypeScript
  • Web Components
    • Beliebig

Mobile Entwicklung

  • Angular 1
    • Ionic
  • React
    • React Native
  • Angular 2
    • Ionic 2
  • Web Components
    • %

Tech-Stack

  • Angular 1
    • JEE style, Batteries included
  • React
    • Stelle dir deinen eigenen Stack zusammen
    • Standard-Stacks existieren
  • Angular 2
    • Nachfolge von Angular 1
    • Jetzt mit Typinformationen (TypeScript)
  • Web Components
    • Nur der Browser
    • Alles andere ist deine Wahl
    • Standard-Stacks existieren NICHT

@mjackson

Fan-Clubs

  • Angular 1
    • Java-Entwickler
  • React
    • JavaScript-Entwickler
    • Freunde der funktionalen Programmierung
  • Angular 2
    • Angular 1-Entwickler???
  • Web Components
    • Google-Entwickler
    • zukünftig größere Firmen???

Coolness-Faktor

  • Angular 1
    • Unmodern
  • React
    • Der Hype
  • Angular 2
    • Der kommende Hype???
  • Web Components
    • Verwirrung

Wie man sich darüber lustig macht

  • Angular 1
    • JavaScript für Java-Leute
    • Magie für die man einen Magier (Berater) braucht
  • React
    • JavaScript-Müdigkeit: Viele Entscheidungen bei Techstack
    • Hipster-Framework
  • Angular 2
    • "Dieses mal machen wir alles richtig"!
  • Web Components
    • Nicht bedeutend genug, um darüber Witze zu machen

Investitions-Schutz

  • Angular 1
    • Rückwärtskompatibilität, Stabilität, Reife
    • Kein Einsatz bei Google
  • React
    • Rückwärtskompatibilität, Stabilität, Reife
    • Facebook basiert darauf
  • Angular 2
    • bleibt abzuwarten (Totgeburt?)
    • Einsatz in mehreren Projekten bei Google
  • Web Components
    • Alle Browser-Hersteller sind zumindest interessiert
    • Wird vanilla.js (hoffentlich)
    • Rest-Unsicherheit bleibt

Review

  1. Der Klassiker: Angular 1.x
  2. Von Antipatterns zu Best-Practices: React
  3. kgV (Vereinigungsmenge): Angular 2
  4. ggT (Schnittmenge): Web Components

Was hat das mit Embarc zu tun?

Vielen Dank!

Fragen / Diskussion

Oliver Zeigermann / @DJCordhose


Online-Version: http://bit.ly/1Ot8Mkg

Bonus Level

Elm: Hype 2016?

  • http://elm-lang.org/
  • Eine funkionale, reactive Sprache mit festgelegter Architektur
  • Statische Typisierung und keine Null-Typen
  • Ähnliche Ideen wie Redux/Flux für React, aber Architektur in die Sprache eingebaut
  • Browser als einzige Zielplattform
  • Wird durch Compiler nach JavaScript übersetzt
  • Nutzt ähnliche Ideen wie React für das Rendering