【问题标题】:RequireJS - define function is not returning dependencies correctlyRequireJS - 定义函数没有正确返回依赖项
【发布时间】:2017-12-04 21:03:22
【问题描述】:

我正在使用 RequireJS,当我使用“define”函数定义一个新模块时,我看到依赖关系已解决,但对象不是我定义的模块。

所有模块都以 AMD 格式定义,设置名称、依赖项数组和函数。导出是通过返回一个对象来完成的。

“define”解析的依赖项具有以下属性:exports、id、packaged 和 uri。如果我然后调用 require 函数,则依赖项设置正确。

更新:我用所描述的问题创建了一个测试示例

HTML:

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Test</title>
    <script src="/Scripts/require.js" data-main="../Scripts/main"></script>
    <script src="/Scripts/module.js"></script>
</head>
<body>
    <div> 
    </div>
</body>
</html>

main.js:

require(["module"], function (module) {
    module.test();
});

module.js:

define([], function () {

    function test() {
        return "a";
    }

    return {
        test: test
    };
});

控制台: 未捕获的 TypeError:module.test 不是函数

发生这种情况是因为模块没有解析为真正的模块,而是解析为具有属性的对象:

-config { 参数:null,调用者:null,长度:0,名称:“config”}

-exports { id: "@r5", uri: "../Scripts/@r5.js" }

在define函数中设置模块名也一样。

注意:在示例中,@Louis 检测到了一个问题。模块不能命名为“模块”。这帮助我修复了示例,但没有解决我的真正问题。下面我描述一下解决方案。

解决方案:

我的问题与名为 Ace(HTML 编辑器)的库有关。这是帮助我解决它的链接:https://github.com/josdejong/jsoneditor/issues/173

【问题讨论】:

  • 你需要的配置是什么样的?你为什么在一个地方使用bConfig而在另一个地方使用builderConfiguration?它们是一样的吗?
  • 那是问题中的错字,我已经修正了。我没有要求配置,这是强制性的吗? require 函数可以正确解析依赖关系,因此 define 应该以同样的方式进行。我正在使用捆绑包来加载文件。
  • 不,define 不应该,因为 require 可以。您必须了解require.js 如何通过设置path(绝对或相对)来定位模块。如果您没有收到无法加载 bConfig 模块的故障,或者根据您的 require.config 设置规范化为模块,那么我能想到的唯一问题是您的项目中有多个 bConfig.js 文件目录。否则没有意义。
  • 我没有多个 bConfig.js 文件。没有错误,问题是如何使用我在问题中指定的属性将对象解析为其他内容。
  • 在您使用minimal reproducible example 编辑问题之前,您只会得到猜测。我使用 RequireJS 多年,但从未见过您描述的行为,目前问题中的代码中没有任何内容可以解释 为什么 您会得到您描述的行为。 (回答前面评论中的一个问题:如果默认值恰好是您所需要的,您绝对可以在不显式设置配置的情况下运行 RequireJS。)

标签: javascript requirejs amd


【解决方案1】:

通过您所做的编辑,现在可以诊断问题。 不要命名任何模块用名称module写,问题就会消失。

名称module 是三个保留模块名称之一:modulerequireexports。你永远不应该用这些名字命名你自己的任何模块。

当你要求 RequireJS 加载 module 时,它并没有加载你的模块。相反,它只是返回一个内部结构,该结构旨在提供有关当前模块的信息。它有像id这样的字段,它给出了当前的模块ID(即模块名称)和url,它给出了加载模块的URL等等。

【讨论】:

  • 您对模块产生冲突并引导我找到项目中的真正问题是正确的。我指的是一个名为 Ace(HTML 编辑器)的库,但与它存在冲突)。谢谢!
【解决方案2】:

好的,看完之后

属性:exports、id、packaged 和 uri。

我猜,就像@Louis 所说的那样,OP 问题中的示例不是 OP (测试)项目中的示例。

定义模块时,有两种(以及更多)通用方法。

在标题为CommonJSdocs 中解释了它们。

如果一个模块是用

定义的
define(function(require, exports, module) {

   console.log(module);

});

那么第三个参数module 将确实包含exports, id and uri

{
   config: function config()
   exports: Object {  }
   id: "js/modules/handgrip/index.js?bust=1512509846564"
   uri: "js/modules/handgrip/index.js?bust=1512509846564&bust=1512509846564"
}

为了在给定的上下文中“返回”你的模块,你可以export它与

define(function(require, exports, module) {

   // require a depedency already loaded in context
   var someDep = require('someDep1');

   module.exports = {
      // whatever this module is about ..
   }
});

仅当您使用名称定义模块时,后跟依赖项,如

define('thename', [ 'someDep1', 'seomDep2', 'etc..' ], function(dep1, dep2, ..) {

   // the arguments in this context are those listed in order as defined in the array (parameters)

}

你得到了预期的结果..

--编辑后更新

当时在 Scrum 会议上,抱歉 ;) 正如@Louis 所写,这很清楚。

moduleexportsrequire 是保留字。

以下结果相同

define(['require', 'exports', 'module'], function(require, exports, module) {
  console.log(module);
});

define(function(require, exports, module) {
  console.log(module);
});

【讨论】:

  • 我正在使用最后一个选项,使用模块名称和依赖项进行定义。我不明白为什么这会解决我描述的问题。为什么我的模块具有exports、id、packaged 和uri 等属性,而不是真实属性?为什么当我使用 require(...) 来明确地获取它们时它可以工作?
  • @FranciscoGoldenstein 除非您的代码是最高机密,否则没有人可以帮助您,伙计;)
  • 这不是最高机密 :) 这是一个大项目,都在一个文件中,我将它分成多个文件,定义模块并实现 RequireJS。很难给你真正的代码,因为它是一个巨大的应用程序。我认为我的问题已经足够好了。
  • @FranciscoGoldenstein 可以预料这是一个巨大的项目。尽管应该知道 de 依赖数组中给出的模块,但在您的示例 bConfig 中,问题可能在任何地方,但只是出错的代码的一部分,例如声明顺序模块以及如何导出它们的定义(例如工厂等)会有所帮助。你是这个捆绑包的作者吗?
  • 我在问题中添加了更多信息。定义为 AMD 格式,并通过返回一个对象来完成导出。大部分 JS 代码不是我写的,我只是继承了它,我正在重构,所以开发者不需要一个月的时间来理解它。
猜你喜欢
  • 2016-10-16
  • 1970-01-01
  • 2015-03-11
  • 1970-01-01
  • 2014-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多