Writing Modular JavaScript With AMD, CommonJS & ES Harmony (Addy Osmani)

In notebook:
Article Notes
Created at:
2016-01-05
Updated:
2016-01-05
Tags:
JavaScript jQuery libraries
Writing Modular JavaScript With AMD, CommonJS & ES Harmony by Addy Osmani  An AMD module definition, the base:
  define(
    module_id /*optional*/, 
    [dependencies] /*optional*/, 
    definition function /*function for instantiating the module or object*/
);
then whatever you ​return​ with the definition function is what is exported.

to require a module:
  require(['foo', 'bar'], function ( foo, bar ) {
        // rest of your code here
        foo.doSomething();
});
you can use require inside a module, to load it dynamically:
  define(function ( require ) {
    var isReady = false, foobar;
 
    // note the inline require within our module definition
    require(['foo', 'bar'], function (foo, bar) {
        isReady = true;
        foobar = foo() + bar();
    });
 
    // we can still return a module
    return {
        isReady: isReady,
        foobar: foobar
    };
});
you can basically require anything as a dependency (templates, markdown files, even CSS)

You can load AMD modules with require.js or curl.js

Advantages 

It's well suited for browser for lazy-loading, cross-domain files without server-side tools. You can include multiple modules in a single file.

jQuery

you can require jquery files as well:
  define(['js/jquery.js','js/jquery.color.js','js/underscore.js'],
    function($, colorPlugin, _){
        // use your plugins
    });
as of jquery 1.7 you can register jQuery as an asynchronous module. Requirejs and curl are compatbile.

need to set ​define.amd.jQuery = true​ to support multiple versions of jquery

CommonJS

example of importing and exporting
  var modA = require('./foo');
var modB = require('./bar');
 
exports.app = function(){
    console.log('Im an application!');
}
 
exports.foo = function(){
    return modA.helloWorld();
}
curl supports commonjs modules in the browser
In general commonjs is better suited for the server (snychronous loading, slightly cleaner (no wrappers), closer to ES6 specifications)

ES6 modules


  module staff{
    // specify (public) exports that can be consumed by
    // other modules
    export var baker = {
        bake: function( item ){
            console.log('Woo! I just baked ' + item);
        }
    }   
}
 
module skills{
    export var specialty = "baking";
    export var experience = "5 years";
}
 
module cakeFactory{
 
    // specify dependencies
    import baker from staff;
 
    // import everything with wildcards
    import * from skills;
 
    export var oven = {
        makeCupcake: function( toppings ){
            baker.bake('cupcake', toppings);
        },
        makeMuffin: function( mSize ){
            baker.bake('muffin', size);
        }
    }
}
remote sources:
  module cakeFactory from 'http://addyosmani.com/factory/cakes.js';
cakeFactory.oven.makeCupcake('sprinkles');
cakeFactory.oven.makeMuffin('large');
on the server:
  // io/File.js
export function open(path) { ... };
export function close(hnd) { ... };

// compiler/LexicalHandler.js
module file from 'io/File';
 
import { open, close } from file;
export function scan(in) {
    try {
        var h = open(in) ...
    }
    finally { close(h) }
}