Choosing the JavaScript framework for your next enterprise-grade app

Who am I?

Carl Bergenhem

Product Manager @KendoUI

Progress

@carlbergenhem

Who is Progress?

  • Progress is the leading .NET and JS UI component vendor
  • Home of Kendo UI and Telerik UI components!
  • Offering UI components for
    • jQuery, AngularJS & Angular, React, and Vue
    • ASP.NET Ajax/MVC/Core
    • WinForms, WPF, UWP (Win10) and Xamarin
  • Other tools include reports and testing - Fiddler & Test Studio
  • Creators of NativeScript
    • A JavaScript-based cross-platform native mobile app framework
    • Use JS, TS, Angular, or Vue to develop native mobile apps!

Agenda

  • What are we going to be covering for each library?
  • Angular
  • React
  • Vue
  • Ember
  • Aurelia
  • Q & A

Focus for each library

  • History
  • Overall usage
  • Core concepts
  • Getting started experience
  • Code samples

Angular

Angular - History

  • Created by Google
  • Originally released as AngularJS (for 1.x)
  • Initial release - September 14th, 2016
    • Preview, alpha, and beta versions existed in 2015
  • Angular initially referred to as AngularJS 2
  • Now it's just "Angular" for anything 2+
  • Version 3.x was skipped
  • Current version - 4.4.1 (5.x in beta)

Angular - Usage

27K+ stars on GitHub​

1.7 million NPM downloads per month

127,272 downloads of Augury, Developer Tools

Angular - Core Concepts

  • Components
  • Dependency Injection
  • Property bindings
  • TypeScript

Angular - Components

  • Everything in Angular is a component
    • The "root" of an app is a component, every view is a component
    • Angular therefore has a Component Tree
  • Data flows in (input property) and out (output property)
import { Component } from '@angular/core';
 
@Component({
  selector: 'my-app',
  template: `
    <h1>{{title}}</h1>
    <h2>My favorite hero is: {{myHero}}</h2>
    `
});

export class AppComponent {
  title = 'Tour of Heroes';
  myHero = 'Windstorm';
}

->  Can be used as  ->

<my-app></my-app>

Angular - Components

  • Every Component has a lifecycle managed by Angular
  • Angular offers lifecycle hooks that we can take advantage of
  • Each component has the following hooks
    • ngOnChanges()

    • ngOnInit()

    • ngDoCheck()

    • ngAfterContentInit()

    • ngAfterContentChecked()

    • ngAfterViewInit()

    • ngAfterViewChecked()

    • ngOnDestroy()

Angular - Property Bindings

Input properties and binding (one-way)

<img src="{{ myProfilePic }}">
<img [src]="myProfilePic">
<img bind-src="myProfilePic">
  1. The {{ ... }} syntax (interpolation) can be used if your property is a string
  2. Using [attribute] can be used in scenario when it's not a plain string
  3. bind-attribute is the same approach as #2
@Component({
  selector: 'my-app',
  template: `
    <h1>{{title}}</h1>
    <h2>My favorite hero is: {{myHero}}</h2>
    `
});

export class AppComponent {
  title = 'Tour of Heroes';
  myHero = 'Windstorm';
}

Angular - Property Bindings

Output properties are usually events emitted by the component

import { Component, EventEmitter, Input, Output } from '@angular/core';
 
@Component({
  selector: 'my-voter',
  template: `
    <h4>{{name}}</h4>
    <button (click)="vote(true)"  [disabled]="voted">Agree</button>
    <button (click)="vote(false)" [disabled]="voted">Disagree</button>
  `
})
export class VoterComponent {
  @Input()  name: string;
  @Output() onVoted = new EventEmitter<boolean>();
  voted = false;
 
  vote(agreed: boolean) {
    this.onVoted.emit(agreed);
    this.voted = true;
  }
}

Angular - Dependency Injection

Take this scenario (from the Angular Docs)

export class Car {
  public engine: Engine;
  public tires: Tires;
  public description = 'No DI';
 
  constructor() {
    this.engine = new Engine();
    this.tires = new Tires();
  }
}
  • Car constructor creates its own copies of Engine and Tires
  • This is very brittle if Engine or Tires needs to change
    • What about different Tire and Engines?
  • No flexibility with customizing a car, engine, or tire

Angular - Dependency Injection

Consider this change

export class Car {
  public description = 'No DI';
 
