Difference between RequireJS and CommonJS

后端 未结 2 938
小鲜肉
小鲜肉 2020-11-29 05:30

I was wondering what the difference between these snippets is.

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


        
相关标签:
2条回答
  • 2020-11-29 05:49

    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.

    0 讨论(0)
  • 2020-11-29 06:16

    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.

    0 讨论(0)
提交回复
热议问题