使用requireJS的模块定义的差异

Difference of module definitions using requireJS

本文关键字:定义 模块 requireJS 使用      更新时间:2023-09-26

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. 有些东西需要名为some_Name的模块。(我认为RequireJS不喜欢有空格的模块名称,所以我假设模块名称带有下划线。)

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

    a。如果碰巧define("some_Name"...在这一步骤之前被调用,那么RequireJS只获取给define的依赖项和工厂函数。

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

  3. RequireJS检查依赖项是否已加载。如果没有,那么它会为每个尚未加载的依赖项发出require调用。

  4. RequireJS调用具有已解析依赖关系的工厂函数。

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

所以。。。

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

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

不,这是不对的。执行moduleOne.whatEver();时,模块moduleOne必须已加载。如果moduleOneundefined,则这是而不是,因为RequireJS的异步性质,而是因为moduleOne的定义方式存在错误。例如,如果它导出值undefined,那么moduleOne将是未定义的。或者,您可能会为moduleOne.whatEver获得一个undefined值,然后在尝试调用它时会导致错误,但这可能是由于忘记导出whatEver等原因造成的。

第二种情况与第一种情况的区别在于,第二种使用CommonJS sugar语法,这导致上面的步骤2需要一些额外的处理。在RequireJS执行工厂之前,它解析函数(正如您所提到的),然后处理工厂函数,就好像定义的函数被这样调用一样:

define("some_Name", ['require', 'exports', './moduleOne'], function (require, exports) {

requireexports模块是RequireJS内部定义的特殊模块。请注意RequireJS是如何在依赖项列表的末尾添加./moduleOne的。一旦完成,过程与第一种情况完全相同。

当执行var moduleOne = require("./moduleOne");时,模块已经加载。因此,这行所做的只是返回对模块的引用。