2
votes

Using RequireJS, I don't believe I fully understand the difference between the following two different usages of 'require'. In this case, I am only talking about the browser, not node.js. One of my questions is: can I require certain dependencies synchronously on the front-end using RequireJS?

first there is this:

    define(function(){

         //below the require is definitely the global require of RequireJS, also aliased as requirejs.

         require(['module'],function(mod){  
          //mod is loaded here only
            }

      });

then there is this:

   define(['require'],function(require){

      require(['dep'],function(dep){  //require is local not global
           //dep is loaded here only
         }

     //now the require subsequently called is the 'local' require
     var dep = require('dependency'); //I doubt this is possible on front-end..or is it?

     });

I guess I don't see the purpose of using require as an argument to define on the front-end, but is there one?

My confusion is arising because of this example here:

http://requirejs.org/docs/api.html

Relative module names inside define(): For require("./relative/name") calls that can happen inside a define() function call, be sure to ask for "require" as a dependency, so that the relative name is resolved correctly:

define(["require", "./relative/name"], function(require) {
    var mod = require("./relative/name");
});

From the above, I can only guess that you can make synchronous calls to other modules with RequireJS on the front-end if one module is relative to another?

Likewise, this example:

Generate URLs relative to module: You may need to generate an URL that is relative to a module. To do so, ask for "require" as a dependency and then use require.toUrl() to generate the URL:

define(["require"], function(require) {
    var cssUrl = require.toUrl("./style.css");
});

so, my question is: what is the difference between the local require and the global require? It certainly doesn't appear that the local require is only/primarily for CommonJS modules.

1

1 Answers

1
votes

All of these examples use asynchronous module loading, not synchronous. The code you are looking at is a bit confusing because it seems synchronous, but in reality it is not.

In this example:

define(["require", "./relative/name"], function(require) {
    var mod = require("./relative/name");
});

The asynchrony is explicit. Because the module id './relative/name' is in the dependency array, the function will not be called until it has been (asynchronously) loaded. The require call then will immediately return the module it has already (asynchronously) loaded.

In another supported syntax, the asynchrony is hidden:

define(function(require) {
    var mod = require("./relative/name");
});

But even this is asynchronous. Requirejs rewrites this code to contain a dependency array just like the one above. So asynchrony is all you get, despite appearances.

Why is this useful and different? Because it can be challenging to match a dozen members of an array with the corresponding places in the function where they are turned into variables. Consider this example from the docs:

define([ "require", "jquery", "blade/object", "blade/fn", "rdapi",
         "oauth", "blade/jig", "blade/url", "dispatch", "accounts",
         "storage", "services", "widgets/AccountPanel", "widgets/TabButton",
         "widgets/AddAccount", "less", "osTheme", "jquery-ui-1.8.7.min",
         "jquery.textOverflow"],
function (require,   $,        object,         fn,         rdapi,
          oauth,   jig,         url,         dispatch,   accounts,
          storage,   services,   AccountPanel,           TabButton,
          AddAccount,           less,   osTheme) {

});

Another reason this is useful and differnt is that the local require allows you to properly resolve relative module paths. This lets you define a bunch of modules relative to each other without explicitly specifying the directory they are in, which is handy if that directory might change.