Slide 1

Slide 1 text

Front-end Technologies

Slide 2

Slide 2 text

MATTEO RONCHI Senior Software Engineer

Slide 3

Slide 3 text

MODERN Front-End Development

Slide 4

Slide 4 text

HISTORY of Front-End Development

Slide 5

Slide 5 text

• Server-side generated HTML pages • Static CSS files • Most interactions trigger a page reload • Javascript is used only for UI interactions • Javascript is inlined inside the HTML code • Limited User Experience • Poor Developer Experience

Slide 6

Slide 6 text

CSS Sass Less PostCSS CSS Next CSS in JS

Slide 7

Slide 7 text

PACKET MANAGERS zipped packages CDN bower npm

Slide 8

Slide 8 text

TASK MANAGEMENT Grunt Gulp npm scripts Node JS modules

Slide 9

Slide 9 text

BUNDLERS Browserify Webpack JSPM Rollup

Slide 10

Slide 10 text

TOOLS & TRANSPILERS Babel Closure Compiler Typescript FlowType EsLint

Slide 11

Slide 11 text

JS FRAMEWORKS Jquery Backbone + Marionette Angular React Rx.js Cycle Angular 2

Slide 12

Slide 12 text

JS Javascript (1997) ECMAScript 5 (2009) ECMAScript 5.1 (2011) ES 2015 ES 2016 ES NEXT

Slide 13

Slide 13 text

• Javascript generated HTML pages • Compiled CSS • The page is never reloaded • Javascript is used for everything • Javascript files are compiled, minified and bundled • Improved User Experience • Rich Developer Experience

Slide 14

Slide 14 text

FROM DOCUMENTS To Components

Slide 15

Slide 15 text

Title Text

Some text about something

HYPERTEXT MARKUP LANGUAGE

Slide 16

Slide 16 text

$(document).ready(() => { $.ajax("my-url.php") .done((data) => { $("#my-title").text(data.title) $("#my-contents").text(data.contents) }) }) JQUERY

Slide 17

Slide 17 text

angular.module("app", []).directive("myPage", function($http) { return { scope: { myUrl: "@"} template: `<div> <h1>{{myTitle}}</h1> <p>{{myContents}}</p> </div>` link: function(scope) { $http.get(scope.myUrl).success((data) => { scope.myTitle = data.title scope.myContents = data.contents }) } } }) ANGULAR

Slide 18

Slide 18 text

class App extends React.Component { componentWillMount() { axios.get(this.props.myUrl).then(({ title, contents }) => { this.setState({ title, contents }) }) } render() { return ( <div> <h1>{this.state.title}</h1> <p>{this.state.contents}</p> </div> ) } } ReactDOM.render( <App myUrl="my-url.php" />, document.getElementById("root") ) REACT

Slide 19

Slide 19 text

COMPONENTS Based Architectures

Slide 20

Slide 20 text

ALL MODERN FRAMEWORKS ARE COMPONENT ORIENTED

Slide 21

Slide 21 text

1997 2016 Documents Page based architectures View based architectures Component based architectures

Slide 22

Slide 22 text

EVERYTHING IS A COMPONENT AN APPLICATION IS A TREE OF COMPONENTS

Slide 23

Slide 23 text

COMPONENTS Composable Encapsulated Reusable Easy to design

Slide 24

Slide 24 text

No content

Slide 25

Slide 25 text

PROS Maintained by Google Declarative syntax Encourage code maintainability Encourage Components reusability Built-in utilities to facilitate Unit tests Play nice with distributed teams Rich ecosystem of ready-to-use components Huge number of developers available

Slide 26

Slide 26 text

CONS Steep learning curve Complex scaffold Requires full control over the web page Old framework (6+years)

Slide 27

Slide 27 text

ANGULAR Basics

Slide 28

Slide 28 text

angular.module('myApp', []) APPLICATION BOOTSTRAP

Slide 29

Slide 29 text

