With AMD modules, when (or why) is it OK to use re

2019-03-09 10:24发布

My understanding of AMD modules (using for example RequireJs or curl.js) is:

require() is used to asynchronously load different modules and when loaded then the callback fn is executed.

And to define a module, you would have separate scripts that use define()

But I've seen some modules use require() inside their function definition, e.g.

define([a, b, c], function(i, ii, iii){ 
    require([d, e, f], function(d, e, f) {
        // do some stuff with these require()'d dependancies
    })
    /* rest of the code for this module */ 
}) 

But I find this confusing because I would have thought that if a module has dependancies then they should be passed through via the main define([dependancies], fnDefinition) function and not within it via require() as per the above example is doing.

Is there a reasoning behind this?

1条回答
爷、活的狠高调
2楼-- · 2019-03-09 11:10

There are a few reasons you may want to use require() in a module.

But first, be sure you request a reference to the correct require variable. In your example, the reference to require is a global. You want a reference to a require that is scoped to the context of your module (sometimes called a "local require"). This is easy:

define(["a", "b", "c", "require"], function(i, ii, iii, require){ 
    require(["d", "e", "f"], function(moduleD, moduleE, moduleF) {
        // do some stuff with these require()'d dependencies
    })
    /* rest of the code for this module */ 
}); 

The main reason this is important is to ensure that relative module ids (e.g. "./peerModule" or "../unclePath/cousinModule") are resolved correctly. (This is one of the reasons, curl.js doesn't have a global require by default.)


Reasons to use a local require:

  1. you don't know which modules are needed at build time (or at load time) due to run-time conditions
  2. you explicitly want to defer loading of some modules until they're needed
  3. you want to load a variation of a module based on results of feature detection (although something like dojo's "has!" plugin might be a better solution ( sorry, link eluding me))

Lastly, AMD defines a second usage of require for compatibility with modules authored in the CommonJS Modules/1.1 which are then wrapped in a define. These look like this:

define(function(require, exports, module){ 
    var a = require("pkgZ/moduleA"), // dependency
        b = require("pkgZ/moduleB"); // dependency
    /* rest of the code for this module */ 
}); 

Server-side javascript devs may find this format appealing. :)

Some AMD loaders (such as RequireJS 0.2+, dojo 1.7+, bdLoad, and curl.js 0.6+) will detect this hybrid AMD/CJSM1.1 format and find dependencies by scanning the module for require calls.

查看更多
登录 后发表回答