Modules/ScriptModules

From CommonJS Spec Wiki
Jump to: navigation, search

Browser Sharable as Written

It would be handy to be able to share modules "as written" with the browser by loading the source code with html script tags. I think the following source code allows this feature. The first and last lines of the modules would be idiomatic boilerplate for modules to be shared on both the client and server.

There are several ways to write the first and last lines. Some of them are shorter than below but give up some of the protection of the global namespace. The technique below only relies on the browser having the "require.install" property and the server not having it.

// ==================================================================
// source code
 
//
// math.js
//
(function(){
 
    var mod = function(require,exports) {
 
        exports.add = function() {
            var sum = 0, i = 0, args = arguments, l = args.length;
            while (i < l) {
                sum += args[i++];
            }
            return sum;
        };
 
    };
 
    require.install ? require.install('math', mod) : mod(require, exports);
 
})();
 
//
// increment.js
//
(function(){
 
    var mod = function(require,exports) {
 
	var add = require('math').add;
	exports.increment = function(val) {
	    return add(val, 1);
	};
 
    };
 
    require.install ? require.install('increment', mod) : mod(require, exports);
 
})();
 
//
// program.js
//
var inc = require('increment').increment;
var a = 1;
inc(a); // 2

Below is a comparison of a module written two different ways.

First, the "normal" way for the browser that people are accustom to seeing these days. There are other ways to do it but this is certainly one way in an attempt to make an oranges-to-oranges comparison.

// define the library in a file called asdf.js
// first and last lines are boilerplate 
 
var LIB = LIB || {};
LIB.asdf = (function() {
 
    var exports={};
 
    var c = 1;
    exports.a = function() {
        return c;
    };
    exports.b = 2;
 
    return exports;
 
})();
 
// use the library in the browser
 
LIB.asdf.a();
 
// use the library on the server
 
require('asdf').LIB.asdf.a();
 
// Use the library on the server or in browser.
// A module dependent on asdf would need to 
// be written like this or something similar.
 
(require ? require('asdf') : window).LIB.asdf.a();

Now write the library so it can be used the same way in the browser and on the server where the server has securable module loading. Note the boilerplate is only a little longer and both versions of boilerplate include the name of the module once. The main three lines of the library are the same.

 
// define the library in a file called asdf.js
// assume "exports" is not defined
// assume "modules" and "require" are defined
// first and last lines are boilerplate
 
(function(){
 
    var mod = function(require, exports) {
 
        var c = 1;
        exports.a = function() {
            return c;
        };
        exports.b = 2;
 
    };
 
    require.install ? require.install('asdf', mod) : mod(require, exports);
 
})();
 
// use the library in the browser or on the server
 
require('asdf').a();