WorkWave Frontend Technologies

WorkWave Frontend Technologies

Internal presentation of technologies used in WorkWave projects

5171121655bc1a7cc89d16a7a3ce8885?s=128

Matteo Ronchi

January 25, 2017
Tweet

Transcript

  1. Front-end Technologies

  2. MATTEO RONCHI Senior Software Engineer

  3. MODERN Front-End Development

  4. HISTORY of Front-End Development

  5. • 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
  6. CSS Sass Less PostCSS CSS Next CSS in JS

  7. PACKET MANAGERS zipped packages CDN bower npm

  8. TASK MANAGEMENT Grunt Gulp npm scripts Node JS modules

  9. BUNDLERS Browserify Webpack JSPM Rollup

  10. TOOLS & TRANSPILERS Babel Closure Compiler Typescript FlowType EsLint

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

    Angular 2
  12. JS Javascript (1997) ECMAScript 5 (2009) ECMAScript 5.1 (2011) ES

    2015 ES 2016 ES NEXT
  13. • 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
  14. FROM DOCUMENTS To Components

  15. <div> <h1>Title Text</h1> <p>Some text about something</p> </div> HYPERTEXT MARKUP

    LANGUAGE
  16. <div> <h1 id="my-title"></h1> <p id="my-contents"></p> </div> <script type="text/javascript"> $(document).ready(() =>

    { $.ajax("my-url.php") .done((data) => { $("#my-title").text(data.title) $("#my-contents").text(data.contents) }) }) </script> JQUERY
  17. <div ng-app="app"> <my-page my-url="my-url.php"></my-page> </div> <script type="text/javascript"> 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 }) } } }) </script> ANGULAR
  18. <div id="root" /> <script type="text/javascript"> 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") ) </script> REACT
  19. COMPONENTS Based Architectures

  20. ALL MODERN FRAMEWORKS ARE COMPONENT ORIENTED

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

    based architectures
  22. EVERYTHING IS A COMPONENT AN APPLICATION IS A TREE OF

    COMPONENTS
  23. COMPONENTS Composable Encapsulated Reusable Easy to design

  24. None
  25. 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
  26. CONS Steep learning curve Complex scaffold Requires full control over

    the web page Old framework (6+years)
  27. ANGULAR Basics

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

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

    APPLICATION BOOTSTRAP
  30. “You can think of a module as a container for

    the different elements of your app.”
  31. A MODULE CAN BE The whole Application A single Component

    A collection of Components and/or services
  32. 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
  33. –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.”
  34. // JS function myCtrl($scope, loadBeers) { loadBeers().then( function beerLoaded(beers) {

    $scope.beers = beers }) } angular.module(‘myApp') .controller('myCtrl', myCtrl) // HTML <body ng-app="myApp"> <div ng-controller="myCtrl"> <ul> <li ng-repeat="beer in beers track by $index”> {{beer}} </li> </ul> </div> </body> CONTROLLERS
  35. // JS function beer() { return { scope: { provider:

    '=' }, restrict: 'E', // E = Element, A = Attribute templateUrl: 'beerTemplate.html' } } angular.module('myApp').directive('beer', beer) // beerTemplate.html <li>{{provider.name}} - {{provider.price}}€</li> // main-view.html <ul> <beer ng-repeat="beer in beers track by $index” provider="beer" ></beer> </ul> DIRECTIVES
  36. –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.”
  37. // DOM <input id="toggleShowHide" type="checkbox"> <div id="status"></div> <div id="showText">Hello JQuery!</div>

    // 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
  38. // DOM <body ng-init="showText = false"> <input ng-model="showText" type="checkbox" >

    <div>Status: {{showText}}</div> <div ng-show="showText"> Hello Angular! </div> <body> ANGULAR VS JQUERY
  39. &

  40. WORKWAVE GPS Grunt based project’s automation Component based Architecture Component

    based routing Reactive data model (Rx.js)
  41. 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
  42. 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
  43. – reactivex.io “ReactiveX is a combination of the best ideas

    from the Observer pattern, the Iterator pattern, and functional programming”
  44. View User Interactions User Store A Store B Actions Web

    API Web Socket Screen Stream Updated Data Pass Data To Store Store
  45. None
  46. 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
  47. ANGULAR FEATURES Optimized for both desktop and mobile Ahead of

    Time (AoT) compilation Incredible performances Native Reactive support (Rx.js)
  48. Basics

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

    @INJECTABLE
  50. import { Injectable } from `angular2/core`; @Injectable() export class MyService

    { constructor(private loadData:LoadData) {} getData() { return this.loadData.load(); } } @INJECTABLE
  51. import { Component } from '@angular/core'; @Component({ selector: 'hello', template:

    '<p>Hello, {{name}}</p>' }) export class Hello { name: string; constructor() { this.name = 'World'; } } @COMPONENT
  52. 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 <button type="button" (click)="visitOtherPage()" confirm>Visit another page</button> @DIRECTIVE
  53. import { Component } from '@angular/core'; @Component({ selector: `product-price`, template:

    `<p>Price: {{ price | currency }}</p>` }) export class ProductPrice { price: number = 99.99; } @PIPES
  54. 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<Hero[]> { return this.http .get(`app/heroes/?name=${term}`) .map((r: Response) => { return r.json().data as Hero[] }); } } HTTP SERVICE
  55. In The Zone

  56. 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
  57. 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
  58. – 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.”
  59. CHANGE DETECTION TRAVELS TOP TO BOTTOM CD CD CD CD

    CD CD CD CD Change Detection Flow
  60. CHANGE DETECTION IS DEFINED AT COMPONENT LEVEL

  61. 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
  62. CHANGE DETECTION (ONPUSH) WITH IMMUTABLE DATA CD CD CD CD

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

    Detection Flow
  64. ANGULAR 2 CONS Typescript as preferred syntax Built upon Rx.js

    Very complex syntax
  65. None
  66. PROS —Same pros of Angular— Maintained by Facebook Minimal API

    Surface Area Very easy to learn
  67. CONS Is not a framework Developers must have a strong

    knowledge of javascript automation tools Weird template syntax(at first glance)
  68. Basics

  69. PRESENTATIONAL COMPONENTS small reusable pure functions easy to test

  70. const Label = (props) => <h1>{props.children}</h1> const Icon = (props)

    => { return ( <i className="fa fa-anchor"> {props.label} </i> ) } const App = () => <div> <Label>Some label</Label> <Icon label="ready to sail" /> </div> STATELESS FUNCTIONAL COMPONENTS
  71. CONTAINER COMPONENTS Context-aware stateful dynamic powerful

  72. 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 ( <button className={‘btn ‘ + cls} onClick={this.toggle}> {this.props.label} </button> ) } } STATEFUL COMPONENTS
  73. Component Lifecycle

  74. 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
  75. 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
  76. HIGHER ORDER Functions

  77. – Marijn Haverbeke (eloquent javascript) “Higher-order functions allow us to

    abstract over actions, not just values.”
  78. 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
  79. From Higher Order Functions (TO) HIGHER ORDER COMPONENTS

  80. const Wrapped = () => <h1>Wrapped Comp</h1> const wrapper =

    (Comp) => () => { return <div><Comp /></div> } const FinalComponent = wrapper(Wrapped) const App = () => { return ( <div> <FinalComponent /> </div> ) } SIMPLE HOC
  81. &
 WorkWave Unified UI

  82. 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
  83. WORKWAVE UNIFIED UI Three projects: - Components library - Services

    library - Unified UI
  84. WORKWAVE UNIFIED UI COMPONENTS LIBRARY Reusable independent components Themed Components

    Ad-hoc Theme engine CSS in JS styling (runtime generated CSS classes)
  85. WORKWAVE UNIFIED UI SERVICES LIBRARY Generic reusable services

  86. WORKWAVE UNIFIED UI Uses both library projects Support dynamic theming

    Client-server communication via WebSocket WorkWave SSO
  87. Live Styleguide UNIFIED UI

  88. THANKS! @CEF62