  constructor(public engine: Engine, public tires: Tires) { }
}
  • We are now consuming Engine and Tires, not creating them
  • This allows us to pass in instances, making things more flexible
let car = new Car(new Engine(), new Tires());
  • Which means we can now do:
class EngineNew {
  constructor(public cylinders: number) { }
}

let bigCylinders = 12;
let car = new Car(new EngineNew(bigCylinders), new Tires());

Angular - TypeScript

  • TypeScript is a typed superset of JavaScript that compiles to plain JS
  • Brings static typing and structuring to JavaScript
  • Intended to help build large and complex web applications
  • Angular standardized on TypeScript from the beginning
  • Plain/Vanilla JavaScript will work as well, but TS is everywhere

Angular - Getting Started

  • The easiest way to start is through the Angular CLI
  • Creating a new project is done through the CLI
  • This will set up a project with all the webpack settings we may need
# Install the Angular CLI
$ npm install -g @angular/cli

# Create our new app
$ ng new my-app

# Start our app
$ cd my-app
$ ng serve --open
  • This creates and launches "my-app" in a browser
  •                              --open specifically opens up a browser for us
ng-serve --open

Angular Sample Code

React

React - History

  • Created by Facebook
  • Initial release - March, 2013
  • Current version - 15.6.1
  • Re-write of the React core is underway - "React Fiber"
  • React 16 will use React Fiber
  • React 16 currently available as an RC
  • As of September 22nd, 2017 - licensed under MIT

React - Usage

75K+ stars on GitHub​

~5 million NPM downloads per month

720,848 downloads of React Developer Tools

React - Core Concepts

  • Virtual DOM
  • JSX
  • Components
  • Props
  • State
  • Lifecycle

React - Virtual DOM

  • The Virtual DOM is a node tree

    • Just like the DOM node tree

    • Lists elements & attributes & content as JS objects with properties

  • render() creates a node tree from the React components

    • It also updates the tree whenever data models are changed

  • React updates the real DOM in three steps

    1. ​​Whenever something has changed, the Virtual DOM will re-render
    2. The difference between old Virtual DOM and new Virtual DOM will be calculated
    3. The real DOM will be updated based on the changes

React - JSX

  • JSX is officially a XML-like syntax that is close, but not quite, HTML

  • It is actually JavaScript with HTML sprinkled in

    • "HTML in JS"

  • JSX is often just syntactical sugar for something like

<MyButton color="blue" shadowSize={2}>
  Click Me
</MyButton>
React.createElement(
  MyButton,
  { color: 'blue', shadowSize: 2 },
  'Click Me'
)

becomes

react.createElement(component, props, ...children)

React - Components

  • Components let you split the UI into independent, reusable pieces, and think about each piece in isolation.
  • Conceptually, components are like JavaScript functions. They accept arbitrary inputs (called "props") and return React elements describing what should appear on the screen.
  • To start, things are very simple, but can get more advanced
  • the render() function is key
function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}
class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

Older JavaScript

ES6

React - Props

  • Props are what give our components attributes and properties
  • These are what drives the core functionality of components
class ShoppingList extends React.Component {
  render() {
    return (
      <div className="shopping-list">
        <h1>Shopping List for {this.props.name}</h1>
        <ul>
          <li>Bananas</li>
          <li>Cereal</li>
          <li>Cabbage</li>
        </ul>
      </div>
    );
  }
}

// Example usage: <ShoppingList name="Carl" />

React - State

  • Each component has, and manages, its own state
  • The state can be extracted and set in our code
class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

React - Lifecycle

  • Mounting

    • constructor()

    • componentWillMount()

    • render()

    • componentDidMount()

  • Updating

    • componentWillReceiveProps()

    • shouldComponentUpdate()

    • componentWillUpdate()

    • render()

    • componentDidUpdate()

  • Unmounting

    • componentWillUnmount()

React - Getting Started

  • The easiest way to get started is through the create-react-app CLI

  • Using the CLI we can create a new app

  • This sets up everything we need to bootstrap a new application

# Install create-react-app - React's CLI
$ npm install -g create-react-app

# Create our app
$ create-react-app my-app

# Start our app
$ cd my-app
$ npm start
  •                     runs through a custom NPM script to kick off the app

npm start

React Sample Code

Vue.js

