Common.js - CommonJS modules for the Browser

I write a lot of open-source JavaScript, and (IMHO), most of it is pretty awesome. :) That said, the latest piece that I just finished writing is probably one of my personal favorites. It is something I have wanted personally for a long time, and I just got tired of waiting for someone else to build it, so I made it myself. As the title says, this post is about using the CommonJS module pattern in the browser. First, I will just link to the project:

common.js on GitHub pages

Let’s see how to use it

Now, for a basic run-down of what this is. First, it is a Node.js module in NPM. It can be installed like so:

$ npm install -g common.js

That creates a new command on your system called commonjs which is the preprocessor. Now, let’s assume you have some CommonJS modules in a javascritps directory, like this:

javascripts/foo.js

var log = require('./log');

module.exports = function() {
    log('foo');
};

javascripts/bar.js

var foo = require('./foo');

exports.doTheThing = function() {
    foo();
};

javascripts/log/index.js

module.exports = function(value) {
    (console && console.log) ? console.log(value) : alert(value);
};

A bit convoluted just to output "foo", I know, but let’s go with it. Now, we compile our CommonJS project into a browser-ready version using the commonjs command:

$ commonjs --src ./javascripts --dest ./js --client

This takes everything in ./javascripts and compiles it to ./js, and then creates a copy of the client library at ./js/common.js.

So, now we create our HTML document to run this in:

<!doctype html>
<html>
<head>
    <title>common.js test</title>
</head>
<body>
    <!-- Load the common.js client library -->
    <script src="js/common.js"></script>
    
    <!-- Load our compiled modules (in whatever order we feel like) -->
    <script src="js/foo.js"></script>
    <script src="js/bar.js"></script>
    <script src="js/log/index.js"></script>
    
    <!-- Start running -->
    <script>
        var bar = require('bar');
        
        bar.doTheThing();
    </script>
</body>
</html>

Let’s see how it works

The common.js preprocessor works by wrapping each of your JavaScript files in an extra function call which defines all the necessary bits for a CommonJS module (such as the module and exports variables). A compiled module looks something like this (except this has been cleaned up for reading):

;
require._modules["/bar.js"] = (function () {
    var __filename = "/bar.js";
    var __dirname = "/";
    var module = {
        loaded: false,
        exports: {},
        filename: __filename,
        dirname: __dirname,
        require: null,
        call: function () {
            var require = module.require;
            module.loaded = true;
            module.call = function () {};
            __module__();
        },
        parent: null,
        children: []
    };
    var exports = module.exports;
    /* ==  Begin source for module /bar.js  == */
    var __module__ = function () {

        var foo = require('./dir/foo');

        exports.doTheThing = function () {
            foo();
        };

    }; /* ==  End source for module /bar.js  == */
    module.require = require._bind(module);
    return module;
}());;

Once your modules are compiled, you add in the very tiny common.js client library which defines the require function and contains the rules for resolving modules. And that’s it.

It should be noted that this is a 100% synchronous process, which means any module you intend to require has to loaded in the DOM before the require call is made.

Share
blog comments powered by Disqus