Require.js要求/定义缺少参数的后果

时间:2014-08-07 20:27:38

标签: javascript requirejs amd scoping

我遇到了各种与竞争条件和我的Web应用程序的范围问题有关的问题,使用require.js来管理依赖项。

我一直在尝试清理和优化代码库,并引入r.js作为控制页面加载时生成的大量请求的机制(加载依赖项)。

问题

未能在模块定义中明确声明参数的后果是什么:

define([
    "jquery",
    "app/modules/validation",
    "jquery.chosen"
], function(
    $,
    Validation,
    // note missing parameter
) { //stuff here });

或者像这样的必需声明:

require([
    "jquery",
    "app/modules/validation",
    "jquery.chosen"
], function(
    $,
    Validation,
    Chosen
) {
    // the 'chosen' object here is actually referencing the object defined in the other module
});

我在我的应用程序中发现了很多问题,并且我想知道上述内容是否应该受到指责?似乎未能包含参数允许它泄漏范围?这可能吗?

修改 我试图避免这种情况变成'debug my require.js'配置但是我们走了:

我的config.js

requirejs.config({
    paths: {
        jquery: 'jquery-shim',
        'jquery.chosen':'chosen/chosen.jquery',
        'jquery.validity': 'lib/jquery.validity'
    },
    shim: {
        'jquery.chosen': ["jquery"],
        'jquery.validity': {
            deps: ["jquery"],
            exports: "jQuery.fn.validity"
        }
    }
});

正如您所看到的,jQuery目前已经出现以下别名 - 我认为这可能是问题所在:

//jquery-shim.js     

 define([], function() {
    return window.jQuery;
 });

当我在html中加载require.js时,它看起来像这样: 正如您所看到的那样,jquery正在使用require.js加载 - 原因是当加载require.js时,它不会绑定到DOMContentLoaded事件,因此绑定到jQ.ready的所有其他代码永远不会执行:

<script src="{{ asset('assets/js/jquery/dist/jquery.min.js') }}"></script>
<script src="{{ asset('assets/js/requirejs/require.js') }}"></script>
<script>
require(['app/site_core'], function (common) {
    require(['app/default']);        
});
</script>

2 个答案:

答案 0 :(得分:1)

这在很大程度上取决于你的“stuff here”。由于您不包含此信息,我将尝试涵盖所有组合:

  1. 您需要jquery.chosen,您将其绑定到工厂函数参数(例如“Chosen”)并使用它。这是正常的使用模式。
  2. 你需要jquery.chosen,你将它绑定到工厂函数参数(例如“Chosen”),但你没有在函数内部使用它。从依赖项列表中删除它 - 不需要使模块签名混乱。
  3. 您需要jquery.chosen,而不是将其绑定到工厂函数参数,但无论如何都不要使用此依赖项。与2类似:删除所有不需要的依赖项以保持代码清洁。
  4. 您需要jquery.chosen,而不是将其绑定到工厂函数参数但是您正在使用它。这是一个潜在的致命场景,取决于插件的编写方式,它可以在某些时候工作,因为JavaScript引擎将尝试查找指向所有已知范围的指定变量,从本地开始到window范围结束。你很幸运它会立即失败,但是如果你选择了一个存在于全局范围内的变量名,你将使用它来跳过AMD机制,导致意想不到的怪癖和时间敏感问题。
  5. 最后两个变体也很危险,因为您在以后添加新依赖项时可能不会注意到不匹配,从而导致混淆错误,例如:

    define([
      "jquery",
      "app/modules/validation",
      "jquery.chosen",
      "underscore",
    ], function($, Validation, _) {
      //_ variable refers to jQuery.chosen due to the mismatch
    });
    

    不确定上次评论中“其他模块”的含义:“此处'选择'对象实际上是引用其他模块中定义的对象

答案 1 :(得分:0)

  

未明确声明参数

的后果是什么?

无论如何,直到你想在你的函数中使用它,但不能,因为你没有引用它。 RequireJS不会反对,也不会被置于某个有问题的状态,因为你缺少一个参数。 AMD模块的合法使用案例没有返回值,其效果是某种副作用,例如装饰不同的AMD模块。

在没有看到任何代码的情况下,我可能会猜测你的问题很可能是因为你的jquery插件没有在AMD中正确加载jQuery - 很可能是noconflict的使用不当,指定加载失败通过shims订购,或全局问题。有关详细信息,请参阅RequireJS的instructions for jQuery

修改: 您的配置似乎没有任何明显错误,除非我没有看到对r.js生成的图层的引用,除非app/site_core是您的图层。在需要包含其中的模块之前,应确保需要该层。 RequireJS config可以用来优雅地做到这一点。

以下是从RequireJS文档修改的。请注意,该图层被指定为依赖项。

var require = {
    deps: ["my/layer"],
    callback: function(module1, module2) {
        //This function will be called when all the dependencies
        //listed above in deps are loaded. Note that this
        //function could be called before the page is loaded.
        //This callback is optional.
    }
};