Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between RequireJS and CommonJS

I was wondering what the difference between these snippets is.

var $ = require('jquery');
var _ = require('underscore');
var BackBone = require('backbone');

and

require(['jquery','underscore','backbone'],function ($, _, BackBone){
    //code goes here
})

Both work fine for me, but not sure is their any purpose behind the above two.

like image 819
powercoder23 Avatar asked Jan 09 '14 13:01

powercoder23


People also ask

What is the difference between CommonJS and AMD?

In fact, AMD was split from CommonJS early in its development. The main difference between AMD and CommonJS lies in its support for asynchronous module loading. "The main difference between AMD and CommonJS lies in its support for asynchronous module loading."

What is the difference between CommonJS and ES6?

While CommonJS and ES6 modules share similar syntax, they work in fundamentally different ways: ES6 modules are pre-parsed in order to resolve further imports before code is executed. CommonJS modules load dependencies on demand while executing the code.

What is the difference between ESM and CommonJS?

ES modules are the standard for JavaScript, while CommonJS is the default in Node. js. The ES module format was created to standardize the JavaScript module system. It has become the standard format for encapsulating JavaScript code for reuse.

What is CommonJS used for?

CommonJS is a module formatting system. It is a standard for structuring and organizing JavaScript code. CJS assists in the server-side development of apps and it's format has heavily influenced NodeJS's module management.


2 Answers

Consider the first snippet, which is in the CommonJS style:

var $ = require('jquery');
var _ = require('underscore');
var BackBone = require('backbone');

These calls are synchronous calls: when require returns, it returns the module you requested. CommonJS require calls are synchronous. There is a proposal for supporting asynchronous forms of require but as far as I can tell it has not progressed beyond the proposal level. Node.js used to have require.async which has been removed. There's a package that implements it though. Using this package looks at lot like using AMD style modules.

Now, consider the second snippet, which is in the AMD style:

require(['jquery','underscore','backbone'],function ($, _, BackBone){
    //code goes here
})

Since RequireJS implements the AMD type of module system, the above code works with RequireJS. This require call is --- as suggested by the name Asynchronous Module Definition (AMD) --- asynchronous. You can't rely on the return value of require to get a module value. You have to use a callback instead. The define call works in a similar way but defines a module in addition to requiring modules.

Now, if you use RequireJS, it provides facilities that allow to use either style when you define modules so that you can define a module like this:

define(['jquery','underscore','backbone'],function ($, _, BackBone){
    //code goes here
});

Or use something that looks more like the CommonJS idiom like this:

define(function (require) {
    var $ = require('jquery');
    var _ = require('underscore');
    var BackBone = require('backbone');
    //code goes here
});

It makes it really easy to convert a CommonJS style module to use with RequireJS: just wrap it with a define call as above. There's a tool to help the conversion.

Behind the scenes, RequireJS reads the code of the callback in the 2nd form and creates a list of dependencies so that in the end it is interpreted like:

define(['require', 'jquery','underscore','backbone'], function (require) {
    var $ = require('jquery');
    var _ = require('underscore');
    var BackBone = require('backbone');
    //code goes here
})

It may be surprising (given that AMD is asynchronous) that the require calls in the callback are synchronous. This is part of RequireJS's support for the CommonJS style. RequireJS supports a kind of synchronous require call but with the following caveat: if the module is already defined before the call to the synchronous require, then the synchronous require returns the module's value, but otherwise it fails immediately. That is, it does not try to load a module. Because RequireJS interprets a module definition that uses the CommonJS style as I've shown above --- as if the dependencies were actually listed in the define arguments --- then these modules are guaranteed to be loaded by the time the synchronous calls to require are made.

Besides being able to use CommonJS modules in RequireJS (provided a wrapper is added), it is also possible to use modules designed for RequireJS in a CommonJS environment like Node.js. For instance, I've used node-amd-loader to load modules I've designed as AMD modules in Node.js.

like image 114
Louis Avatar answered Oct 17 '22 13:10

Louis


The former snippet adheres to the CommonJS spec, which outlines how modules are to be exported/transported to be used in other modules.

So, you could write code which could look like this

src/ExpressModule.js

var express = require('express');
// do initialization
exports.express = express;

And then you can use it like this

src/UserExpressModule.js

var express = require('./ExpressModule');
// do something else

CommonJS spec was built primarily for server side environments, and by extension, is used in Node.js

On the other hand of the spectrum is AMD, most notably implemented by RequireJS. AMD was built for browser environments, or client-side code, and here you can use and define modules like the latter snippet in your code

A sample use could be like this

src/main.js

requirejs.config({
    baseUrl: '../vendor'
    path: '../src'
});
require(['jquery', 'underscore', 'backbone'], function($, _, Backbone) {
    // do some client side computation here
});

You can then include this main.js file in your index.html like so

<script data-main="src/main.js" src="vendor/require.js"></script>

Essentially, CommonJS and AMD are at their core specifications for modularizing Javascript, but are aimed at different execution environments.

like image 1
Achrome Avatar answered Oct 17 '22 13:10

Achrome