Modular

JavaScript
Andrew Eisenberg

Tasktop Technologies
1
Modular

JavaScript
Andrew Eisenberg

Tasktop Technologies
1
(Non-)
A story about JavaScript
and modularization in 4
parts
2
A story about JavaScript
and modularization in 4
parts
2
No Modules

(ancient history)
A story about JavaScript
and modularization in 4
parts
2
No Modules

(ancient history)
Module Pattern

(industrial revolution)
A story about JavaScript
and modularization in 4
parts
2
No Modules

(ancient history)
Module Pattern

(industrial revolution)
Module loaders

(today)
A story about JavaScript
and modularization in 4
parts
2
No Modules

(ancient history)
Module Pattern

(industrial revolution)
Module loaders

(today)
Harmony Modules

(tomorrow)
A story about JavaScript
and modularization in 4
parts
2
No Modules

(ancient history)
Module Pattern

(industrial revolution)
Module loaders

(today)
Harmony Modules

(tomorrow)
This is really the story of a
language reaching maturity
We are Java Devs.

Why should we care?
JavaScript is not just blinky text and popups

Massive applications being built with it on
client AND server

JavaScript is useful and ubiquitous

TIOBE index #9 (March 2014)

But JavaScript is (or was) only a toy
language
3
blinky
We are Java Devs.

Why should we care?
JavaScript is not just blinky text and popups

Massive applications being built with it on
client AND server

JavaScript is useful and ubiquitous

TIOBE index #9 (March 2014)

But JavaScript is (or was) only a toy
language
3
But there is a core
goodness
4
But there is a core
goodness
4
No modules
Part I --- Ancient History (c. 1995)
5
The original approach
Script tags

All code is global
6
The original approach
Script tags

All code is global
6
html	
  
	
  	
  script	
  “foo.js”/	
  
	
  	
  script	
  “bar.js”/	
  
/html
The original approach
Script tags

All code is global
6
html	
  
	
  	
  script	
  “foo.js”/	
  
	
  	
  script	
  “bar.js”/	
  
/html
//	
  foo.js	
  
var	
  x	
  =	
  9;
The original approach
Script tags

All code is global
6
html	
  
	
  	
  script	
  “foo.js”/	
  
	
  	
  script	
  “bar.js”/	
  
/html
//	
  foo.js	
  
var	
  x	
  =	
  9;
//	
  bar.js	
  
console.log(x);
Prognosis?
Name clashes

No explicit dependencies

Order is important

Just pray that all dependencies are available
7
Prognosis?
Name clashes

No explicit dependencies

Order is important

Just pray that all dependencies are available
7
Ugggh!
Module pattern
Part II --- Industrial Revolution (c. 2006)
8
Module pattern
All code is still global

Each script defines its
own namespace

Pattern has many
variations
9
Module pattern
All code is still global

Each script defines its
own namespace

Pattern has many
variations
9
html	
  
	
  	
  script	
  “foo.js”/	
  
	
  	
  script	
  “bar.js”/	
  
/html
Module pattern
All code is still global

Each script defines its
own namespace

Pattern has many
variations
9
html	
  
	
  	
  script	
  “foo.js”/	
  
	
  	
  script	
  “bar.js”/	
  
/html
//	
  foo.js	
  
foo	
  =	
  foo	
  ||	
  {};	
  
foo.x	
  =	
  9;
Module pattern
All code is still global

Each script defines its
own namespace

Pattern has many
variations
9
html	
  
	
  	
  script	
  “foo.js”/	
  
	
  	
  script	
  “bar.js”/	
  
/html
//	
  foo.js	
  
foo	
  =	
  foo	
  ||	
  {};	
  
foo.x	
  =	
  9;
//	
  bar.js	
  
(function(foo)	
  {	
  
	
  var	
  x	
  =	
  “Number	
  ”;	
  
	
  console.log(x	
  +	
  foo.x);	
  
})(foo);
Still very popular
e.g., jQuery fn namespace*
10
* jQuery 1.7 introduced AMD modules
Still very popular
e.g., jQuery fn namespace*
10
(function(	
  $	
  )	
  {	
  
	
  $.fn.myPlugin=function(args){	
  
	
  	
  //	
  awesome	
  plugin	
  stuff	
  
	
  };	
  
})(	
  jQuery	
  );	
  
	
  $.fn.myPlugin(args);
* jQuery 1.7 introduced AMD modules
Prognosis?
Name clashes,

but far less common

Easier to mock dependencies

But…

Order matters

Just pray that all
dependencies are available
11
Prognosis?
Name clashes,

