Javascript Design Patterns. AMD & commonJS. RequireJS Marc Torrent Vernetta
Javascript Design Patterns
A reusable solution that can be applied to commonly occurring problems in software design -in our case- in writing JavaScript Web application. What is a Pattern? Templates for how we solve problems - ones which can be used in quite a few different situations situations Addy Osmani
Three Main Benefits 1. Proven Solutions 2. Easily Reused 3. Expressive NOT EXACT SOLUTIONS SUPPORT DEVELOPERS
A Good Pattern 1. Solves a particular problem 2. Not an obvious solution 3. A proven described concept 4. Describe a relationship Display some recurring phenomenon: ❖ Fitness of purpose ❖ Usefulness ❖ Applicability
Antipatterns 1. Polluting global namespace 2. Strings to setTimeout and setInterval + eval() 3. Modify the Object prototype (very bad!!) 4. Javascript in an inline form 5. Use of document.write Knowledge for anti-patterns is critical for success !!!!
Antipatterns 1. Polluting global namespace 2. Strings to setTimeout and setInterval + eval() 3. Modify the Object prototype (very bad!!) 4. Javascript in an inline form 5. Use of document.write Knowledge for anti-patterns is critical for success !!!!
Design Pattern Types ➢ Creational ○ Factory Pattern ○ Constructor Pattern ○ Singleton Pattern ○ Prototype Pattern ➢ Structural ○ Module Pattern ○ Adapter Pattern ○ Decorator Pattern ○ Façade Pattern ○ Mixin Pattern ○ Flyweight Pattern ➢ Behavioral ○ Mediator Pattern ○ Observer Pattern - Classes - Objects
Creational Patterns
Constructor Pattern
Constructor Pattern - Prototype
Prototype Pattern
Sub-Classing
Mixin Pattern
Structural Patterns
Module Pattern - Object Literal
Module Pattern - IIFE
Module Pattern - Revealing
Behavioral Patterns
Observer Pattern - I SUBJECT STATE OBSERVERS LIST OBSERVER OBSERVER OBSERVER OBSERVER OBSERVER N O T I F Y CONCRETE SUBJECT CONCRETE OBSERVER UPDATEUPDATEUPDATEUPDATEUPDATE
Observer Pattern - II
Observer Pattern - III
Observer Pattern - IV
Observer Pattern - V
Observer Pattern - VI
Observer Pattern - VII
Publish/Subscribe Pattern - I PUBLISHER (SUBJECT) SUBSCRIBER EVENT AGGREGATOR SUBSCRIBER SUBSCRIBER
Publish/Subscribe Pattern II
Publish/Subscribe Pattern III
Publish/Subscribe Pattern IV
Mediator Pattern - I SUBJECT SUBSCRIBER EVENT AGGREGATOR SUBSCRIBER SUBSCRIBER MEDIATOR
Mediator Pattern - II
Mediator Pattern - III
Mediator Pattern - IV
Mediator Pattern - V
Modern Modular JavaScript Design Patterns
Module A Module B Module C Module N…... Application - Modular Application - Loosely Coupled - Dependency Control - Script Loader ➢ BROWSER: - Asynchronous Module Definition (AMD) - requireJS ➢ SERVER: - commonJS Dependency Control
AMD Modules ➢ Defining modules with dependencies to other modules. ➢ The module and dependencies can be asynchronously loaded. ➢ Both modules are asynchronous and highly flexible by nature ➢ Removes the tight coupling between code and module identity
AMD Modules Advantages ● Provides a clear proposal for how to approach defining flexible modules. ● Significantly cleaner than the present global namespace and <script> tag solutions many of us rely on. There's a clean way to declare stand-alone modules and dependencies they may have. ● Module definitions are encapsulated, helping us to avoid pollution of the global namespace. ● Most AMD loaders support loading modules in the browser without a build process. ● Provides a "transport" approach for including multiple modules in a single file. ● It's possible to lazy load scripts if this is needed.
AMD Modules - define vs require define( module_id /*optional*/, [dependencies] /*optional*/, definition function /*function for instantiating the module or object*/ ); require( [dependencies] /*required*/, complete function /*function for instantiating the dependecies*/ );
AMD Modules - define vs require define([“url_to_anonymous_module”, “named_module_id”], function(ModuleA, ModuleB) { function doCoolStuff(a) { ModuleA.cool(a, ModuleB.getCool()); } return { cool: doCoolStuff }; } ); require([“myModule”], function(moduleC) { var superCool = “super cool”; moduleC.cool(superCool); });
requireJS ➢ Library for working with AMD modules. Asynchronous script loader and dependency manager. ➢ Easy naming definition with a json configuration. Prepare non AMD modules for other AMD modules as its dependency management stays untouched. ➢ Optimization tool for bundling modules in one or many optimized, uglified and minimized module. ➢ With plugin extension for loading non JS scripts, like CSS, JSON, JSONP, etc… ➢ commonJS wrapper for styling AMD module loading with commonJS syntax and reducing verbosity.
requireJS and AMD require([dependencies], function(depA, depB, ...){}); requirejs([dependencies], function(depA, depB, ...){}); define() function and module definition remains exactly the same requirejs.config({ baseUrl: ‘path_to_where_scripts_are’, paths: { name_of_a_module: ‘relative_path_of_the_module’, other_module_name: ‘relative_path_of_other_module’ }, shim: { name_of_a_module: { exports: ‘Foo’, }, other_module_name: [“name_of_a_module”] } });
requireJS and HTML <html> <head></head> <body> <script data-main="js/app.js" src="js/require.js"></script> <script type=”text/javascript”> requirejs([“app”], function(app) { app.start(); }); </script> </body> </html>
commonJS modules ➢ Reusable piece of JavaScript which exports specific objects made available to any dependent code. ➢ Unlike AMD, there are typically no function wrappers around such modules. ➢ Two primary parts: a free variable named exports which contains the objects a module wishes to make available to other modules and a require function that modules can use to import the exports of other modules ➢ Only able to define objects which can be tedious to work with if we're trying to obtain constructors out of them ➢ Useful for Server side because it can use io, fs, system, etc..
commonJS in depth var libA = require(‘package/libA’), libB = require(‘package/libB’); function foo(){ libA.log( ‘hello world!’ ); } exports.foo = foo; exports.bar = function bar() { libB.myFunc(); }; var foobar = require(‘foobar’); foobar.foo(); foobar.bar();
requireJS with commonJS style define(function(require) { var moduleA = require(‘moduleA’), moduleB = require(‘moduleB’); function doCoolStuff(a) { moduleA.cool(a, moduleB.getCool()); } return { cool: doCoolStuff }; } );
Library App with RequireJS & AMD
Thanks for your attention! Leave your questions on the comments section
Workshop 2: JavaScript Design Patterns