Vue - History

  • Created by Evan You
  • Initially intended as "little Angular"
  • First commit - June 27th, 2013
  • Has gone through two major releases, 1.x and 2.x
  • Often called "just" a view library
  • Current release - 2.4.4

Vue - Usage

67K+ stars on GitHub​

680+ thousand NPM downloads per month

258,207 downloads of Vue Developer Tools

Vue - Core Concepts

  • Vue - "The Progressive Framework"
  • Optional Support Libraries
  • Components
  • Single File Component

Vue - The Progressive Framework

  • Vue (core) is built to be minimalist and small
  • More features and functionality are added by other frameworks
  • "Progressive" comes from tacking on frameworks as-needed
    • Tackle this in stages as opposed to include the kitchen sink
  • This makes Vue simple to use initially - add complexity later
  • Vue can be dropped in and used anywhere - without builds
<script src="https://unpkg.com/vue/dist/vue.js"></script>

<div id="app">
  <p>{{ helloText }}</p>
</div>

new Vue({
  el: '#app',
  data: {
    helloText: 'Hello World!'
  }
})

Vue - Optional Support Libraries

Vue - Components

  • Components mean small, self-contained, and re-usable parts of an app
  • A  Vue component is a Vue instance with pre-defined options
// HTML
<ol>
  <my-item></my-item>
</ol>

// Component
Vue.component('my-item', {
  template: '<li>This is an item!</li>'
})
  • Components have a data attribute that adds objects to the reactivity system
  • Each object added to data will have its properties converted to getters/setters

Vue - Components

Vue - Single File Component

<!-- The actual view itself -->
<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
  </div>
</template>

