KEMBAR78
Dependency Management with RequireJS | PDF
DEPENDENCY	
  	
  
MANAGEMENT	
  
with	
  RequireJS	
  
HELLO	
  
                              my	
  name	
  is	
  


         Aaron Hardy
                                    ·∙	
  
                   @AARONIUS	
  	
  	
  	
  	
  AARONHARDY.COM	
  


So8ware	
  Engineer,	
  Adobe	
  Digital	
  MarkeAng	
  Suite	
  
     We	
  enable	
  management,	
  measurement,	
  execu1on,	
  and	
  
       op1miza1on	
  of	
  digital	
  adver1sing	
  and	
  marke1ng.	
  
What	
  is	
  dependency	
  management?	
  
Loading…	
  
The	
  right	
  code.	
  
In	
  the	
  right	
  order.	
  
At	
  the	
  right	
  Ame.	
  
At	
  the	
  right	
  speed.	
  
	
  
(oh	
  and	
  btw,	
  make	
  it	
  easy)	
  
	
  
	
  
Old-­‐school	
  Dependency	
  Management	
  
What	
  are	
  the	
  dependencies	
  here?	
  
<script     src="script3.js"></script>
<script     src="script1.js"></script>
<script     src="script13.js"></script>
<script     src="script7.js"></script>
<script     src="script6.js"></script>
<script     src="script12.js"></script>
<script     src="script4.js"></script>
<script     src="script11.js"></script>
<script     src="script5.js"></script>
<script     src="script9.js"></script>
<script     src="script8.js"></script>
<script     src="script10.js"></script>
<script     src="script2.js"></script>
Old-­‐school	
  Dependency	
  Management	
  
What	
  is	
  a	
  module?	
  
A	
  structure	
  used	
  to	
  encapsulate	
  methods	
  and	
  aTributes	
  to	
  avoid	
  
polluAng	
  the	
  global	
  namespace.	
  
var Calculator = (function(){
  function funkify(num) {
    return num * Math.random() / Math.random();
  }

   function add(a, b, getFunky){
     var sum = a + b;
     return getFunky ? funkify(sum) : sum;
   }

  return {
     add:add
  };
})();
What	
  is	
  AMD?	
  
Asynchronous	
  module	
  definiAon.	
  	
  	
  
•  A	
  mechanism	
  for	
  defining	
  modules	
  such	
  that	
  the	
  module	
  and	
  its	
  
   dependencies	
  can	
  be	
  asynchronously	
  loaded.	
  
•  Suited	
  for	
  a	
  browser	
  environment.	
  
•  Generally	
  used	
  in	
  tandem	
  with	
  an	
  AMD	
  loader.	
  
What	
  is	
  RequireJS?	
  
A	
  JavaScript	
  file	
  and	
  module	
  loader.	
  Capable	
  of	
  loading	
  modules	
  
defined	
  in	
  the	
  AMD	
  format	
  and	
  their	
  dependencies.	
  
	
  
Not	
  the	
  only	
  AMD	
  loader	
  (but	
  unofficially	
  the	
  most	
  popular)	
  
•  curl.js	
  
•  lsjs	
  
•  dojo	
  
•  mootools	
  
	
  
Open	
  source.	
  New	
  BSD	
  or	
  MIT	
  licensed.	
  
Defining	
  a	
  module 	
  	
  
/js/book.js	
  
define({
  title: "My Sister's Keeper",
  publisher: "Atria"
});
RequesAng	
  dependencies	
  
/js/bookshelf.js	
  
define([
  'book'
], function(book) {
  return {
     listBook: function() {
       alert(book.title);
     }
  };
});
Se]ng	
  up	
  your	
  app	
  
/index.html	
  
<!DOCTYPE html>
<html>
  <head>
    <title>RequireJS Example</title>
    <script data-main="js/main"
         src="js/libs/require.js"></script>
  </head>
  <body/>
</html>
Se]ng	
  up	
  your	
  app	
  
/js/main.js	
  
require([
  'bookshelf'
], function(bookshelf) {
  bookshelf.listBook();
});
define()	
  vs.	
  require()	
  
define()	
  completes	
  three	
  steps:	
  
1.  Loads	
  the	
  specified	
  dependencies	
  
2.  Calls	
  the	
  callback	
  funcAon	
  
