如何使jQuery插件可通过requirejs加载


88

我正在使用requirejs + jquery,我想知道是否有一种聪明的方法可以使jQuery插件与require一起很好地工作。

例如,我正在使用jQuery-cookie。如果我理解正确,我可以创建一个名为jquery-cookie.js的文件,然后在里面执行

define(["jquery"], // Require jquery
       function($){
// Put here the plugin code. 
// No need to return anything as we are augmenting the jQuery object
});
requirejs.config( {
    "shim": {
        "jquery-cookie"  : ["jquery"]
    }
} );

我想知道我是否可以做像jQuery这样的事情:

if ( typeof define === "function" && define.amd && define.amd.jQuery ) {
    define( "jquery", [], function () { return jQuery; } );
}

或者这是使jQuery插件与requirejs或任何amd兼容的唯一方法

Answers:


67

您只需要做

define(["jquery"], // Require jquery
       function($){
// Put here the plugin code. 
// No need to return anything as we are augmenting the jQuery object
});

在jquery-cookie.js的末尾,或者

requirejs.config( {
    "shim": {
        "jquery-cookie"  : ["jquery"]
    }
} );

在您包含jquery-cookie之前的任何地方(例如,数据主体指向的任何地方)。

您发布的最后一个代码块适用于jQuery之类的东西,它们可以重新分发,并且可能在AMD环境中也可能不在。理想情况下,每个jQuery插件都应该已经进行了设置。

我更喜欢将包含的库尽可能地保持纯净,因此每页一次的全局填充程序配置对我来说似乎是最干净的解决方案。这样,升级就更安全,而CDN成为可能。


1
如果我没有同时执行定义和填充操作,那么我将获得$ .cookie并非函数错误消息
Nicola Peluchetti 2012年

以我的经验,不从定义函数返回任何信息是不够的,requirejs将无法识别模块已加载。可以通过shim来解决:{插件:{取决于:['jquery'],导出:'plugins'}
honzajde 2013年

您应该注意,jQuery插件脚本需要实际运行。我不是专家,但是我找到了一个简单的解决方案,其中只有一个require(['plugin1', 'plugin2']);等。没有传入回调,因此,除了插件脚本本身之外,什么也不会运行。这意味着它们随后将添加到自己,jQuery.fn以便在其他任何地方都可以将“ jquery”列为依赖项并将它们包括在内。就像我说的那样,我对此很陌生,也许有更好的方法(例如仅使用script标签),但这确实可行。
Joshua Bambrick 2013年

3
乔希:你在赌博,一切都会以正确的顺序加载。您网站上的某些用户可能会看到损坏的内容。问题是没有那么多插件加载,这是插件加载和什么其他的时间执行。使用require的主要原因是确保基于依赖关系而不是猜测的合理操作顺序。
汉斯(Hans)

104

http://requirejs.org/docs/api.html#config-shim指出了在RequireJS中使用垫片配置的一些注意事项。即,在使用优化程序时,“不要在构建中将CDN加载与shim config混合使用”。

我一直在寻找一种在有和没有RequireJS的网站上使用相同的jQuery插件代码的方法。我在https://github.com/umdjs/umd/blob/master/jqueryPlugin.js找到了jQuery插件的代码片段。您将您的插件包装在此代码中,它将以任何一种方式正常工作。

(function (factory) {
if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module depending on jQuery.
    define(['jquery'], factory);
} else {
    // No AMD. Register plugin with global jQuery object.
    factory(jQuery);
}
}(function ($) {

    $.fn.yourjQueryPlugin = function () {
        // Put your plugin code here
    };  

}));

功劳归于jrburke;就像很多javascript一样,它是作用在其他函数上的函数。但是我想我已经解压了它在做什么。

factory第一行中的function参数本身就是一个函数,该函数被调用以在$参数上定义插件。当不存在与AMD兼容的加载器时,将直接调用它以在全局jQuery对象上定义插件。就像常见的插件定义习惯用法一样:

function($)
{
  $.fn.yourjQueryPlugin = function() {
    // Plugin code here
  };
}(jQuery);

如果有模块加载器,则将factory其注册为回调,以供加载器在加载jQuery后调用。jQuery的加载副本是参数。相当于

define(['jquery'], function($) {
  $.fn.yourjQueryPlugin = function() {
     // Plugin code here
  };
})

3
我喜欢这个答案,因为即使问题是关于jQuery插件的,它也适用于任何类型的模块或库,而不仅仅是jQuery。我花了一分钟的时间来整理代码,但是一旦这样做,它就非常有意义了。
亚当·塔特尔

1
绝对是不可渗透的javascript。我添加了一些有关其工作原理的解释。
卡尔·雷蒙德

关于如何执行此操作以及制作与jQuery Zepto 兼容的插件的任何技巧?您可以轻松地用替换非AMD代码factory(jQuery || Zepto);,但是我不知道您将如何处理AMD部分。我认为您必须将jQuery的“路径”设置为zepto? paths: { jquery: 'vendor/zepto/zepto.min' }
Ryan Wheale 2014年

哇,我很久以来一直想了解这段代码。非常感谢,shim本质上不是这样吗?我猜不是..因为您说您正在像上面那样手动编码。
尤金

对像我这样的白痴的提示:在$.fn.jqueryPlugin代码段中的位置,更改jqueryPlugin为插件名称!
马特·莱西

2

正如所有Jquery插件的FYI已经使用amd / require一样,因此您无需在shim中声明任何内容。实际上,在某些情况下,这样做可能会给您带来麻烦。

如果查看jquery cookie JS,将看到define调用和require([“ jquery”])。

在jquery.js中,您将看到对define(“ jquery”,[],function()...的调用。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.