19

我对 AMD 模块(例如使用 RequireJs 或 curl.js)的理解是:

require()用于异步加载不同的模块,并在加载时执行回调 fn。

并且要定义一个模块,您将有单独的脚本使用define()

但是我已经看到一些模块require()在它们的函数定义中使用,例如

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 */ 
}) 

但是我觉得这很令人困惑,因为我会认为如果一个模块具有依赖关系,那么它们应该通过主define([dependancies], fnDefinition)函数传递,而不是require()按照上面的示例在其中传递。

这背后有什么原因吗?

4

1 回答 1

28

您可能想require()在模块中使用有几个原因。

但首先,请确保您请求引用正确的require变量。在您的示例中,对的引用require全局. 您需要对require范围为模块上下文的 a 的引用(有时称为“本地要求”)。这很简单:

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 */ 
}); 

这很重要的主要原因是确保正确解析相关模块 ID(例如“./peerModule”或“../unclePath/cousinModule”)。(这是原因之一,curl.js 默认没有全局变量require。)


使用本地的原因require

  1. 由于运行时条件,您不知道在构建时(或加载时)需要哪些模块
  2. 您明确希望将某些模块的加载推迟到需要它们时
  3. 您想根据特征检测的结果加载模块的变体(尽管类似 dojo 的“有!”插件可能是更好的解决方案(抱歉,链接躲避我))

require最后,为了与 CommonJS Modules/1.1 中编写的模块兼容,AMD 定义了第二种用法,然后将其包装在define. 这些看起来像这样:

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

服务器端 javascript 开发人员可能会发现这种格式很有吸引力。:)

一些 AMD 加载程序(例如 RequireJS 0.2+、dojo 1.7+、bdLoad 和 curl.js 0.6+)将检测这种混合 AMD/CJSM1.1 格式并通过扫描模块的require调用来查找依赖项。

于 2011-10-20T11:43:25.363 回答