3.  Registers	
  the	
  return	
  value	
  from	
  the	
  callback	
  funcAon	
  

require()	
  only	
  performs	
  #1	
  and	
  #2.	
  
DEMO	
  
hTp://code.aaronhardy.com/require-­‐literal	
  
Defining	
  a	
  constructor	
  module 	
  	
  
/js/book.js	
  
define(function() {
  var Book = function(title, publisher) {
     this.title = title;
     this.publisher = publisher;
  };
  return Book;
});
Using	
  a	
  constructor	
  module 	
  	
  
/js/bookshelf.js	
  
define([
  'book'
], function(Book) {
  var books = [
     new Book('A Tale of Two Cities', 'Chapman & Hall'),
     new Book('The Good Earth', 'John Day')
  ];

  return {
     listBooks: function() {
       for (var i = 0, ii = books.length; i < ii; i++) {
         alert(books[i].title);
       }
     }
  };
});
DEMO	
  
hTp://code.aaronhardy.com/require-­‐constructor	
  
Configuring	
  RequireJS	
  
/js/main.js	
  
require.config({
  baseUrl: '/another/path',
  paths: {
    'myModule': 'dirA/dirB/dirC/dirD/myModule’,
    'templates': '../templates',
    'text': 'libs/text'
  }
});

require([
  'bookshelf'
], function(bookshelf) {
  bookshelf.listBook();
});
Shimming	
  non-­‐AMD	
  libraries	
  
/js/main.js	
  
require.config({
  paths: {
     jquery: 'libs/jquery',
     underscore': 'libs/lodash',
     backbone: 'libs/backbone',
  },
  shim: {
     backbone: {
        deps: ['underscore', 'jquery'],
        exports: 'Backbone'
     },
     underscore: {
        exports: '_’
     }
  }
});
Using	
  shimmed	
  libraries	
  
/js/book.js	
  
define([
  'backbone'
], function(Backbone) {
  return Backbone.Model.extend({
     defaults: {
       genre: 'historical'
     }
  })
});
RequireJS	
  plugins	
  
Used	
  for	
  loading	
  and/or	
  transforming	
  different	
  types	
  of	
  
dependencies	
  either	
  at	
  run-­‐Ame	
  or	
  compile-­‐Ame.	
  
•  text	
  –	
  Loads	
  files	
  as	
  plain	
  text	
  
•  i18n	
  –	
  InternaAonalizaAon	
  
•  cs	
  –	
  Loads	
  and	
  compiles	
  CoffeeScript	
  
•  font	
  –	
  Loads	
  web	
  fonts	
  
•  image	
  –	
  Loads	
  image	
  files	
  
•  json	
  –	
  Loads	
  and	
  parses	
  JSON	
  
•  mdown	
  –	
  Loads	
  and	
  compiles	
  Markdown	
  
	
  
and	
  many	
  more…	
  

	
  
RequireJS	
  text	
  plugin	
  usage	
  
/js/main.js	
  
require.config({
  'paths': {
    'jquery': 'libs/jquery',
    'templates': '../templates',
    'text': 'libs/text’
  }
});

require([
  'jquery',
  'text!templates/book.tpl.html'
], function($, template) {
  $(document).ready(function() {
    $('body').html(template);
  });
});
DEMO	
  
hTp://code.aaronhardy.com/require-­‐template	
  
CondiAonal	
  dependencies	
  
require([
  'modernizr'
], function(Modernizr) {
  var drawCircle = function() { … };

  if (Modernizr.canvas) {
    drawCircle();
  } else {
    require(['excanvas'], drawCircle);
  }
});
Errbacks	
  
requirejs.config({
  enforceDefine: true,
  paths: {
    jquery: 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min'
  }
});

require(['jquery'], function ($) {
  //Do something with $ here
}, function (err) {
  var failedId = err.requireModules && err.requireModules[0],
  if (failedId === 'jquery') {
    requirejs.undef(failedId);

      requirejs.config({
        paths: {
          jquery: 'local/jquery'
        }
      });

      require(['jquery'], function () {});
  }
});
OpAmizaAon	
  
ConcatenaAon	
  and	
  minificaAon	
  
r.js	
  –	
  RequireJS	
  opAmizer	
  able	
  to	
  run	
  in	
  Node	
  or	
  Rhino	
  (Java)	
  
