Interoperable JavaScript for the browser and Node

A major stumbling block in creating code that can be shared between the browser and Node is how to cleanly export modules when using RequireJS for front end module loading. This can be seen in the differing syntax below:

RequireJS

define(['underscore', './example-dependency'], function(_, ExampleDependency) {  
  //return an object to define the module
  return {
    ...
  }
});

CommonJS

var _ = require('underscore');  
var ExampleDependency = require('./example-dependency');

exports = {  
…
}

As they stand, these two variants are either incompatible or require ugly double export hacks. Fortunately amdefine solves this problem by allowing you to export modules using the AMD define() syntax, whilst transparently exporting them for the CommonJS with the addition of one extra line at the top of each file. It should also be noted that this is stripped out by the RequireJS optimizer pre deployment.

Shared

if (typeof define !== 'function') { var define = require('amdefine')(module) }

define(['underscore', './example-dependency'], function(_, ExampleDependency) {  
  //return an object to define the module
  return {
    ...
  }
});

Automagically, the code above now works in both environments. Just add amdefine to your project:

npm install amdefine

Note: Adding the save parameter automatically adds the latest version to the dependencies in package.json as well as installing the package.

npm install amdefine --save

For more on this topic, see my follow up article on tidier module definition styles, and avoiding the potential issues with RequireJS.