but far less common

Easier to mock dependencies

But…

Order matters

Just pray that all
dependencies are available
11
Better
Prognosis?
Name clashes,

but far less common

Easier to mock dependencies

But…

Order matters

Just pray that all
dependencies are available
11
Better
But still ugggh!
Module loaders
Part III --- Today
12
The module explosion
13
Idea!

Use the environment to
selectively load modules in
order
The module explosion
13
Idea!

Use the environment to
selectively load modules in
order
Relies on a module
loader outside the
language specification
The module explosion
Formats

CommonJS

AMD
13
Idea!

Use the environment to
selectively load modules in
order
Relies on a module
loader outside the
language specification
The module explosion
Formats

CommonJS

AMD
Loaders

node (CJS)

requireJs (AMD)

curl (AMD)

…
13
Idea!

Use the environment to
selectively load modules in
order
Relies on a module
loader outside the
language specification
CommonJS
Used by node

Bad news for the web
14
var	
  modA	
  =	
  require(‘moduleA’),	
  
	
  	
  modB	
  =	
  require(‘moduleB’);	
  
!
export.aVal	
  =	
  modA.myVal;	
  
export.bVal	
  =	
  modB.myVal;
CJS is not web-friendly
15
//	
  main.js	
  
if	
  (needSub)	
  {	
  
	
  	
  require('./sub');	
  
}
//	
  sub.js	
  
console.log(‘here’);
Conditional loading of modules. (Yay!)

But, that means synchronous loading

Synchronous loading makes for horrendous web
experience
Asynchronous module
definition (AMD)
Asynchronous
loading of
modules

Makes a
happy web

Syntax more
cumbersome
16
define(‘myModule’,	
  
	
  	
  [‘moduleA’,	
  ‘moduleB],	
  	
  
	
  	
  function(a,	
  b)	
  {	
  
	
  	
  return	
  {	
  	
  
	
  	
  	
  	
  aVal:	
  a.myVal,	
  
	
  	
  	
  	
  bVal	
  :	
  b.myVal	
  
	
  	
  }	
  
});
Require.js: a
sort of deep dive
(There’s magic,

but the good kind)
17
Universal Module
Declarations (UMD)
Attempt to unify client and server side modules

BUT not a standard

Semantics different browser vs. server
18
Universal Module
Declarations (UMD)
Attempt to unify client and server side modules

BUT not a standard

Semantics different browser vs. server
18
define(function(require,export,module){	
  
	
  	
  var	
  modA	
  =	
  require(‘moduleA’),	
  
	
  	
  	
  	
  modB	
  =	
  require(‘moduleB’);	
  
	
  	
  export.aVal	
  =	
  modA.myVal;	
  
	
  	
  export.bVal	
  =	
  modB.myVal;	
  
});
But UMD needs even

more boilerplate
19
All sorts of UMD proposals here:

https://github.com/umdjs/umd
But UMD needs even

more boilerplate
19
All sorts of UMD proposals here:

https://github.com/umdjs/umd
//	
  Boilerplate	
  
if	
  (typeof	
  module	
  ===	
  'object'	
  	
  	
  
	
  	
  	
  	
  typeof	
  define	
  !==	
  'function')	
  {	
  
	
  	
  var	
  define	
  =	
  function	
  (factory)	
  {	
  
	
  	
  	
  	
  module.exports	
  =	
  factory(require,exports,module);	
  
	
   };	
  
}	
  
//	
  Here	
  is	
  the	
  actual	
  module	
  
define(function	
  (require,	
  exports,	
  module)	
  {	
  
	
  	
  var	
  b	
  =	
  require('b');	
  
	
   return	
  function	
  ()	
  {};	
  
});
Browserify: no more
boilerplate
Pre-processor

converts CJS - AMD

something browser compatible

Avoid AMD boilerplate