DEMO	
  
hTp://code.aaronhardy.com/require-­‐opAmizaAon	
  
node	
  libs/r.js	
  -­‐o	
  baseUrl=.	
  name=main	
  out=main-­‐built.js	
  
OpAmizaAon	
  using	
  almond	
  
In	
  producAon,	
  replaces	
  RequireJS	
  and	
  is	
  bundled	
  with	
  built	
  file.	
  
•  1K	
  (almond)	
  vs	
  14K	
  (RequireJS)	
  
•  Avoids	
  two	
  separate,	
  sequenAal	
  HTTP	
  requests	
  
	
  
Biggest	
  limitaAon:	
  
•  No	
  dynamic	
  loading;	
  all	
  dependencies	
  must	
  be	
  in	
  the	
  same	
  file	
  or	
  
      loaded	
  beforehand	
  


	
  
DEMO	
  
hTp://code.aaronhardy.com/require-­‐almond	
  
node	
  libs/r.js	
  -­‐o	
  baseUrl=.	
  name=libs/almond	
  include=main	
  out=main-­‐built.js	
  
THANK	
  YOU!	
  
@aaronius	
  ·∙	
  aaronhardy.com	
  

Dependency Management with RequireJS

  • 1.
    DEPENDENCY     MANAGEMENT   with  RequireJS  
  • 2.
    HELLO   my  name  is   Aaron Hardy ·∙   @AARONIUS          AARONHARDY.COM   So8ware  Engineer,  Adobe  Digital  MarkeAng  Suite   We  enable  management,  measurement,  execu1on,  and   op1miza1on  of  digital  adver1sing  and  marke1ng.  
  • 3.
    What  is  dependency  management?   Loading…   The  right  code.   In  the  right  order.   At  the  right  Ame.   At  the  right  speed.     (oh  and  btw,  make  it  easy)      
  • 4.
    Old-­‐school  Dependency  Management   What  are  the  dependencies  here?   <script src="script3.js"></script> <script src="script1.js"></script> <script src="script13.js"></script> <script src="script7.js"></script> <script src="script6.js"></script> <script src="script12.js"></script> <script src="script4.js"></script> <script src="script11.js"></script> <script src="script5.js"></script> <script src="script9.js"></script> <script src="script8.js"></script> <script src="script10.js"></script> <script src="script2.js"></script>
  • 5.
  • 6.
    What  is  a  module?   A  structure  used  to  encapsulate  methods  and  aTributes  to  avoid   polluAng  the  global  namespace.   var Calculator = (function(){ function funkify(num) { return num * Math.random() / Math.random(); } function add(a, b, getFunky){ var sum = a + b; return getFunky ? funkify(sum) : sum; } return { add:add }; })();
  • 7.
    What  is  AMD?   Asynchronous  module  definiAon.       •  A  mechanism  for  defining  modules  such  that  the  module  and  its   dependencies  can  be  asynchronously  loaded.   •  Suited  for  a  browser  environment.   •  Generally  used  in  tandem  with  an  AMD  loader.  
  • 8.
    What  is  RequireJS?   A  JavaScript  file  and  module  loader.  Capable  of  loading  modules   defined  in  the  AMD  format  and  their  dependencies.     Not  the  only  AMD  loader  (but  unofficially  the  most  popular)   •  curl.js   •  lsjs   •  dojo   •  mootools     Open  source.  New  BSD  or  MIT  licensed.  
  • 9.
    Defining  a  module     /js/book.js   define({ title: "My Sister's Keeper", publisher: "Atria" });
  • 10.
    RequesAng  dependencies   /js/bookshelf.js   define([ 'book' ], function(book) { return { listBook: function() { alert(book.title); } }; });
  • 11.
    Se]ng  up  your  app   /index.html   <!DOCTYPE html> <html> <head> <title>RequireJS Example</title> <script data-main="js/main" src="js/libs/require.js"></script> </head> <body/> </html>
  • 12.
    Se]ng  up  your  app   /js/main.js   require([ 'bookshelf' ], function(bookshelf) { bookshelf.listBook(); });
  • 13.
    define()  vs.  require()   define()  completes  three  steps:   1.  Loads  the  specified  dependencies   2.  Calls  the  callback  funcAon   3.  Registers  the  return  value  from  the  callback  funcAon   require()  only  performs  #1  and  #2.  
  • 14.
  • 15.
    Defining  a  constructor  module     /js/book.js   define(function() { var Book = function(title, publisher) { this.title = title; this.publisher = publisher; }; return Book; });
  • 16.
    Using  a  constructor  module     /js/bookshelf.js   define([ 'book' ], function(Book) { var books = [ new Book('A Tale of Two Cities', 'Chapman & Hall'), new Book('The Good Earth', 'John Day') ]; return { listBooks: function() { for (var i = 0, ii = books.length; i < ii; i++) { alert(books[i].title); } } }; });
  • 17.
  • 18.
    Configuring  RequireJS   /js/main.js   require.config({ baseUrl: '/another/path', paths: { 'myModule': 'dirA/dirB/dirC/dirD/myModule’, 'templates': '../templates', 'text': 'libs/text' } }); require([ 'bookshelf' ], function(bookshelf) { bookshelf.listBook(); });
  • 19.
    Shimming  non-­‐AMD  libraries   /js/main.js   require.config({ paths: { jquery: 'libs/jquery', underscore': 'libs/lodash', backbone: 'libs/backbone', }, shim: { backbone: { deps: ['underscore', 'jquery'], exports: 'Backbone' }, underscore: { exports: '_’ } } });
  • 20.
    Using  shimmed  libraries   /js/book.js   define([ 'backbone' ], function(Backbone) { return Backbone.Model.extend({ defaults: { genre: 'historical' } }) });
  • 21.
    RequireJS  plugins   Used  for  loading  and/or  transforming  different  types  of   dependencies  either  at  run-­‐Ame  or  compile-­‐Ame.   •  text  –  Loads  files  as  plain  text   •  i18n  –  InternaAonalizaAon   •  cs  –  Loads  and  compiles  CoffeeScript   •  font  –  Loads  web  fonts   •  image  –  Loads  image  files   •  json  –  Loads  and  parses  JSON   •  mdown  –  Loads  and  compiles  Markdown     and  many  more…    
  • 22.
    RequireJS  text  plugin  usage   /js/main.js   require.config({ 'paths': { 'jquery': 'libs/jquery', 'templates': '../templates', 'text': 'libs/text’ } }); require([ 'jquery', 'text!templates/book.tpl.html' ], function($, template) { $(document).ready(function() { $('body').html(template); }); });
  • 23.
  • 24.
    CondiAonal  dependencies   require([ 'modernizr' ], function(Modernizr) { var drawCircle = function() { … }; if (Modernizr.canvas) { drawCircle(); } else { require(['excanvas'], drawCircle); } });
  • 25.
    Errbacks   requirejs.config({ enforceDefine: true, paths: { jquery: 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min' } }); require(['jquery'], function ($) { //Do something with $ here }, function (err) { var failedId = err.requireModules && err.requireModules[0], if (failedId === 'jquery') { requirejs.undef(failedId); requirejs.config({ paths: { jquery: 'local/jquery' } }); require(['jquery'], function () {}); } });
  • 26.
    OpAmizaAon   ConcatenaAon  and  minificaAon   r.js  –  RequireJS  opAmizer  able  to  run  in  Node  or  Rhino  (Java)  
  • 27.
    DEMO   hTp://code.aaronhardy.com/require-­‐opAmizaAon   node  libs/r.js  -­‐o  baseUrl=.  name=main  out=main-­‐built.js  
  • 28.
    OpAmizaAon  using  almond   In  producAon,  replaces  RequireJS  and  is  bundled  with  built  file.   •  1K  (almond)  vs  14K  (RequireJS)   •  Avoids  two  separate,  sequenAal  HTTP  requests     Biggest  limitaAon:   •  No  dynamic  loading;  all  dependencies  must  be  in  the  same  file  or   loaded  beforehand    
  • 29.
    DEMO   hTp://code.aaronhardy.com/require-­‐almond   node  libs/r.js  -­‐o  baseUrl=.  name=libs/almond  include=main  out=main-­‐built.js  
  • 30.
    THANK  YOU!   @aaronius  ·∙  aaronhardy.com  

Editor's Notes

  • #27 node r.js -o name=main out=js/main-built.jsbaseUrl=js
  • #29 node r.js -o name=main out=js/main-built.jsbaseUrl=js