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

What's happening in frontend now?

koba04
August 20, 2015

What's happening in frontend now?

YAPC::Asia 2015 (08/21) @koba04

koba04

August 20, 2015
Tweet

More Decks by koba04

Other Decks in Programming

Transcript

  1. What's happening
    in frontend now?
    YAPC::Asia 2015 (8/21) @koba04

    View Slide

  2. koba04
    • Toru Kobayashi
    • Web application engineer
    • ≠ Frontend engineer
    • Single Page Application
    • Backbone -> Angular -> React

    View Slide

  3. Agenda
    • Ajax ʙ
    • Language
    • Web Application
    • Tools
    • Environment

    View Slide

  4. 2005 2015
    Ajax
    ECMAScript 5
    ECMAScript 2015

    View Slide

  5. Once upon a time…

    View Slide

  6. Good old web
    • Client requests HTML.
    • Server responses HTML.
    • Very simple
    • JavaScript doesn’t have to use.
    browser server
    GET /index.html
    index.html
    GET /about.html
    about.html

    View Slide

  7. Ajax!
    • Google Map
    • Asynchronous updates
    • We need JavaScript!
    • From Page to Application

    View Slide

  8. We need to write JavaScript…

    View Slide

  9. Language

    View Slide

  10. ECMAScript 5

    View Slide

  11. ECMAScript 5 (5.1)
    • “use strict”;
    • Object.create, Object.defineProperty
    • Array.prototype.(forEach, map, filter, reduce…)
    • JSON.parse, JSON.stringify
    • IE9ʙ
    2009
    2011(5.1)

    View Slide

  12. CoffeeScript

    View Slide

  13. CoffeeScript
    • Jeremy Ashkenas
    • CoffeeScript is a little language that compiles
    into JavaScript
    • Brevity and readability.
    • Rails 3.1 CoffeeScript
    • Some features are in ECMAScript 2015
    2010(1.0)

    View Slide

  14. class Parent
    class Hello extends Parent
    constructor: (@name) ->
    super()
    method: ->
    console.log @name
    hello = new Hello 'coffee'
    setTimeout(
    () => hello.method(),
    1000
    )

    View Slide

  15. Web Application

    View Slide

  16. jQuery

    View Slide

  17. jQuery
    • John Resig
    • DOM API is too low level
    • Browsers compatibility
    • jQuery Plugin
    • document.querySelector, Deferred(Promise)…
    2006

    View Slide

  18. $button.on(‘click’, function() {
    $.ajax(
    method: ‘GET’,
    url: ‘/api/item_list’
    )
    .done(function(items) {
    $ul = $(‘’);
    $.each(items, function(index, value) {
    $ul.append($(‘’ + value + ‘’));
    });
    $(‘.items’).append($ul);
    });
    });
    });

    View Slide

  19. View Slide

  20. Backbone.js

    View Slide

  21. Backbone.js
    • Jeremy Ashkenas
    • JavaScript MVC framework
    • Observer pattern
    • Depend on jQuery & underscore.js
    2010

    View Slide

  22. Backbone.Collection
    Backbone.View
    Backbone.Model
    Backbone.Model
    Backbone.Router
    Backbone.Event
    Backbone.History

    View Slide

  23. var View = Backbone.View.extend({
    events: { 'change .text': 'change' },
    initialize: function() {
    this.listenTo(this.model, 'change', this.render);
    },
    change: function() {
    this.model.set('text', this.$el.find('.text').val());
    },
    render: function() {
    this.$el.html(
    '' +
    this.model.get('text') +
    ‘'
    );
    return this;
    }
    });
    $('#app').append(
    new View({
    model: new Backbone.Model({text: ‘initial'})
    }).render().$el
    );

    View Slide

  24. Tools

    View Slide

  25. Node.js

    View Slide

  26. Node.js
    • Node.js is a platform built on V8
    • npm (173,476 packages)
    • server & cli
    • Event loop is that it runs under a single thread
    • Stream
    2009

    View Slide

  27. var http = require('http');
    var fs = require('fs');
    http.createServer(function(req, res) {
    fs.readFile('test.png', function(err, data) {
    if (err) return console.log(err);
    res.writeHead(200, {'Content-Type': 'image/png'});
    res.end(data);
    });
    }).listen(3000);
    // ↓
    http.createServer(function(req, res) {
    fs.createReadStream('test.png').pipe(res);
    }).listen(3001);
    Stream!

    View Slide

  28. Grunt

    View Slide

  29. Grunt.js
    • The JavaScript Task Runner
    • Not a build tool
    • Configurable
    • Yeomanɺassemble
    • Last release is 2014 May…
    • npm scripts
    2012

    View Slide

  30. CoffeeScript
    Port
    JavaScript
    watch
    JavaScript
    Running
    Webserver
    Minified
    JavaScript
    Output files
    Src files
    compile
    uglify
    exec

    View Slide

  31. module.exports = (grunt) ->
    watch:
    coffee:
    files: ["coffee/**/*.coffee"]
    tasks: ["js"]
    coffee:
    files:
    "static/js/app.js": [
    "coffee/app.coffee"
    "coffee/model/*.coffee"
    "coffee/collection/*.coffee"
    "coffee/view/*.coffee"
    ]
    concat:
    dev:
    src: [
    "bower_components/jquery/jquery.js"
    "bower_components/underscore/underscore.js"
    "bower_components/backbone/backbone.js"
    "static/js/app.js"
    ]
    dest: “static/js/all.js"

    View Slide

  32. Environment

    View Slide

  33. Chrome

    View Slide

  34. Chrome
    • Fast! Fast! Fast!
    • Webkit (version 28ʙ Blink)
    • Google V8 JavaScript Engine
    • JavaScriptCore(Safari), Chakra(IE),
    SpiderMonkey(Firefox)
    • Just in Time (JIT)
    2008

    View Slide

  35. Single Page Application

    View Slide

  36. Language

    View Slide

  37. TypeScript

    View Slide

  38. TypeScript
    • Microsoft
    • Typed superset of JavaScript
    • Class, Interface, Generics, Modules…
    • IDE Support
    • DefinitelyTyped
    2012

    View Slide

  39. class Greeter {
    greeting: string;
    constructor(message: string) {
    this.greeting = message;
    }
    greet(): string {
    return "Hello, " + this.greeting;
    }
    }
    var greeter = new Greeter("world");

    View Slide

  40. AST

    View Slide

  41. AST
    • Abstract Syntax Tree
    • SpiderMonkey Parser API
    • https://developer.mozilla.org/en-US/docs/
    Mozilla/Projects/SpiderMonkey/Parser_API
    • Esprima, Espree, Acorn, Babylon
    • ESTree, ShiftAST

    View Slide

  42. var answer = hoge * 7;
    VariableDeclarator
    Identifier
    answer
    Identifier
    hoge
    BinaryExpression
    *
    Literal
    7

    View Slide

  43. {
    "type": "Program",
    "body": [
    {
    "type": "VariableDeclaration",
    "declarations": [
    {
    "type": "VariableDeclarator",
    "id": {
    "type": "Identifier",
    "name": "answer"
    },
    "init": {
    "type": "BinaryExpression",
    "operator": "*",
    "left": {
    "type": "Identifier",
    "name": "hoge"
    },
    "right": {
    "type": "Literal",
    "value": 7,
    "raw": "7"
    }
    }
    }
    ],
    "kind": "var"
    }
    ]
    }
    var answer = hoge * 7;
    Parse
    by Esprima
    http://esprima.org/demo/parse.html

    View Slide

  44. Your JavaScript
    Espree
    Acorn

    AST
    Transpile
    Lint
    Analyze

    View Slide

  45. Libraries using AST
    • Linter - ESLint
    • Analyzer - istanbul, plato
    • Test - power-assert
    • Transpiler - browserify, babel

    View Slide

  46. Web Application

    View Slide

  47. https://blog.twitter.com/2012/improving-performance-on-twittercom

    View Slide

  48. Problems of SPA
    • SEO
    • Performance(initial load)
    • Maintenance
    browser server
    HTML
    JavaScript
    JSON Data

    View Slide

  49. Isomorphic
    (Universal JavaScript)

    View Slide

  50. Isomorphic
    • Share the code between client and server
    • → For maintenance
    • Initial render executes on the server
    • → For SEO and Performance
    • Frameworks have different approaches
    • Meteor, Rendr…

    View Slide

  51. browser server
    HTML included contents
    GET app.js
    GET /
    Node.js
    You can see the contents!
    Start to run your JavaScript on
    the browser
    GET /other/page
    Route on the browser

    View Slide

  52. The requirements of SPA
    • Binding JSON data to DOM
    • Routing by the browser History API
    • Browser side template engine
    • Data management
    • Memory management

    View Slide

  53. Angular.js

    View Slide

  54. Angular.js
    • Google
    • HTML enhanced for web apps.
    • 2way Data binding
    • Full stack (ng-http, ng-router…)
    • Very simple? (initially)
    • Angular 2 is completely different.
    release:2009
    1.0: 2012

    View Slide




  55. View Slide

  56. Tools

    View Slide

  57. SPA is…
    • Many assets files
    • JavaScript, CSS, template…
    • Hard to manage concatenating with Grunt
    • Increase a build time…

    View Slide

  58. gulp

    View Slide

  59. gulp
    • Stream base build system
    • Simple tasks pipe as stream
    • Programmable not configurable
    • Simple API
    • task, run, watch, src, dest
    2014

    View Slide

  60. CoffeeScript Stream
    pipe
    Src files
    Stream
    pipe
    gulp.src
    coffee
    Stream
    pipe
    Stream
    pipe
    gulp.dest
    Files
    dest files

    View Slide

  61. var gulp = require('gulp');
    var concat = require(‘gulp-concat');
    var coffee = require('gulp-coffee');
    var uglify = require('gulp-uglify');
    var coffeeFiles = './src/**/*.coffee';
    gulp.task('compile', function(){
    gulp.src(coffeeFiles)
    ����.pipe(coffee())
    .pipe(concat(‘app.js’))
    .pipe(uglify())
    .pipe(gulp.dest(‘dist’));
    });
    gulp.task(‘watch’, function() {
    gulp.watch(coffeeFiles, ['compile']);
    });

    View Slide

  62. browserify

    View Slide

  63. browserify
    • substack
    • Browserify lets you require('modules') in the
    browser by bundling up all of your dependencies.
    • No more concatenating which is depending on
    the order
    • It makes possible to share code between the
    browser and server.
    2013

    View Slide

  64. require(‘./foo’);
    require(‘./bar’);
    bundle.js
    app.js
    require(‘events’);
    require(‘react’);


    bar.js
    foo.js
    events
    react

    View Slide

  65. StatelessɾComposableɾ
    Stream

    View Slide

  66. Language

    View Slide

  67. ECMAScript 2015

    View Slide

  68. ECMAScript 2015
    • ECMAScript 6
    • JavaScript is more powerful.
    • Class, Modules, Arrow Function, Promise…
    • Destructuring assignment —
    • Browsers haven’t supported all features yet.
    2015 June

    View Slide

  69. http://kangax.github.io/compat-table/es6/

    View Slide

  70. class Person {
    method(val=“default”) {
    console.log(val);
    }
    method2(...array) {
    return new Promise((resolve, reject) => {
    setTimeout(() => {
    resolve(array.map(val => val * 2));
    }, 1000);
    });
    }
    }
    const person = new Person();
    person.method2(1, 2, 3).then(array => console.log(array));
    // [2, 4, 6]
    const user = {name: ‘Jim’, age: 20};
    const {name, age} = user;

    View Slide

  71. Babel

    View Slide

  72. Babel
    • Sebastian McKenzie
    • JavaScript transpiler
    • Use next generation JavaScript, today.
    • We can use ECMAScript 2015 now!
    • Stage option (default is stage2) ʙ 5.x
    2014

    View Slide

  73. TC39
    • Technical Committee 39
    • proposals into 4 stages
    • Stage 0 - Strawman
    • Stage 1 - Proposal
    • Stage 2 - Draft
    • Stage 3 - Candidate
    • Stage 4 - Finished

    View Slide

  74. https://github.com/tc39/ecma262

    View Slide

  75. Environment

    View Slide

  76. Service Workers

    View Slide

  77. Service Workers
    • JavaScript is more powerful.
    • Run independently of web pages.
    • Intercept Request
    • Offline / Cache
    • Background Sync
    • Push Notification
    • HTTPS Only

    View Slide

  78. // index.js
    if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('sw.js').then(
    sw => console.log('success'),
    err => console.log('error', err)
    );
    }
    // sw.js
    self.addEventListener('install', sw => console.log('oninstall'));
    self.addEventListener('fetch', ev => {
    if (ev.request.url.indexOf('test') !== -1) {
    ev.respondWith(new Response('Hello Service Worker'));
    }
    });

    View Slide

  79. View Slide

  80. Extensible Web

    View Slide

  81. Extensible Web
    • The Extensible Web Manifesto
    • https://extensiblewebmanifesto.org/
    • New low-level capabilities
    • Virtuous cycle
    • Prioritize efforts
    • Web Components ➜ Polymer

    View Slide

  82. Web Application

    View Slide

  83. React.js

    View Slide

  84. React.js
    • Facebook
    • Stateless Component
    • Mutability ➜ Complexity
    • Declarative programming
    • VIRTUAL DOM
    • Isomorphic!
    2014

    View Slide

  85. ᶃ USJHHFS
    BOFWFOU
    ᶄFWFOU
    ᶅVQEBUFBTUBUF
    ᶆQBTTFTBTUBUFBTQSPQT
    ᶇVQEBUF%0.
    CZQSPQT
    Stateful
    Stateless

    View Slide

  86. class App extends React.Component {
    constructor(...args) {
    super(args);
    this.state = {count: 0};
    }
    onClick() {
    this.setState({count: this.state.count + 1});
    }
    render() {
    const {count} = this.state;
    return (

    {count}
    click

    );
    }
    }
    React.render(, document.getElementById(‘app’));

    View Slide

  87. Flux

    View Slide

  88. Flux
    • Facebook
    • An application Architecture for Building User
    Interfaces
    • Unidirectional data flow

    View Slide

  89. Function Reactive
    Programming

    View Slide

  90. Functional Reactive
    Programming
    • Asynchronous data streams
    • A stream is a sequence of ongoing events
    ordered in time.
    • Mouse event, touch event, fetch response…
    • Observer and observable
    • Rx.js, Bacon.js, ECMAScript Observable(stage1)

    View Slide

  91. const $ = document.querySelector.bind(document);
    const plus = Rx.Observable.fromEvent($('#plus'), 'click');
    const minus = Rx.Observable.fromEvent($('#minus'), 'click');
    plus
    .map(1)
    .merge(minus.map(-1))
    .scan((acc, value) => acc + value)
    .subscribe(value => sum.textContent = value)
    ;

    View Slide

  92. click
    plus
    click
    minus
    click
    minus
    click
    plus
    click
    plus
    plus.map(1)
    minus.map(-1)
    scan((acc, value) => acc + value)
    -1
    1
    -1
    1 1 1
    0 -1 0 1

    View Slide

  93. Redux

    View Slide

  94. Redux
    • Inspired by Flux and Elm
    • Actions, A Store, Reducers
    • Reducers are pure functions
    • (state, action) => state
    • State is read-only
    • Single source of truth

    View Slide

  95. Reducer
    Component
    Reducer
    Component
    Store
    messages: [‘hello’]
    filter: ALL
    type: ADD_MESSAGE
    text: ‘hoge’
    messages =>
    messages.concat(action.text)
    filter =>
    action.filter
    Action
    type: FILTER
    text: UNREAD
    Action
    Reduce Reduce
    subscribe

    View Slide

  96. import { createStore } from 'redux';
    // Reducer
    function counter(state = 0, action) {
    switch (action.type) {
    case 'INCREMENT':
    return state + 1;
    case 'DECREMENT':
    return state - 1;
    default:
    return state;
    }
    }
    const store = createStore(counter);
    const unsubscribe = store.subscribe(() => console.log(store.getState()));
    store.dispatch({ type: 'INCREMENT' }); // 1
    store.dispatch({ type: 'INCREMENT' }); // 2
    store.dispatch({ type: 'DECREMENT' }); // 1
    unsubscribe();

    View Slide

  97. Conclusion

    View Slide

  98. Combination simple parts

    View Slide

  99. Unix philosophy
    • Small is beautiful.
    • Make each program do one thing well.
    • Build a prototype as soon as possible.
    • Choose portability over efficiency.
    • Store data in flat text files.
    • Use software leverage to your advantage.
    • Use shell scripts to increase leverage and portability.
    • Avoid captive user interfaces.
    • Make every program a Filter.

    View Slide

  100. cat access.log | cut -d: -f2 | sort | uniq -c

    View Slide

  101. data | your program | your program | output

    View Slide

  102. Thank you!

    View Slide