Difference between RequireJS and CommonJS

天涯浪子 提交于 2019-11-27 01:08:47

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.

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!