RequireJs - 定义 vs 引用

63

对于模块,我使用require而不是define来返回对象。例如,假设我有以下jQuery插件(jquery.my-plugin.js):

require(['jquery'], function($) {
    $.fn.myPlugin = function(options) {
        ...
    };
});

如果我在另一个模块中这样说:

require(['jquery', 'jquery.my-plugin'], function($) {
    $('#element').myPlugin();
});

我发现这不起作用,因为myPlugin还没有被注册。但是,如果我将require更改为在jquery.my-plugin模块内定义,则可以正常运行。

如果有人能解释一下我为什么必须这样做,我会很感激。在我继续使用之前,我想充分理解它。谢谢


3
可能是使用require和define的时候的重复问题。 - Armand
2个回答

109

实际上,当你使用 require 时,你的意思是"我想要这个,但我也要它所有的依赖项"。因此在下面的例子中,我们要求 A,但是 require 会搜索所有依赖项并确保它们在继续之前被加载。

require(['a'], function(a) {
    // b, c, d, e will be loaded
});

// File A
define(['b','c','d','e'], function() {
    return this;
});

通常情况下,当你想定义一个将被你的应用程序重复使用的模块时,你会使用 define,而当你仅需要加载一个依赖项时,则会使用 require


1
谢谢,但为什么我不能在文件A中使用require而不是define呢?本质上,它会做同样的事情,即在执行之前,文件A需要b、c、d和e。 - nfplee
@PaulOsborne:听起来有点像:“如果你有层级关系的东西,使用类定义(module.exports),如果你有常见的可重用工具,则使用通用模块对象(exports)”。也就是说,我们是否总是将 define 和通用模块对象一起使用,将 require 和类定义一起使用? - Sudheer Aedama
在这种情况下,OP中的第二个'require'语句应该是'define',而且不需要列出'jquery'依赖项,因为'jquery'已经是'jquery.my-plugin'的依赖项。 - Niko Bellic
2
@NikoBellic 不,我原始问题中的第一个“require”语句应该使用“define”,因为它是一个依赖项(这个答案中依赖于“文件A”的方式相反)。您是正确的,您不需要重复依赖于“jquery”。 - nfplee
@nfplee 感谢您的回答。是的,我同意您在原始帖子中第一个 'require' 需要是一个 define。请看下面我的回答。让我知道您的想法。我不是100%确定,但我认为 $ 不需要包含在第二个 'require' 中的原因是因为它是全局的。 - Niko Bellic
@nfplee在这种情况下,define和require的调用顺序会是什么样的? - meDeepakJain

5
以下是应该放在 jquery.my-plugin.js 中的代码,它 定义了 一个名为 'jquery.my-plugin' 的模块,可以在其他地方用作依赖项。
define(['jquery'], function($) { //jquery is a dependency to the jquery.my-plugin module
    $.fn.myPlugin = function(options) { //adds a function to the *global* jQuery object, $ (global since jQuery does not follow AMD)
        ...
    };
});

以下是一段代码,您需要将您的插件函数附加到全局jQuery对象,然后使用它...
require(['jquery.my-plugin'], function() { // jquery.my-plugin is loaded which attaches the plugin to the global JQuery object as shown above, then this function fires

    //the only reason $ is visible here is because it's global. If it was a module, you would need to include it as a dependency in the above require statement
    $('#element').myPlugin(); //the $ refers to the global object that has the plugin attached
});

1
一切看起来都很好。是的,$对象在全局范围内定义,所以我想是否在require语句中包含它是可选的。这样做可以避免潜在的库冲突问题,并且与上面的define语句保持一致。 - nfplee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接