Can use some node.js libs in browser
20
*http://browserify.org/
Browserify example
21
// require the core node events module!
var EventEmitter = require(‘events')!
! .EventEmitter;!
!
//create a new event emitter!
var emitter = new EventEmitter;!
!
// set up a listener for the event!
emitter.on('pizza', function(message){!
console.log(message);!
});!
!
// emit an event!
emitter.emit('pizza', ‘yummy!');
Browserify example
21
// require the core node events module!
var EventEmitter = require(‘events')!
! .EventEmitter;!
!
//create a new event emitter!
var emitter = new EventEmitter;!
!
// set up a listener for the event!
emitter.on('pizza', function(message){!
console.log(message);!
});!
!
// emit an event!
emitter.emit('pizza', ‘yummy!');
$	
  browserify	
  index.js	
  	
  bundle.js
Prognosis?
22
Prognosis?
No more language level name clashes
Not order dependent
Dependencies explicit in module
Load and edit time checkers
22
Prognosis?
No more language level name clashes
Not order dependent
Dependencies explicit in module
Load and edit time checkers
22
Yay! We did it!
Prognosis?
No more language level name clashes
Not order dependent
Dependencies explicit in module
Load and edit time checkers
22
Yay! We did it!
...right?
Prognosis?
No more language level name clashes
Not order dependent
Dependencies explicit in module
Load and edit time checkers
BUT...

Too many competing module systems

modules for client and server 

Modules still not first class

Boilerplate
22
Yay! We did it!
...right?
Prognosis?
No more language level name clashes
Not order dependent
Dependencies explicit in module
Load and edit time checkers
BUT...

Too many competing module systems

modules for client and server 

Modules still not first class

Boilerplate
22
Yay! We did it!
...right?
Ugggh!
Harmony Modules
Part IV --- Tomorrow
23
Real Modules
ES6 Harmony

Official JavaScript module spec

Sync and async friendly

Browser and server friendly
24
ES6 Harmony
25
//	
  foo.js	
  
module	
  foo	
  {	
  
	
  	
  	
  	
  export	
  var	
  x	
  =	
  42;	
  
}
//	
  bar.js	
  
import	
  foo	
  as	
  foo;	
  
console.log(foo.x);
ES6 modules, today!
Using the ES6 Module Transpiler*
26
*https://github.com/square/es6-module-transpiler
Prognosis ES6?
Finally, modules are first class in the
language!

Loaders/runtimes will implement spec
differently

sync loading possible

async loading possible
27
Prognosis ES6?
Finally, modules are first class in the
language!

Loaders/runtimes will implement spec
differently

sync loading possible

async loading possible
27
Expected release date? 201X?
Prognosis JavaScript?
28
Prognosis JavaScript?
Plagued by poor
design choices early
on
28
Prognosis JavaScript?
Plagued by poor
design choices early
on
JS used to be a toy
language
28
Prognosis JavaScript?
Plagued by poor
design choices early
on
JS used to be a toy
language
Hard, but possible to
fix past mistakes.
28
Resources
ES6 module transpiler

https://github.com/square/es6-module-transpiler

AMD module specification (draft, never ratified):

http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition

CommonJS module specification:

http://wiki.commonjs.org/wiki/Modules

UMD modules (various proposed implementations):

https://github.com/umdjs/umd

ES6 Harmony draft specification

http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts

JavaScript Module pattern

http://www.adequatelygood.com/JavaScript-Module-Pattern-In-
Depth.html

Browserify

http://browserify.org

http://superbigtree.tumblr.com/post/54873453939/introduction-to-
browserify (borrowed browserify example)
29
Questions?
Andrew Eisenberg

twitter: @werdnagreb

email:
andrew.eisenberg@tasktop.com
30
Story parts

No modules

Module pattern

Module loaders

Language modules

Modular JavaScript

  • 1.
  • 2.
  • 3.
    A story aboutJavaScript and modularization in 4 parts 2
  • 4.
    A story aboutJavaScript and modularization in 4 parts 2 No Modules (ancient history)
  • 5.
    A story aboutJavaScript and modularization in 4 parts 2 No Modules (ancient history) Module Pattern (industrial revolution)
  • 6.
    A story aboutJavaScript and modularization in 4 parts 2 No Modules (ancient history) Module Pattern (industrial revolution) Module loaders (today)
  • 7.
    A story aboutJavaScript and modularization in 4 parts 2 No Modules (ancient history) Module Pattern (industrial revolution) Module loaders (today) Harmony Modules
 (tomorrow)
  • 8.
    A story aboutJavaScript and modularization in 4 parts 2 No Modules (ancient history) Module Pattern (industrial revolution) Module loaders (today) Harmony Modules
 (tomorrow) This is really the story of a language reaching maturity
  • 9.
    We are JavaDevs. Why should we care? JavaScript is not just blinky text and popups Massive applications being built with it on client AND server JavaScript is useful and ubiquitous TIOBE index #9 (March 2014) But JavaScript is (or was) only a toy language 3 blinky
  • 10.
    We are JavaDevs. Why should we care? JavaScript is not just blinky text and popups Massive applications being built with it on client AND server JavaScript is useful and ubiquitous TIOBE index #9 (March 2014) But JavaScript is (or was) only a toy language 3
  • 11.
    But there isa core goodness 4
  • 12.
    But there isa core goodness 4
  • 13.
    No modules Part I--- Ancient History (c. 1995) 5
  • 14.
    The original approach Scripttags All code is global 6
  • 15.
    The original approach Scripttags All code is global 6 html      script  “foo.js”/      script  “bar.js”/   /html
  • 16.
    The original approach Scripttags All code is global 6 html      script  “foo.js”/      script  “bar.js”/   /html //  foo.js   var  x  =  9;
  • 17.
    The original approach Scripttags All code is global 6 html      script  “foo.js”/      script  “bar.js”/   /html //  foo.js   var  x  =  9; //  bar.js   console.log(x);
  • 18.
    Prognosis? Name clashes No explicitdependencies Order is important Just pray that all dependencies are available 7
  • 19.
    Prognosis? Name clashes No explicitdependencies Order is important Just pray that all dependencies are available 7 Ugggh!
  • 20.
    Module pattern Part II--- Industrial Revolution (c. 2006) 8
  • 21.
    Module pattern All codeis still global Each script defines its own namespace Pattern has many variations 9
  • 22.
    Module pattern All codeis still global Each script defines its own namespace Pattern has many variations 9 html      script  “foo.js”/      script  “bar.js”/   /html
  • 23.
    Module pattern All codeis still global Each script defines its own namespace Pattern has many variations 9 html      script  “foo.js”/      script  “bar.js”/   /html //  foo.js   foo  =  foo  ||  {};   foo.x  =  9;
  • 24.
    Module pattern All codeis still global Each script defines its own namespace Pattern has many variations 9 html      script  “foo.js”/      script  “bar.js”/   /html //  foo.js   foo  =  foo  ||  {};   foo.x  =  9; //  bar.js   (function(foo)  {    var  x  =  “Number  ”;    console.log(x  +  foo.x);   })(foo);
  • 25.
    Still very popular e.g.,jQuery fn namespace* 10 * jQuery 1.7 introduced AMD modules
  • 26.
    Still very popular e.g.,jQuery fn namespace* 10 (function(  $  )  {    $.fn.myPlugin=function(args){      //  awesome  plugin  stuff    };   })(  jQuery  );    $.fn.myPlugin(args); * jQuery 1.7 introduced AMD modules
  • 27.
    Prognosis? Name clashes, but farless common Easier to mock dependencies But… Order matters Just pray that all dependencies are available 11
  • 28.
    Prognosis? Name clashes, but farless common Easier to mock dependencies But… Order matters Just pray that all dependencies are available 11 Better
  • 29.
    Prognosis? Name clashes, but farless common Easier to mock dependencies But… Order matters Just pray that all dependencies are available 11 Better But still ugggh!
  • 30.
  • 31.
    The module explosion 13 Idea! Usethe environment to selectively load modules in order
  • 32.
    The module explosion 13 Idea! Usethe environment to selectively load modules in order Relies on a module loader outside the language specification
  • 33.
    The module explosion Formats CommonJS AMD 13 Idea! Usethe environment to selectively load modules in order Relies on a module loader outside the language specification
  • 34.
    The module explosion Formats CommonJS AMD Loaders node(CJS) requireJs (AMD) curl (AMD) … 13 Idea! Use the environment to selectively load modules in order Relies on a module loader outside the language specification
  • 35.
    CommonJS Used by node Badnews for the web 14 var  modA  =  require(‘moduleA’),      modB  =  require(‘moduleB’);   ! export.aVal  =  modA.myVal;   export.bVal  =  modB.myVal;
  • 36.
    CJS is notweb-friendly 15 //  main.js   if  (needSub)  {      require('./sub');   } //  sub.js   console.log(‘here’); Conditional loading of modules. (Yay!) But, that means synchronous loading Synchronous loading makes for horrendous web experience
  • 37.
    Asynchronous module definition (AMD) Asynchronous loadingof modules Makes a happy web Syntax more cumbersome 16 define(‘myModule’,      [‘moduleA’,  ‘moduleB],        function(a,  b)  {      return  {            aVal:  a.myVal,          bVal  :  b.myVal      }   });
  • 38.
    Require.js: a sort ofdeep dive (There’s magic,
 but the good kind) 17
  • 39.
    Universal Module Declarations (UMD) Attemptto unify client and server side modules BUT not a standard Semantics different browser vs. server 18
  • 40.
    Universal Module Declarations (UMD) Attemptto unify client and server side modules BUT not a standard Semantics different browser vs. server 18 define(function(require,export,module){      var  modA  =  require(‘moduleA’),          modB  =  require(‘moduleB’);      export.aVal  =  modA.myVal;      export.bVal  =  modB.myVal;   });
  • 41.
    But UMD needseven
 more boilerplate 19 All sorts of UMD proposals here: https://github.com/umdjs/umd
  • 42.
    But UMD needseven
 more boilerplate 19 All sorts of UMD proposals here: https://github.com/umdjs/umd //  Boilerplate   if  (typeof  module  ===  'object'              typeof  define  !==  'function')  {      var  define  =  function  (factory)  {          module.exports  =  factory(require,exports,module);     };   }   //  Here  is  the  actual  module   define(function  (require,  exports,  module)  {      var  b  =  require('b');     return  function  ()  {};   });
  • 43.
    Browserify: no more boilerplate Pre-processor convertsCJS - AMD something browser compatible Avoid AMD boilerplate Can use some node.js libs in browser 20 *http://browserify.org/
  • 44.
    Browserify example 21 // requirethe core node events module! var EventEmitter = require(‘events')! ! .EventEmitter;! ! //create a new event emitter! var emitter = new EventEmitter;! ! // set up a listener for the event! emitter.on('pizza', function(message){! console.log(message);! });! ! // emit an event! emitter.emit('pizza', ‘yummy!');
  • 45.
    Browserify example 21 // requirethe core node events module! var EventEmitter = require(‘events')! ! .EventEmitter;! ! //create a new event emitter! var emitter = new EventEmitter;! ! // set up a listener for the event! emitter.on('pizza', function(message){! console.log(message);! });! ! // emit an event! emitter.emit('pizza', ‘yummy!'); $  browserify  index.js    bundle.js
  • 46.
  • 47.
    Prognosis? No more languagelevel name clashes Not order dependent Dependencies explicit in module Load and edit time checkers 22
  • 48.
    Prognosis? No more languagelevel name clashes Not order dependent Dependencies explicit in module Load and edit time checkers 22 Yay! We did it!
  • 49.
    Prognosis? No more languagelevel name clashes Not order dependent Dependencies explicit in module Load and edit time checkers 22 Yay! We did it! ...right?
  • 50.
    Prognosis? No more languagelevel name clashes Not order dependent Dependencies explicit in module Load and edit time checkers BUT... Too many competing module systems modules for client and server Modules still not first class Boilerplate 22 Yay! We did it! ...right?
  • 51.
    Prognosis? No more languagelevel name clashes Not order dependent Dependencies explicit in module Load and edit time checkers BUT... Too many competing module systems modules for client and server Modules still not first class Boilerplate 22 Yay! We did it! ...right? Ugggh!
  • 52.
    Harmony Modules Part IV--- Tomorrow 23
  • 53.
    Real Modules ES6 Harmony OfficialJavaScript module spec Sync and async friendly Browser and server friendly 24
  • 54.
    ES6 Harmony 25 //  foo.js   module  foo  {          export  var  x  =  42;   } //  bar.js   import  foo  as  foo;   console.log(foo.x);
  • 55.
    ES6 modules, today! Usingthe ES6 Module Transpiler* 26 *https://github.com/square/es6-module-transpiler
  • 56.
    Prognosis ES6? Finally, modulesare first class in the language! Loaders/runtimes will implement spec differently sync loading possible async loading possible 27
  • 57.
    Prognosis ES6? Finally, modulesare first class in the language! Loaders/runtimes will implement spec differently sync loading possible async loading possible 27 Expected release date? 201X?
  • 58.
  • 59.
    Prognosis JavaScript? Plagued bypoor design choices early on 28
  • 60.
    Prognosis JavaScript? Plagued bypoor design choices early on JS used to be a toy language 28
  • 61.
    Prognosis JavaScript? Plagued bypoor design choices early on JS used to be a toy language Hard, but possible to fix past mistakes. 28
  • 62.
    Resources ES6 module transpiler https://github.com/square/es6-module-transpiler AMDmodule specification (draft, never ratified): http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition CommonJS module specification: http://wiki.commonjs.org/wiki/Modules UMD modules (various proposed implementations): https://github.com/umdjs/umd ES6 Harmony draft specification http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts JavaScript Module pattern http://www.adequatelygood.com/JavaScript-Module-Pattern-In- Depth.html Browserify http://browserify.org http://superbigtree.tumblr.com/post/54873453939/introduction-to- browserify (borrowed browserify example) 29
  • 63.
    Questions? Andrew Eisenberg twitter: @werdnagreb email: andrew.eisenberg@tasktop.com 30 Storyparts No modules Module pattern Module loaders Language modules