requirejsでjQueryプラグインをロード可能にする方法


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と互換にする唯一の方法である場合

回答:


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を含める前の任意の場所(たとえば、data-mainが指す場所など)。

あなたが投稿した最後のコードブロックは、jQueryのようなものに再配布され、AMD環境にある場合とない場合があります。理想的には、すべてのjQueryプラグインですでに設定されているはずです。

含まれているライブラリをできるだけ純粋なものにしておくことを好むので、ページごとに1回のグローバルシム構成は、私にとって最もクリーンなソリューションのようです。そうすれば、アップグレードがより安全になり、CDNが可能になります。


1
定義とシムの両方が機能しない場合、機能しません$ .cookieが機能エラーメッセージではありません
Nicola Peluchetti

私の経験では、定義関数から何も返さないだけでは不十分で、requirejsはモジュールがロードされたことを認識しません。これは、shimによって起動することができます:{plugins:{depends:['jquery']、exports: 'plugins'}
honzajde

jQueryプラグインスクリプトを実際に実行する必要があることに注意してください。私は専門家でrequire(['plugin1', 'plugin2']);はありませんが、1つなどがある単純な解決策を見つけました。コールバックが渡されないため、プラグインスクリプト自体以外は何も実行されません。これは、それらが自分自身を追加することを意味しjQuery.fnます。他の場所では、依存関係として「jquery」をリストするだけで、それらが含まれます。私が言ったように、私はこれにかなり慣れており、より良いアプローチ(scriptタグを使用するなど)があるかもしれませんが、これはうまくいきます。
Joshua Bambrick 2013年

3
Josh:すべてが正しい順序で読み込まれることを賭けています。あなたのサイトの何人かのユーザーはおそらく壊れたものを見ています。問題は、限りではないこと、それはだ、プラグインのロード時にプラグインがロードされ、他に何時に実行されています。requireを使用する主な理由は、当て推量ではなく、依存関係に基づいて適切な操作順序を保証するためです。
ハンス

104

http://requirejs.org/docs/api.html#config-shimで指摘されている、RequireJSでのシム構成の使用にはいくつかの注意事項があります。つまり、オプティマイザを使用しているときは、「ビルドでCDNのロードとシム構成を混在させないでください」。

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最初の行の関数引数は、それ自体が$引数にプラグインを定義するために呼び出される関数です。AMD互換ローダーが存在しない場合は、グローバルjQueryオブジェクトにプラグインを定義するために直接呼び出されます。これは、一般的なプラグイン定義のイディオムと同じです。

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

モジュールローダーがある場合は、factoryjQueryのロード後にローダーが呼び出すコールバックとして登録されます。ロードされたjQueryのコピーが引数です。それは同等です

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

3
質問はjQueryプラグインに関するものでしたが、これはjQueryだけでなく、あらゆる種類のモジュールまたはライブラリで機能するため、この回答が好きです。コードに頭を回すのに1分かかりましたが、一度行ったら、それは完全に理にかなっています。
Adam Tuttle 2013

1
それは間違いなく不可解なJavaScriptです。それがどのように機能するかについてのいくつかの説明を追加しました。
カールレイモンド

これを実行し、jQuery または Zepto で動作するプラグインを作成するためのヒントはありますか?非AMDコードをfactory(jQuery || Zepto);に簡単に置き換えることができますが、AMD部分をどのように実行するかはわかりません。jQueryの「パス」をzeptoに設定する必要があると思いますか? paths: { jquery: 'vendor/zepto/zepto.min' }
Ryan Wheale、2014

うわー、私はずっとこのコードの断片を理解したいと思っていました。どうもありがとうございshimます。本質的にそれだけではありませんか?上記のように手動でコーディングしているとおっしゃっていたからです。
ユージーン

私のような馬鹿のための助言:それ$.fn.jqueryPluginがスニペットで言うところjqueryPlugin、プラグイン名に変更してください!!
Matt Lacey

2

すべてのjqueryプラグインのFYIと同じように、すでにamd / requireを使用しているため、shimで何も宣言する必要はありません。実際、これを行うと、場合によっては問題が発生する可能性があります。

jquery Cookie JSを見ると、define呼び出しとrequire(["jquery"])が表示されます。

jquery.jsには、define( "jquery"、[]、function()...の呼び出しが表示されます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.