CommonJS Modules with Rhino
CommentsRhino, Mozilla’s Java based JavaScript implementation, has gotten a facelift recently. First, the source was moved from CVS to GitHub, where it joins all the JavaScript cool kids. Let’s hope this change brings some more lifeblood into the project.
Perhaps more significantly, the latest 1.7R3 release of Rhino brings support for loading CommonJS modules. The nice thing about this is that you can author server-side JavaScript modules and deploy them with a single, simple dependency: a cross-platform .jar file.
To see this in action, you can download the 1.7R3 release and extract the archive. For this example, I’ll write a few simple math modules that provide add and subtract methods. Then we’ll run a main.js application that pulls in these modules.
The layout for these example files looks like this:
main.js
my_modules/
math.js
math/
add.js
subtract.js
First, here’s the add.js module:
exports.add = function(a, b) {
return a + b;
};
This module doesn’t have any dependencies. It exports one method: add.
And now the subtract.js module:
var add = require("./add").add;
exports.subtract = function(a, b) {
return add(a, -b);
};
For the sake of this example, the subtract.js module requires the add.js module to implement the subtract method. The require call uses a relative module locator. This makes the exports from add.js available locally.
Finally, to provide a nice API for our application to use, I’ll create a math.js module that exports both add and subtract. The math.js module looks like this:
exports.add = require("./math/add").add;
exports.subtract = require("./math/subtract").subtract;
That’s it. Now the main.js application script:
var math = require("math");
print("5 minus 3 is " + math.subtract(5, 3));
In this case, the require call uses an absolute identifier to pull in the math.js module’s exports. This means it will pull in the first math.js script found on the module search path (available as require.paths within a module).
To run my application, I invoke Rhino with the -module and -main command line options.
$ java -jar rhino1_7R3/js.jar -modules my_modules -main main.js
5 minus 3 is 2
The -modules value is a path that becomes my module search path (use multiple -modules options for multiple paths). The -main value is the path to my main application script.
Nothing fancy in this example, but it demonstrates the potential for scripting server-side applications with JavaScript modules using Rhino.