使用requireJS的模块定义的差异

时间:2014-08-29 17:37:38

标签: javascript requirejs amd commonjs

requireJS给我一个令人头疼的问题。 requireJS是AMD,根据定义,它说它是异步的。通常我会定义一个这样的模块。

define("some Name", ["./moduleOne"],function(moduleOne){

  //this would be undefined
  moduleOne.whatEver();  

  var aMethod = function(){
    //user aModule.whatever();
  }

  return {
    method: aMethod;
  }
});

好吧,我知道我不能直接使用moduelOne.whatever因为它是异步加载的,如果调用回调则它不存在。

第一个问题,这是正确的吗?

现在,如果我将模块定义更改为:

define("some Name", function(require, exports){

  var moduleOne = require(".moduleOne");      

  //this is OK
  moduleOne.whatEver();  

  var aMethod = function(){
    //user aModule.whatever();
  }

    exports.method = aMethod;
});

我可以直接使用aModule.whatever。当我从文档中读到时,使用这个(commonJS)样式,需要使用Function.prototype.toString解析函数,查看require语句并直接加载模块。

我很确定,我在这里误解了一些东西,如果有人可以解释究竟requireJS是如何工作的,以及第二种风格是否真的同步,那将是很好的。

由于

1 个答案:

答案 0 :(得分:3)

你误解了它是如何运作的。

两个示例中,您在问题中提供了执行顺序:

  1. 某些东西需要名为some_Name的模块。 (我不认为RequireJS对包含空格的模块名称感到满意,所以我假设模块名称带有下划线。)

  2. RequireJS查找模块some_Name的依赖项和工厂函数。工厂是定义模块时define给出的函数。

    一个。如果define("some_Name"...在此步骤之前被称为,则RequireJS只会获取给予define的依赖项和工厂函数。

    湾如果尚未执行define("some_Name"...,则RequireJS将转到网络并尝试获取包含define调用的文件并执行它。按照惯例,这将是一个与模块名称+ .js扩展名相同的文件,但这可以在RequireJS配置中覆盖。

  3. RequireJS检查是否加载了依赖项。如果没有,则它会针对尚未加载的每个依赖项发出require次调用。

  4. RequireJS使用已解析的依赖项调用工厂函数。

  5. 请注意,我没有在这里讨论所有可能的情况。我坚持使用最常见的案例来保持简单。

    因此...

      

    好吧,我知道我不能直接使用moduelOne.whatever因为它是异步加载的,如果调用回调则不存在。

         

    第一个问题,这是正确的吗?

    不,这不正确。在moduleOne.whatEver();执行时,模块moduleOne必须已加载。如果moduleOneundefined,则,因为RequireJS具有异步性,但因为moduleOne的定义存在错误。例如,如果它导出值undefined,则moduleOne将是未定义的。或者,您可能会获得undefined的{​​{1}}值,这会在您尝试调用时导致错误,但这可能是由于忘记导出moduleOne.whatEver而造成的。 / p>

    第二种情况和第一种情况之间的区别在于第二种情况使用CommonJS糖语法,这导致上面的步骤2进行了一些额外的处理。在RequireJS执行工厂之前,它解析函数(如你所提到的),然后处理工厂函数,就好像已经按照这样调用定义的那样:

    whatEver

    define("some_Name", ['require', 'exports', './moduleOne'], function (require, exports) { require模块是RequireJS内部定义的特殊模块。请注意RequireJS如何在依赖项列表的末尾添加exports。完成后,该过程与第一种情况完全相同。

    执行./moduleOne时,模块已加载。所以这一行的作用仅仅是返回对模块的引用。