Top Banner
Building Large Scale Javascript Application It's a little different than traditional JS
81

Building Large Scale Javascript Application

Aug 27, 2014

Download

Software

Anis Ahmad

In recent years a number of libraries for building large JavaScript applications has appeared. As we no longer need to battle DOM differences between browsers we can finally focus on building highly interactive front-end applications instead. But before we can do a good job with these new libraries we need unlearn our previous DOM-centric approach and need to be aware of good practices and patterns of developing modern javascript app.
It will start with jQuery based old style practices and try to discuss on how can we approach to a modular, decoupled, scalable application architecture. This slide was prepared in very short time for technical session series of Digital World 2014 (http://www.digitalworld.org.bd/technical-session). The event video is here - https://www.youtube.com/watch?v=Gpw7l27MUUc (slide was not properly covered in video).

It has taken inspiration, ideas (, even some contents) from the following sources -
* http://addyosmani.com/largescalejavascript/
* http://addyosmani.com/resources/essentialjsdesignpatterns/book/
* https://www.youtube.com/watch?v=vXjVFPosQHw
* https://www.youtube.com/watch?v=qWr7x9wk6_c
* https://speakerdeck.com/kimjoar/patterns-of-large-scale-javascript-applications-1
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Building Large Scale Javascript Application

Building Large ScaleJavascript Application

It's a little different than traditional JS

Page 2: Building Large Scale Javascript Application

Who are the target audience?What is Javascript?

I use JS to do form validation

Javascript is the interactive tool that I use for user intraction

I write the full app in JS

Page 3: Building Large Scale Javascript Application

What do we actually mean by Large Scale JavascriptApplication?

Large in size?

Large in complexity?

Large in developer count?

Page 4: Building Large Scale Javascript Application

Why do we care?The ability of browsers have increased

The load on the client, rather than on the server

High level of interaction

Page 5: Building Large Scale Javascript Application

What is the secret of building BIG things?

Page 6: Building Large Scale Javascript Application

Aircrafts are amazing architecture!

Page 7: Building Large Scale Javascript Application

How they made this crazy huge thing?

Page 8: Building Large Scale Javascript Application

The secret to building large apps is never build largeapps. Break up your applications into small pieces.

Then, assemble those testable, bite-sized pieces intoyour big– Justin Meyer

Page 9: Building Large Scale Javascript Application

Okay, Let's startAs we generally start

Page 10: Building Large Scale Javascript Application

We have a good main.js

function somethingGood() {    // Good code}

// few other functions ...

$( document ).ready(function() {    $('#aButton').onClick(function(e) {        // Do something    });

    // few event bindings ...});        

Page 11: Building Large Scale Javascript Application

But at the end, it become bad!

function somethingGood() {    // ## Bad code, full of mess ##}

// 39 strange functions with 40% repetation

$( document ).ready(function() {    $('#aButton').onClick(function(e) {        // Do something ## became 60 lines! ##    });

    // ## 33 bindings ## , some event may bound multiple times});        

Page 12: Building Large Scale Javascript Application

Let's break them down

Files++

Filesize--

Page 13: Building Large Scale Javascript Application

Lots of files...

Let’s Organise them

Page 14: Building Large Scale Javascript Application

By feature By Layer

Page 15: Building Large Scale Javascript Application

By feature By Layer

Page 16: Building Large Scale Javascript Application

Lets call them Modules

Page 17: Building Large Scale Javascript Application

Okay, but...

What is a Module?

Page 18: Building Large Scale Javascript Application

My Yahoo!

Page 19: Building Large Scale Javascript Application

Modules made it!

Page 20: Building Large Scale Javascript Application

Modules are (preferably) small, focused, purposefulportion of code that -

Page 21: Building Large Scale Javascript Application

Modules ... portion of code that -

Provides a specific feature

Page 22: Building Large Scale Javascript Application

Modules ... portion of code that -

Contains business logic

Page 23: Building Large Scale Javascript Application

Modules ... portion of code that -

Is decoupled (from other modules)

Page 24: Building Large Scale Javascript Application

Modules ... portion of code that -

Is reusable (context matters)

Page 25: Building Large Scale Javascript Application

Modules ... portion of code that -

Is testable

Page 26: Building Large Scale Javascript Application

A simple module looks like -

var MyModule = ( function( window, $ ) {  function aPrivateMethod() {    $('catchSomething').load('http://...');  }

  function myPublicMethod() {    privateMethod();    alert( 'my other method' );  }

  // explicitly return public methods when this object is instantiated  return {    someMethod : myPublicMethod  };} )( window, jQuery );        

Page 27: Building Large Scale Javascript Application

Module rules

Page 28: Building Large Scale Javascript Application

Module Rule #1

Never access the DOM outside the module

Page 29: Building Large Scale Javascript Application
Page 30: Building Large Scale Javascript Application

Module Rule #2

Don't Create Global variables

Page 31: Building Large Scale Javascript Application

Module Rule #3

Don’t Access Non-Native, Global objects

Page 32: Building Large Scale Javascript Application

Module Rule #4

Inject Dependencies

Page 33: Building Large Scale Javascript Application

Module Communationwith other modules

Page 34: Building Large Scale Javascript Application
Page 35: Building Large Scale Javascript Application
Page 36: Building Large Scale Javascript Application

Mediator PatternMediators are used when the communication between modules may be complex, but is still

well defined.

Page 37: Building Large Scale Javascript Application

Mediators and Modules

Page 38: Building Large Scale Javascript Application

Mediator publish/subscribe example

// example subscriber functionvar Subscriber = function ExampleSubscriber( myVariable ) {  console.log( myVariable );};

// example usagesvar myMediator = new Mediator();myMediator.subscribe( 'some event', Subscriber );myMediator.publish( 'some event', 'foo bar' ); // console logs "foo bar"        

Page 39: Building Large Scale Javascript Application
Page 40: Building Large Scale Javascript Application

Well defined Interfacing

Page 41: Building Large Scale Javascript Application

Dependencies

Dependency on other code/Globals

Dependency on other files

Dependency on third party libraries

Page 42: Building Large Scale Javascript Application

$('#my‐button').click(function() {    $.get('https://api.github.com', function(data) {        $('#res').html(data.emojis_url);    });});        

Closure cannot be reused

Closure cannot be tested

$.get and $('#res') using global object

Page 43: Building Large Scale Javascript Application

var downloadEmojis = function() {    $.get('https://api.github.com', function(data) {        $('#res').html(data.emojis_url);    });};

$('#my‐button').click(downloadEmojis);        

Difficult to test

$.get and $('#res') using global object

Page 44: Building Large Scale Javascript Application

var downloadEmojis = function(ajax, $el) {    ajax.get('https://api.github.com', function(data) {        $el.html(data.emojis_url);    });};

$('#my‐button').click(function() {    downloadEmojis($, $('#res'));});        

Now we can controle dependencies :)

Page 45: Building Large Scale Javascript Application

Dependency on other files/Modules

Page 46: Building Large Scale Javascript Application

Scripts behind this presentation

<script src="bower_components/bespoke.js/dist/bespoke.min.js"></script><script src="bower_components/bespoke‐keys/dist/bespoke‐keys.min.js"></script><script src="bower_components/bespoke‐touch/dist/bespoke‐touch.min.js"></script><script src="bower_components/bespoke‐bullets/dist/bespoke‐bullets.min.js"></script><script src="bower_components/bespoke‐scale/dist/bespoke‐scale.min.js"></script><script src="bower_components/bespoke‐hash/dist/bespoke‐hash.min.js"></script><script src="bower_components/bespoke‐progress/dist/bespoke‐progress.min.js"></script><script src="bower_components/bespoke‐state/dist/bespoke‐state.min.js"></script><script src="bower_components/prism/prism.js"></script><script src="bower_components/prism/components/prism‐php.min.js"></script><script src="scripts/main.js"></script>    

Page 47: Building Large Scale Javascript Application

How can we make it better?

AMD

COMMON.JS

Page 48: Building Large Scale Javascript Application

Let's see a little bit more about AMDUsing require.js

Page 49: Building Large Scale Javascript Application

Using require.js

Include Require JS

<script data‐main="scripts/main" src="scripts/require.js"></script>

Page 50: Building Large Scale Javascript Application

Using require.js

Configure Paths

require.config({    baseUrl: 'js/lib',    paths: {        jquery: 'jquery‐1.9.0'        parse : 'parse‐1.2.18.min',        underscore: 'underscore',        backbone: 'backbone',        marionette: 'backbone.marionette'    }});

Page 51: Building Large Scale Javascript Application

Using require.js

Define modules

define([    'app',    'marionette'], function(app, Marionette){

    return ExampleModule = app.module("Example", function(Example) {        this.startWithParent = false;

        this.addInitializer(function(){            console.log('Module:Example => initialized');            this.router = new Router({ controller: Controller });        });    });});

Page 52: Building Large Scale Javascript Application

Asynchronous loading

Page 53: Building Large Scale Javascript Application

On demand script loading

 if(teamProfile) {    // Load and show team profile    require(['views/TeamProfileView'], function(TeamProfileView) {        var teamInfo = { model : app.reqres.request('core:team', shortName) }        app.main.show(new TeamProfileView(teamInfo));    });}            

Page 54: Building Large Scale Javascript Application

Dependency on third party libraries

Page 55: Building Large Scale Javascript Application

http://bower.io/

Page 56: Building Large Scale Javascript Application

list dependencies in bower.json

// bower.json{    "dependencies": {        "angular": "~1.0.7",        "angular‐resource": "~1.0.7",        "jquery": "1.9.1"} }

Page 57: Building Large Scale Javascript Application

MV* Frameworks

Page 58: Building Large Scale Javascript Application

Seperation between Data and DOMM → Data | V → DOM | * → has many variations

Page 59: Building Large Scale Javascript Application

MVCController → Mediates inputs and manipulates the model

Page 60: Building Large Scale Javascript Application

MVPPresenter → all presentation logic is pushed to the presenter

Page 61: Building Large Scale Javascript Application

MVVMViewModel → exposes model so it can be easily managed and consumed

Page 62: Building Large Scale Javascript Application

How to select the right one?Why they are this huge in nymbers? :(

Page 63: Building Large Scale Javascript Application

Same todo app built around 70 times with different frameworks and approaches

Page 64: Building Large Scale Javascript Application
Page 65: Building Large Scale Javascript Application

Let's see how BackboneJS did it

Page 66: Building Large Scale Javascript Application

Todo Model

(function () {    app.Todo = Backbone.Model.extend({        // and ensure that each todo created has title and completed keys.        defaults: {            title: '',            completed: false        },

        toggle: function () {            this.save({                completed: !this.get('completed')            });        }    });})();

Page 67: Building Large Scale Javascript Application

Create a Todo

var todo = new app.Todo({  title: "Do something good!"});

Page 68: Building Large Scale Javascript Application

What about list of Todos?

var Todos = Backbone.Collection.extend({        model: app.Todo,

        // Filter down the list of all todo items that are finished.        completed: function () {            return this.filter(function (todo) {                return todo.get('completed');            });        },

        // Many other functions related to list ...    });

Collections

Page 69: Building Large Scale Javascript Application

Create a Todo list

var todoList = new Todos(    {title: 'Do something good'},    {title: 'Another Task'},    {title: 'This task is Done', completed: true},);            

Page 70: Building Large Scale Javascript Application

Who will create them actually?

collection.fetch(); // Pulls list of items from servercollection.create(); // Create new item in list

// Sync a modelmodel.fetch(); // Fetch an item from servermodel.save(); // Save changes to modelmodel.destroy(); // Delete a model            

Page 71: Building Large Scale Javascript Application

Template

<script type="text/template" id="item‐template">    <div class="view">        <input class="toggle" type="checkbox" <%= completed ? 'checked' : '' %>>        <label><%= title %></label>        <button class="destroy"></button>    </div>    <input class="edit" value="<%‐ title %>"></script>            

The DOM to render models or collection

Page 72: Building Large Scale Javascript Application

Views

app.TodoView = Backbone.View.extend({    tagName:  'li',    template: _.template($('#item‐template').html()),

    initialize: function () {        this.listenTo(this.model, 'change', this.render);        this.listenTo(this.model, 'visible', this.toggleVisible);    },

    render: function () {        this.$el.html(this.template(this.model.toJSON()));        return this;    }});            

Takes models, Render them, listning to events

Page 73: Building Large Scale Javascript Application

Views cont.

events: {    'click .toggle': 'toggleCompleted',    'dblclick label': 'edit'},

toggleCompleted: function () {    this.model.toggle();},

edit: function () {    this.$el.addClass('editing');    this.$input.focus();},        

Handling to DOM events and manipulate model

Page 74: Building Large Scale Javascript Application

Routers

var TodoRouter = Backbone.Router.extend({        routes: {            '*filter': 'setFilter',            'url/pattern': 'handlerFunction'            'url/pattern/:param': 'handlerFunction'        },

        setFilter: function (param) {            // Trigger a collection filter event            app.todos.trigger('filter');        }    });        

Handles the routing with url changes

Page 75: Building Large Scale Javascript Application

Start listning to url changes

app.TodoRouter = new TodoRouter();Backbone.history.start();    

Page 76: Building Large Scale Javascript Application

Url change? reload?... NO

http://the/app/url.com#a‐routehttp://the/app/url.com#another‐routehttp://the/app/url.com#a‐route/withParam/23    

Page 77: Building Large Scale Javascript Application

No more todayIt was a lot of things... ain't it?

Page 78: Building Large Scale Javascript Application

Wait... Do I really need aaall of these?Well, depends on your apps requirement

Page 79: Building Large Scale Javascript Application

Resource

http://superherojs.com/

Page 80: Building Large Scale Javascript Application

About us

[    {        "name": "Mohammad Emran Hasan",        "mail": "[email protected]",        "blog": "http://emranhasan.com"    },    {        "name": "Anis Uddin Ahmad",        "mail": "[email protected]",        "blog": "http://ajaxray.com"    }]          

Page 81: Building Large Scale Javascript Application

Questions?