The CommonJS module proposal specifies a simple API for declaring modules that work outside of the browser (such as on the server). Unlike AMD, it attempts to cover a broader set of concerns such as IO, filesystem, promises, and more.
Originally called ServerJS in a project started by Kevin Dangoor back in 2009, the format was more recently formalized by CommonJS, a volunteer working group that aims to design, prototype, and standardize JavaScript APIs. To date, theyâve attempted to ratify standards for both modules and packages.
From a structure perspective, a CommonJS module is a
reusable piece of JavaScript that exports specific objects made
available to any dependent code. Unlike AMD, there are typically no
function wrappers around such modules (so we wonât see define
here, for example).
CommonJS modules basically contain two primary parts: a free
variable named exports
, which contains the objects a module wishes to make
available to other modules, and a require
function that modules can use to import the exports of other
modules (Examples 11-9, 11-10, and 11-11).
This can be done as AMD supports a simplified CommonJS wrapping feature.
var
modA
=
require
(
"./foo"
);
var
modB
=
require
(
"./bar"
);
exports
.
app
=
function
(){
console
.
log
(
"Im an application!"
);
}
exports
.
foo
=
function
(){
return
modA
.
helloWorld
();
}
bar.js:
exports
.
name
=
"bar"
;
foo.js:
require
(
"./bar"
);
exports
.
helloWorld
=
function
(){
return
"Hello World!!"
}
SproutCore 1.1 http://sproutcore.com
Server-side:
Node http://nodejs.org
Persevere http://www.persvr.org/
Wakanda http://www.wakandasoft.com/
There are developers that feel CommonJS is better suited to server-side development, which is one reason thereâs currently a level of disagreement over which format should and will be used as the de facto standard in the pre-Harmony age moving forward. Some of the arguments against CommonJS include a note that many CommonJS APIs address server-oriented features that one would simply not be able to implement at a browser level in JavaScriptâfor example, io, system and js could be considered unimplementable by the nature of their functionality.
That said, itâs useful to know how to structure CommonJS modules regardless so that we can better appreciate how they fit in when defining modules that may be used everywhere. Modules that have applications on both the client and server include validation, conversion, and templating engines. The way some developers are approaching choosing which format to use is opting for CommonJS when a module can be used in a server-side environment and using AMD if this is not the case.
As AMD modules are capable of using plug-ins and can define more granular things like constructors and functions, this makes sense. CommonJS modules are only able to define objects that can be tedious to work with if weâre trying to obtain constructors out of them.
Although itâs beyond the scope of this section, you may have also
noticed that there were different types of require
methods mentioned when discussing AMD and CommonJS. The concern with a
similar naming convention is of course confusion, and the community is
currently split on the merits of a global require
function. John Hannâs suggestion here is that rather than calling it
require
, which would probably fail to achieve the
goal of informing users about the different between a global and inner
require
, it may make more sense to rename the global
loader method something else (e.g., the name of the library). Itâs for
this reason that a loader like curl.js uses curl()
as opposed to require
.
Get Learning JavaScript Design Patterns now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.