# CommonJS Notes

- Introduction§ 1
- Manual Conversion§ 2
- Conversion Tool§ 3
- Setting Exported Value§ 4
- Alternative Syntax§ 5
- Loading Modules from CommonJS Packages§ 6
- Optimization Tool§ 7

## Introduction§ 1

CommonJS defines a module format. Unfortunately, it was defined without giving browsers equal footing to other JavaScript environments. Because of that, there are CommonJS spec proposals for Transport formats and an asynchronous require.

RequireJS tries to keep with the spirit of CommonJS, with using string names to refer to dependencies, and to avoid modules defining global objects, but still allow coding a module format that works well natively in the browser. RequireJS implements the Asynchronous Module Definition (formerly Transport/C) proposal.

If you have modules that are in the traditional CommonJS module format, then you can easily convert them to work with RequireJS. Not all modules will convert cleanly to the new format. Types of modules that may not convert well:

- Modules that use conditional code to do a require call, like if(someCondition) require('a1') else require('a2');
- Some types of circular dependencies.

## Manual Conversion§ 2

If you just have a few modules to convert, then all you need to do is wrap the module in this code:

    define(function(require, exports, module) {
        //Put traditional CommonJS module content here
    });

IMPORTANT: The function arguments should always be listed as require, exports, module, with those exact names and in that exact order, otherwise chaos will ensue. You can leave off exports and module from the list, but if they are needed, they need to be specified in the exact order illustrated here.

## Conversion Tool§ 3

If you have many modules to convert, the r.js project has a converter tool built into the r.js file. Give it the path to the directory you want to convert and an output directory:

    node r.js -convert path/to/commonjs/modules/ path/to/output

There are a small number of CommonJS modules do not work well as define()-wrapped modules. See the r.js README

for more information.

## Setting Exported Value§ 4

There are some CommonJS systems, mainly Node, that allow setting the exported value by assigning the exported value as module.exports. That idiom is supported by RequireJS, but there is another, easier way -- just return the value from the function passed to define:

    define(function (require) {
        var foo = require('foo');

        //Define this module as exporting a function
        return function () {
            foo.doSomething();
        };
    });

With this approach, then you normally do not need the exports and module function arguments, so you can leave them off the module definition.

## Alternative Syntax§ 5

Instead of using require() to get dependencies inside the function passed to define(), you can also specify them via a dependency array argument to define(). The order of the names in the dependency array match the order of arguments passed to the definition function passed to define(). So the above example that uses the module foo:

    define(['foo'], function (foo) {
        return function () {
            foo.doSomething();
        };
    });

See the API docs for more information on that syntax.

## Loading Modules from CommonJS Packages§ 6

Modules in CommonJS packages can be loaded by RequireJS by setting up the RequireJS configuration to know about the location and package attributes. See the packages API section for more information.

## Optimization Tool§ 7

RequireJS has an optimization tool that can combine module definitions together into optimized bundles for browser delivery. It works as a command-line tool that you use as part of code deployment. See the optimization docs for more information.