<!-- Model just for this View -->
<script>
export default {
  name: 'hello',
  data () {
    return {
      msg: 'Welcome to Your Vue.js App'
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1, h2 {
  font-weight: normal;
}
</style>

Vue - Getting Started

Simple Start

<script src="https://unpkg.com/vue/dist/vue.js"></script>

Advanced Start

# Install vue-cli

$ npm install -g vue-cli

# Create a new project using the "webpack" template

$ vue init webpack my-app

# Install dependencies and run app
$ cd my-app
$ npm install
$ npm run dev

Vue Sample Code

Ember

Ember - History

  • Created by Yehuda Katz
  • Initial release - December 8th, 2011
  • A true MVVM / SPA framework
  • Huge refresh in 2.0 update
    • One-way data flow is now the default
    • Built-in tools for hot reloading / automatic browser refreshes
    • Standard lifecycle hooks for components
  • Current release - 2.13

Ember - Usage

18K+ stars on GitHub​

340+ thousand NPM downloads per month

69,383 downloads of Ember Developer Tools

Ember - Core Concepts

  • Router & Route Handlers
  • Templates
  • Models
  • Components

Ember - Router & Route Handlers

  • Ember uses routes as a way to represent the state of the application
  • Each URL has a connected route object that controls what to display
  • When a URL is entered by the user (manually, linked, etc.)
    • Ember Router takes the URL and maps it to a route handler
    • Route handler renders a template
    • Route handler loads a model available for the template

Ember - Templates

  • Templates are what builds our application's HTML
  • Everything the user interacts with is provided through a template
  • Ember uses HTMLBars
    • HTMLBars is a compiler for Handlebars
    • Designed to build a DOM instead of a string
    • This means that helpers have a context (parents, siblings, attributes)
  • Any Handlebars syntax is valid within Ember
<div>{{Intro}}, this is a simple Ember template!</div>

Ember - Models

  • Models represent persistent state
  • Models contain the data associated with the current state of the app
  • Every route has an associated model
  • Models are in charge of saving data to the storage of choice
  • Put simply: models are what provide our data

Ember - Components

  • Components in Ember are pretty much like the ones discussed so far
  • Consists of two parts
    1. a template written in HTMLBars
    2. a JS file defining the component's behavior
  • Components own their own data
  • Can be nested and communicate with their parents and children
    • Parent -> Child: bindings
    • Child -> Parent: events
  • Libraries like Polymer can be used with Ember

Ember - Getting Started

  • Easiest route to work with Ember is through the ember-cli
  • Creating new projects is a quick command
  • This will set up everything we need:
# Install the Ember CLI
$ npm install -g ember-cli

# Create our new app
$ ember new my-app

# Start our app
$ cd ember-quickstart
$ ember serve

Ember Sample Code

Aurelia

Aurelia - History

  • Created by Rob Eisenberg
  • First release - January 26th, 2015
  • "Next generation version of Durandal"
  • Also a true MVVM framework
  • Created after Rob left the Angular team to start Aurelia
  • Current release - 1.1.4

Aurelia - Usage

10K+ stars on GitHub​

25+ thousand NPM downloads per month

1,641 downloads of Aurelia Inspector

Aurelia - Core Concepts

  • Collection of Modules
  • Components
  • Binding
  • Templates

Aurelia - Collection of Modules

  • Aurelia aims to not be a monolithic framework
  • Broken down in to a collection of feature-oriented modules
    • Metadata, Dependency Injection, Templating, routing, etc.
  • Each module is written with JavaScript (ESNext) or TypeScript
  • Everything built on open web standards
    • Carefully follows the DOM standard
    • No abstraction over the DOM

Aurelia - Components

  • Aurelia components composed of two things
    1. View
    2. ViewModel
  • View is written with HTML and rendered in the DOM
  • ViewModel written in ES 2016 or TypeScript
  • Template engine and Dependency Injection "enforce" this pair
    • Also grants a life cycle to these components

Aurelia - Binding

  • Aurelia supports binding HTML and SVG attributes to JS expressions
  • Looks something like:
<!-- Basic Aurelia binding -->
<element attribute.command="expression"></element>

<!-- Actual implementation -->

<a href.bind="customUrl">Link Text</a>
  • Can also do custom commands for binding
<input type="text" value.bind="sampleField" />
<input type="text" value.two-way="sampleField" />

<a href.one-way="publicUrl">Link</a>
<a href.one-time="staticPublicUrl">Linky</a>

Aurelia - Templates

  • Aurelia takes advantage of the HTML <template> element
  • Uses the ${ ... } syntax for interpolation
    • This is standards-based ES2015 syntax
  • Tied to a ViewModel to supply data
<template>
  <p>
    ${arriving ? 'Hello' : 'Goodbye'}, ${name}!
  </p>
</template>

Aurelia - Getting Started

# Install instructions found on aurelia-cli GitHub page
$ au new my-app

$ cd my-app

# link the CLI to run commands with "au"
$ npm link aurelia-cli

$ au-run

Aurelia Sample Code

Summary

Angular

  • Backed by Google
  • Enjoying a large amount of adoption
    • Second-most usage of these libraries
    • Widely popular thanks to AngularJS 1.x
  • Great for larger groups of developers
    • TypeScript is widely used in the enterprise
    • Provides lots of structure in both app architecture and classes
    • Opinionated

React

  • Backed by Facebook
  • First to introduce the idea of a Virtual DOM
  • JSX 
    • Can divide teams - HTML in JS
    • Powerful language to create HTML
  • More freedom than Angular
  • Revamp from 15 - 16, React Fiber, resolves a lot of open items
    • Performance, file size, and more!
  • Now under the MIT license
    • No more license woes from patent clauses

Vue

  • "New" kid on the block
  • One of the fastest growing libraries
    • Has been growing at a very steady rate already
  • Very simple to get started with
  • Can be dropped in to existing applications
    • This means existing apps can be converted step-by-step
    • No need to start completely from scratch
    • Less conflicts with what already exists
  • Powerful by itself, even better with friends

Ember

  • The oldest of the libraries we've looked at today
  • Revamp from 1.x to 2.x modernized it quite a bit
  • A true "MVVM" framework
  • Models, Views, and ViewModels all play an important role 
  • Routes and Route Handlers are key to managing state
    • Routes drives models and templates
    • Components exist, but still driven through routes
  • Everything in Ember has a clear purpose

Aurelia

  • The "smallest" of the libraries that we covered today
  • Extremely passionate and engaging community
  • Picking up steam within the .NET world
  • A true MVVM framework
  • Very standards-based
    • ES6, HTML, TypeScript etc.
  • ​Fairly easy to pick up and add to projects

User Experience

Shameless Plug

  • These frameworks are great for building applications
  • But what about the user experience?
  • Building complex forms, data grids, charts, etc. is still hard
  • Kendo UI has over 70+ UI components
  • Supports

Q & A

Choosing the JavaScript framework for your next enterprise-grade app

By Carl Bergenhem

Choosing the JavaScript framework for your next enterprise-grade app

  • 2,549