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

The Modern JavaScript Application

The Modern JavaScript Application

A talk at FOWA London

Andy Appleton

October 16, 2012
Tweet

More Decks by Andy Appleton

Other Decks in Technology

Transcript

  1. The Modern
    JavaScript Application
    Andy Appleton
    @appltn
    http://appleton.me

    View Slide

  2. JS is growing up
    we are doing more and more with it
    and we need more robust tools

    View Slide

  3. $(function(){
    $('.thing').on('click', function(ev){
    ev.preventDefault();
    var $link = $(this)
    $.get($link.attr('href'), function(data) {
    $link.fadeOut(function(){
    $('body').append(data);
    });
    });
    });
    });

    View Slide

  4. We can do better
    other languages have rich sets of
    tools and patterns, we can too!

    View Slide

  5. View Slide

  6. View Slide

  7. View Slide

  8. Models
    var Person = Backbone.Model.extend({
    sayName: function(){
    return this.get('name');
    }
    });
    var andy = new Person({
    name: 'Andy'
    });
    andy.sayName(); // => 'Andy'

    View Slide

  9. Collections
    var People = Backbone.Collection.extend({
    sayNames: function(){
    return this.map(function(model){
    return model.get('name');
    }).join(', ');
    }
    });

    View Slide

  10. Views
    var PersonView = Backbone.view.extend({
    render: function(){
    this.el.innerHTML = this.model.get('name');
    }
    });

    View Slide

  11. Tools

    View Slide

  12. View Slide

  13. View Slide

  14. Modules
    defined chunks of code which list
    their own dependencies

    View Slide

  15. Our Model From Earlier
    define(['path/to/dependency'],
    function(dependency){
    return Backbone.Model.extend({
    // Adding methods and properties
    });
    });

    View Slide

  16. Alternative Syntax
    define(function(require){
    var dependency = require('path/to/dep');
    return Backbone.Model.extend({
    // Adding methods and properties
    });
    });

    View Slide

  17. Structure & Conventions
    Split each module into a separate file

    View Slide

  18. View Slide

  19. The Requests!

    View Slide

  20. The Requests!
    The Humanity!

    View Slide

  21. r.js
    The RequireJS build tool

    View Slide

  22. $ node r.js -o config.js
    Concatenate & minify JS into a single file
    Concatenate & minify CSS via @import

    View Slide

  23. View Slide

  24. Templating

    View Slide

  25. View Slide

  26. http://handlebarsjs.com/

    View Slide

  27. var input = '{{ name }}';
    var templateFn = Handlebars.compile(input);
    var output = templateFn({ name: 'Andy' });
    // => 'Andy'

    View Slide

  28. var input = '
    \
    \
    {{title}}\
    by {{author}} on {{date}}\
    \
    {{content}}\
    \
    ';

    View Slide

  29. index.html
    <br/><article><br/><header><br/><h1>{{title}}</h1><br/>...etc<br/>
    my-view.js
    var input = $('#tpl-name').text();
    // ...compile etc

    View Slide

  30. https://github.com/SlexAxton/require-handlebars-plugin

    View Slide

  31. my-view.js
    define(function(require){
    var templateFn = require('hbs!path/to/tpl');
    // View now has access to compiled template
    // function
    });
    post-template.hbs


    {{title}}
    ...etc

    View Slide

  32. my-view.js
    define(function(require){
    var templateFn = require('hbs!path/to/tpl');
    // View now has access to compiled template
    // function
    });
    post-template.hbs


    {{title}}
    ...etc

    View Slide

  33. Handy Patterns

    View Slide

  34. Mediator
    A central object to publish and
    subscribe to global events

    View Slide

  35. var mediator = _.clone(Backbone.Events);
    mediator.on('eventname', function(args){
    console.log(args);
    });
    mediator.trigger('eventname', 'sausages');
    // => 'sausages'
    mediator.off('eventname');

    View Slide

  36. Model Caching
    sharing model instances across views

    View Slide

  37. define(function(require){
    var _cache = {},
    Model = Backbone.Model.extend();
    Model.create = function(opts) {
    if (opts.id && !_cache[opts.id]) {
    _cache[opts.id] = new Model(opts);
    }
    return _cache[opts.id];
    };
    return Model;
    });

    View Slide

  38. define(function(require){
    var _cache = {},
    Model = Backbone.Model.extend();
    Model.create = function(opts) {
    if (opts.id && !_cache[opts.id]) {
    _cache[opts.id] = new Model(opts);
    }
    return _cache[opts.id];
    };
    return Model;
    });

    View Slide

  39. define(function(require){
    var _cache = {},
    Model = Backbone.Model.extend();
    Model.create = function(opts) {
    if (opts.id && !_cache[opts.id]) {
    _cache[opts.id] = new Model(opts);
    }
    return _cache[opts.id];
    };
    return Model;
    });

    View Slide

  40. Unit Testing

    View Slide

  41. View Slide

  42. http://pivotal.github.com/jasmine/

    View Slide

  43. var Person = Backbone.Model.extend({
    sayName: function(){
    return this.get('name');
    }
    });
    Our Model From Earlier
    (again)

    View Slide

  44. describe('Person model', function(){
    describe('#sayName', function(){
    it('returns `name` attribute', function(){
    var person = new Person({ name: 'Andy' });
    expect(person.sayName()).toEqual('Andy');
    });
    });
    });

    View Slide

  45. View Slide

  46. Automation

    View Slide

  47. Grunt
    JS command line build tool
    http://gruntjs.com/

    View Slide

  48. View Slide

  49. +
    http://phantomjs.org/

    View Slide

  50. View Slide

  51. View Slide

  52. View Slide

  53. https://github.com/mrappleton/jasmine-examples

    View Slide

  54. View Slide

  55. Andy Appleton
    @appltn
    http://appleton.me

    View Slide