angular.module('myApp', []) .service('myServiceName', function myServiceName() { // do something }) APPLICATION BOOTSTRAP

Slide 30

Slide 30 text

“You can think of a module as a container for the different elements of your app.”

Slide 31

Slide 31 text

A MODULE CAN BE The whole Application A single Component A collection of Components and/or services

Slide 32

Slide 32 text

function loadBeers($http) { return function (){ // load data from remote source return $http.then( function dataReceived(result)) { return result.data } } } angular.module('myApp') .factory('loadBeers', loadBeers) SERVICE - FACTORY - PROVIDER

Slide 33

Slide 33 text

–Angular Docs “Angular services are substitutable objects that are wired together using dependency injection. You can use services to organize and share code across your app. Lazily instantiated – Angular only instantiates a service when an application component depends on it. Singletons – Each component dependent on a service gets a reference to the single instance generated by the service factory.”

Slide 34

Slide 34 text

// JS function myCtrl($scope, loadBeers) { loadBeers().then( function beerLoaded(beers) { $scope.beers = beers }) } angular.module(‘myApp') .controller('myCtrl', myCtrl) // HTML

Slide 35

Slide 35 text

// JS function beer() { return { scope: { provider: '=' }, restrict: 'E', // E = Element, A = Attribute templateUrl: 'beerTemplate.html' } } angular.module('myApp').directive('beer', beer) // beerTemplate.html
  • {{provider.name}} - {{provider.price}}€
  • // main-view.html
    DIRECTIVES

    Slide 36

    Slide 36 text

    –Angular Docs “At a high level, directives are markers on a DOM element (such as an attribute, element name, comment or CSS class) that tell AngularJS's HTML compiler ($compile) to attach a specified behavior to that DOM element or even transform the DOM element and its children.”

    Slide 37

    Slide 37 text

    // DOM
    Hello JQuery!
    // JS $(function() { function toggle() { var isChecked = $('#toggleShowHide').is(':checked') $('#status').text('Status: ' + isChecked) var specialParagraph = $('#showText') if (isChecked) { specialParagraph.show() } else { specialParagraph.hide() } } $(‘#toggleShowHide’).change( function() { toggle() }) toggle() }) ANGULAR VS JQUERY

    Slide 38

    Slide 38 text

    // DOM
    Status: {{showText}}
    Hello Angular!
    ANGULAR VS JQUERY

    Slide 39

    Slide 39 text

    &

    Slide 40

    Slide 40 text

    WORKWAVE GPS Grunt based project’s automation Component based Architecture Component based routing Reactive data model (Rx.js)

    Slide 41

    Slide 41 text

    angular.module('wwLoaderLayer') .component('wwLoaderLayer', { template: ‘ww-loader-layer.html’, bindings: { showAtLoading: '@' }, controller($document, toggleLoaderLayer) { let modal let toggleLoaderLayerSubscriber const toggleLoaderLayerSignalReceived = (status) => { const action = status ? undefined : 'hide' modal.modal(action) } this.$onInit = () => { toggleLoaderLayerSubscriber = toggleLoaderLayer.subscribe(toggleLoaderLayerSignalReceived) } this.$postLink = () => { modal = $document.find('#loader-layer') } this.$onDestroy = () => { toggleLoaderLayerSubscriber.unsubscribe() } } }) ANGULAR COMPONENT

    Slide 42

    Slide 42 text

    RX.JS “An API for asynchronous programming with observable streams” [reactivex.io] Can be used to implement Unilateral data flow architectures Offers powerful operators to create really complex async workflows Very steep learning curve

    Slide 43

    Slide 43 text

    – reactivex.io “ReactiveX is a combination of the best ideas from the Observer pattern, the Iterator pattern, and functional programming”

    Slide 44

    Slide 44 text

    View User Interactions User Store A Store B Actions Web API Web Socket Screen Stream Updated Data Pass Data To Store Store

    Slide 45

    Slide 45 text

    No content

    Slide 46

    Slide 46 text

    ANGULAR TIMELINE AngularJS was originally developed in 2009 by Misko Hevery and Adam Abrons Misko Hevery started to work for Google in 2009 1st release of AngularJS: 1 developer, 3 weeks, 1000 loc AngularJS version 1.0 was released in 2012 by Google Angular version 2 was released in September 2016 after 2 years development

    Slide 47

    Slide 47 text

    ANGULAR FEATURES Optimized for both desktop and mobile Ahead of Time (AoT) compilation Incredible performances Native Reactive support (Rx.js)

    Slide 48

    Slide 48 text

    Basics

    Slide 49

    Slide 49 text

    export class MyService { getData() { return this.loadData.load(); } } @INJECTABLE

    Slide 50

    Slide 50 text

    import { Injectable } from `angular2/core`; @Injectable() export class MyService { constructor(private loadData:LoadData) {} getData() { return this.loadData.load(); } } @INJECTABLE

    Slide 51

    Slide 51 text

    import { Component } from '@angular/core'; @Component({ selector: 'hello', template: '

    Hello, {{name}}

    ' }) export class Hello { name: string; constructor() { this.name = 'World'; } } @COMPONENT

    Slide 52

    Slide 52 text

    import { Directive, HostListener } from '@angular/core'; @Directive({ selector: `[confirm]` }) export class ConfirmDirective { @HostListener(`click`, [`$event`]) confirmFirst(event: Event) { return window.confirm( `Are you sure you want to do this?` ); } } // Usage Visit another page @DIRECTIVE

    Slide 53

    Slide 53 text

    import { Component } from '@angular/core'; @Component({ selector: `product-price`, template: `

    Price: {{ price | currency }}

    ` }) export class ProductPrice { price: number = 99.99; } @PIPES

    Slide 54

    Slide 54 text

    import {Injectable} from '@angular/core'; import {Http, Response} from '@angular/http'; import {Observable} from 'rxjs'; import {Hero} from './hero'; @Injectable() export class LoadDataService { constructor(private http: Http) {} search(term: string): Observable { return this.http .get(`app/heroes/?name=${term}`) .map((r: Response) => { return r.json().data as Hero[] }); } } HTTP SERVICE

    Slide 55

    Slide 55 text

    In The Zone

    Slide 56

    Slide 56 text

    ANGULAR $DIGEST CYCLE AngularJS engine is built using a dirty checking algorithm. Application state is a single entity connected to every visual component and calculated every time a component mutates some data It’s very easy to trigger unwanted $digest cycles impacting performances Very difficult to debug

    Slide 57

    Slide 57 text

    ANGULAR 2 CHANGE DETECTION Based on ngZone Recalculate the components tree state after every async interaction (events, timers, observables..) Every component has its own Change Detector Component’s Change Detector is generated at runtime to improve performances Developers control how and when components are recalculated

    Slide 58

    Slide 58 text

    – ngBook2 “When one of the components change, no matter where in the tree it is, a change detection pass is triggered for the whole tree, from top to bottom.”

    Slide 59

    Slide 59 text

    CHANGE DETECTION TRAVELS TOP TO BOTTOM CD CD CD CD CD CD CD CD Change Detection Flow

    Slide 60

    Slide 60 text

    CHANGE DETECTION IS DEFINED AT COMPONENT LEVEL

    Slide 61

    Slide 61 text

    ANGULAR 2 CHANGE DETECTION Every component gets a change detector responsible for checking the bindings defined in its template ChangeDetectionStrategy: - default: update the component every time data changes - onPush: update the component only when its inputs change or the component requests to be updated

    Slide 62

    Slide 62 text

    CHANGE DETECTION (ONPUSH) WITH IMMUTABLE DATA CD CD CD CD CD CD Change Detection Flow

    Slide 63

    Slide 63 text

    CHANGE DETECTION (ONPUSH) WITH OBSERVABLES CD CD CD CD Change Detection Flow

    Slide 64

    Slide 64 text

    ANGULAR 2 CONS Typescript as preferred syntax Built upon Rx.js Very complex syntax

    Slide 65

    Slide 65 text

    No content

    Slide 66

    Slide 66 text

    PROS —Same pros of Angular— Maintained by Facebook Minimal API Surface Area Very easy to learn

    Slide 67

    Slide 67 text

    CONS Is not a framework Developers must have a strong knowledge of javascript automation tools Weird template syntax(at first glance)

    Slide 68

    Slide 68 text

    Basics

    Slide 69

    Slide 69 text

    PRESENTATIONAL COMPONENTS small reusable pure functions easy to test

    Slide 70

    Slide 70 text

    const Label = (props) =>

    {props.children}

    const Icon = (props) => { return ( {props.label} ) } const App = () =>
    Some label
    STATELESS FUNCTIONAL COMPONENTS

    Slide 71

    Slide 71 text

    CONTAINER COMPONENTS Context-aware stateful dynamic powerful

    Slide 72

    Slide 72 text

    class Toggle extends React.Component { constructor(props) { super(props) this.state = { enabled: false } this.toggle = this.toggle.bind(this) } toggle() { this.setState({ enabled: !this.state.enabled }) } render() { const cls = this.state.enabled ?'btn-success':'btn-danger' return ( {this.props.label} ) } } STATEFUL COMPONENTS

    Slide 73

    Slide 73 text

    Component Lifecycle

    Slide 74

    Slide 74 text

    class MyComponent extends React.Component { // Component Initialization constructor(props) {} // component ready to be mounted componentWillMount() {} // Props have changed componentWillReceiveProps(nextProps) {} // prevent rendering if not required shouldComponentUpdate(nextProps, nextState) {} // Prepare before rendering componentWillUpdate(nextProps, nextState) {} } COMPONENT LIFECYCLE

    Slide 75

    Slide 75 text

    class MyComponent extends React.Component { // create/update the component render() {} // Component DOM it’s been created componentDidMount() {} // Component DOM it’s been updated componentDidUpdate(prevProps, prevState) {} // cleanup before component destruction componentWillUnmount() {} } COMPONENT LIFECYCLE

    Slide 76

    Slide 76 text

    HIGHER ORDER Functions

    Slide 77

    Slide 77 text

    – Marijn Haverbeke (eloquent javascript) “Higher-order functions allow us to abstract over actions, not just values.”

    Slide 78

    Slide 78 text

    function applyVat(vat) { return (value) => ((vat + 100) / 100) * value } const applyVat22 = applyVat(22) console.log(applyVat22(100)) // print -> 122 function maybe(condition, action) { if (condition) { action() } } const action = (msg) => () => console.log(msg) maybe(true, action(`It works!`)) maybe(false, action(`Doesn't work!`)) // print -> It works! HOF

    Slide 79

    Slide 79 text

    From Higher Order Functions (TO) HIGHER ORDER COMPONENTS

    Slide 80

    Slide 80 text

    const Wrapped = () =>

    Wrapped Comp

    const wrapper = (Comp) => () => { return
    } const FinalComponent = wrapper(Wrapped) const App = () => { return (
    ) } SIMPLE HOC

    Slide 81

    Slide 81 text

    &
 WorkWave Unified UI

    Slide 82

    Slide 82 text

    WORKWAVE UNIFIED UI NodeJS based project’s automation Production bundle created with Webpack Unilateral data flow with redux Async sequences with redux-saga Online documentation Live styleguide

    Slide 83

    Slide 83 text

    WORKWAVE UNIFIED UI Three projects: - Components library - Services library - Unified UI

    Slide 84

    Slide 84 text

    WORKWAVE UNIFIED UI COMPONENTS LIBRARY Reusable independent components Themed Components Ad-hoc Theme engine CSS in JS styling (runtime generated CSS classes)

    Slide 85

    Slide 85 text

    WORKWAVE UNIFIED UI SERVICES LIBRARY Generic reusable services

    Slide 86

    Slide 86 text

    WORKWAVE UNIFIED UI Uses both library projects Support dynamic theming Client-server communication via WebSocket WorkWave SSO

    Slide 87

    Slide 87 text

    Live Styleguide UNIFIED UI

    Slide 88

    Slide 88 text

    THANKS! @CEF62