Workshop 2: JavaScript Design Patterns

  • 1.
    Javascript Design Patterns. AMD& commonJS. RequireJS Marc Torrent Vernetta
  • 2.
  • 3.
    A reusable solutionthat can be applied to commonly occurring problems in software design -in our case- in writing JavaScript Web application. What is a Pattern? Templates for how we solve problems - ones which can be used in quite a few different situations situations Addy Osmani
  • 4.
    Three Main Benefits 1.Proven Solutions 2. Easily Reused 3. Expressive NOT EXACT SOLUTIONS SUPPORT DEVELOPERS
  • 5.
    A Good Pattern 1.Solves a particular problem 2. Not an obvious solution 3. A proven described concept 4. Describe a relationship Display some recurring phenomenon: ❖ Fitness of purpose ❖ Usefulness ❖ Applicability
  • 6.
    Antipatterns 1. Polluting globalnamespace 2. Strings to setTimeout and setInterval + eval() 3. Modify the Object prototype (very bad!!) 4. Javascript in an inline form 5. Use of document.write Knowledge for anti-patterns is critical for success !!!!
  • 7.
    Antipatterns 1. Polluting globalnamespace 2. Strings to setTimeout and setInterval + eval() 3. Modify the Object prototype (very bad!!) 4. Javascript in an inline form 5. Use of document.write Knowledge for anti-patterns is critical for success !!!!
  • 8.
    Design Pattern Types ➢Creational ○ Factory Pattern ○ Constructor Pattern ○ Singleton Pattern ○ Prototype Pattern ➢ Structural ○ Module Pattern ○ Adapter Pattern ○ Decorator Pattern ○ Façade Pattern ○ Mixin Pattern ○ Flyweight Pattern ➢ Behavioral ○ Mediator Pattern ○ Observer Pattern - Classes - Objects
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
    Module Pattern -Object Literal
  • 17.
  • 18.
  • 19.
  • 20.
    Observer Pattern -I SUBJECT STATE OBSERVERS LIST OBSERVER OBSERVER OBSERVER OBSERVER OBSERVER N O T I F Y CONCRETE SUBJECT CONCRETE OBSERVER UPDATEUPDATEUPDATEUPDATEUPDATE
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
    Publish/Subscribe Pattern -I PUBLISHER (SUBJECT) SUBSCRIBER EVENT AGGREGATOR SUBSCRIBER SUBSCRIBER
  • 28.
  • 29.
  • 30.
  • 32.
    Mediator Pattern -I SUBJECT SUBSCRIBER EVENT AGGREGATOR SUBSCRIBER SUBSCRIBER MEDIATOR
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
    Module A ModuleB Module C Module N…... Application - Modular Application - Loosely Coupled - Dependency Control - Script Loader ➢ BROWSER: - Asynchronous Module Definition (AMD) - requireJS ➢ SERVER: - commonJS Dependency Control
  • 39.
    AMD Modules ➢ Definingmodules with dependencies to other modules. ➢ The module and dependencies can be asynchronously loaded. ➢ Both modules are asynchronous and highly flexible by nature ➢ Removes the tight coupling between code and module identity
  • 40.
    AMD Modules Advantages ●Provides a clear proposal for how to approach defining flexible modules. ● Significantly cleaner than the present global namespace and <script> tag solutions many of us rely on. There's a clean way to declare stand-alone modules and dependencies they may have. ● Module definitions are encapsulated, helping us to avoid pollution of the global namespace. ● Most AMD loaders support loading modules in the browser without a build process. ● Provides a "transport" approach for including multiple modules in a single file. ● It's possible to lazy load scripts if this is needed.
  • 41.
    AMD Modules -define vs require define( module_id /*optional*/, [dependencies] /*optional*/, definition function /*function for instantiating the module or object*/ ); require( [dependencies] /*required*/, complete function /*function for instantiating the dependecies*/ );
  • 42.
    AMD Modules -define vs require define([“url_to_anonymous_module”, “named_module_id”], function(ModuleA, ModuleB) { function doCoolStuff(a) { ModuleA.cool(a, ModuleB.getCool()); } return { cool: doCoolStuff }; } ); require([“myModule”], function(moduleC) { var superCool = “super cool”; moduleC.cool(superCool); });
  • 43.
    requireJS ➢ Library forworking with AMD modules. Asynchronous script loader and dependency manager. ➢ Easy naming definition with a json configuration. Prepare non AMD modules for other AMD modules as its dependency management stays untouched. ➢ Optimization tool for bundling modules in one or many optimized, uglified and minimized module. ➢ With plugin extension for loading non JS scripts, like CSS, JSON, JSONP, etc… ➢ commonJS wrapper for styling AMD module loading with commonJS syntax and reducing verbosity.
  • 44.
    requireJS and AMD require([dependencies],function(depA, depB, ...){}); requirejs([dependencies], function(depA, depB, ...){}); define() function and module definition remains exactly the same requirejs.config({ baseUrl: ‘path_to_where_scripts_are’, paths: { name_of_a_module: ‘relative_path_of_the_module’, other_module_name: ‘relative_path_of_other_module’ }, shim: { name_of_a_module: { exports: ‘Foo’, }, other_module_name: [“name_of_a_module”] } });
  • 45.
    requireJS and HTML <html> <head></head> <body> <scriptdata-main="js/app.js" src="js/require.js"></script> <script type=”text/javascript”> requirejs([“app”], function(app) { app.start(); }); </script> </body> </html>
  • 46.
    commonJS modules ➢ Reusablepiece of JavaScript which exports specific objects made available to any dependent code. ➢ Unlike AMD, there are typically no function wrappers around such modules. ➢ Two primary parts: a free variable named exports which contains the objects a module wishes to make available to other modules and a require function that modules can use to import the exports of other modules ➢ Only able to define objects which can be tedious to work with if we're trying to obtain constructors out of them ➢ Useful for Server side because it can use io, fs, system, etc..
  • 47.
    commonJS in depth varlibA = require(‘package/libA’), libB = require(‘package/libB’); function foo(){ libA.log( ‘hello world!’ ); } exports.foo = foo; exports.bar = function bar() { libB.myFunc(); }; var foobar = require(‘foobar’); foobar.foo(); foobar.bar();
  • 48.
    requireJS with commonJSstyle define(function(require) { var moduleA = require(‘moduleA’), moduleB = require(‘moduleB’); function doCoolStuff(a) { moduleA.cool(a, moduleB.getCool()); } return { cool: doCoolStuff }; } );
  • 49.
    Library App withRequireJS & AMD
  • 55.
    Thanks for yourattention! Leave your questions on the comments section