requireJSとjQueryを一緒に使用するにはどうすればよいですか?


82

requireJSを使用したいのですが、jQueryを使用しています。最新のjQueryバージョンを使用していないため、requireJSとjQueryを組み合わせたバージョンを使用したくありません。requireJSを使用するための最良の方法は何ですか?


2
最新のjQueryを使用できない理由は何ですか?
シークレット2010

jQuery1.3.8を使用しています。このバージョンは、1.4.Xとは少し異なります。最新のjQueryを使用するために、いくつかのコードを更新する必要がありますが、今はそのための時間がありません。また、パッケージを組み合わせるのは正しいことではないと思います。
Naor 2010

以下の答えは良いです...なぜあなたはそれを正しいとマークしなかったのですか?
Prisoner ZERO

@Prisoner ZERO:正直なところ、私はそれをテストすることができませんでした。私は最近、マイクロソフトのajaxスクリプトローダーを使用しました。この答えをマークするように私に思い出させてくれてありがとう。あなたがそれが素晴らしいと言ったなら-私はあなたを信じています。
Naor

また、requirejsを他のライブラリで使用するのは難しいと感じました。逆もまた同様です。そのため、はるかに使いやすく、Angularでテストされたライブラリを作成しました。下部にデモアプリケーションがあります:gngeorgiev.github.io/Modulerr.js Modulerr.jsに依存せずにすべてのスクリプトを1つに結合することもできます
Georgi-it

回答:


130

それは私の正確な質問でもあります!また、古いjQueryを使用する必要がありますが、より「従来の」javascriptライブラリも使用する必要があります。それを行うための最良のテクニックは何ですか?(よろしければ、質問を編集してより広範にすることもあります。)これが私が学んだことです。

RequireJSの作成者であるJamesBurkeが、RequireJS + jQueryファイルを組み合わせ利点について説明しました。あなたは2つのことを得る。

  1. モジュール、jqueryが利用可能であり、それはjQueryオブジェクトです。これは安全です:

    // My module depends on jQuery but what if $ was overwritten?
    define(["jquery"], function($) {
      // $ is guaranteed to be jQuery now */
    })
    
  2. jQueryは、require()または何かの前にすでにロードされていdefine()ます。すべてのモジュールは、jQueryの準備ができていることが保証されています。require/order.jsjQueryは基本的に最初にロードするようにハードコードされているため、プラグインも必要ありません。

私にとって、#2はあまり役に立ちません。ほとんどの実際のアプリケーションには、正しい順序でロードする必要のある多くの .jsファイルがあります。悲しいですが本当です。SammyまたはUnderscore.jsが必要になるとすぐに、RequireJS + jQueryファイルを組み合わせても役に立ちません。

私の解決策は、「order」プラグインを使用して従来のスクリプトをロードする単純なRequireJSラッパーを作成することです。

私のアプリにこれらのコンポーネントがあるとします(依存関係による)。

  • 私のアプリ、greatapp
    • greatappはカスタムjqueryに依存します(私が使用しなければならない古いバージョン)
    • greatappはmy_sammy(SammyJSと使用する必要のあるすべてのプラグイン)に依存します。これらは順番になっている必要があります
      1. my_sammyはjqueryに依存します(SammyJSはjQueryプラグインです)
      2. my_sammyはsammy.jsに依存します
      3. my_sammyはsammy.json.jsに依存します
      4. my_sammyはsammy.storage.jsに依存します
      5. my_sammyはsammy.mustache.jsに依存します

私の考えで.jsは、それ以上で終わるものはすべて「従来の」スクリプトです。ないもの.jsはすべてRequireJSプラグインです。重要なのは、高レベルのもの(greatapp、my_sammy)はモジュールであり、より深いレベルでは、従来の.jsファイルにフォールバックすることです。

起動

それはすべて、RequireJSに開始方法を指示するブーターから始まります。

<html>
  <head>
    <script data-main="js/boot.js" src="js/require.js"></script>
  </head>
</html>

ではjs/boot.jsIのみ設定し、どのようにアプリケーションを起動するに置きます。

require( // The "paths" maps module names to actual places to fetch the file.
         // I made modules with simple names (jquery, sammy) that will do the hard work.
         { paths: { jquery: "require_jquery"
                  , sammy : "require_sammy"
                  }
         }

         // Next is the root module to run, which depends on everything else.
       , [ "greatapp" ]

         // Finally, start my app in whatever way it uses.
       , function(greatapp) { greatapp.start(); }
       );

主な用途

greatapp.js、私の正常探してモジュールを持っています。

define(["jquery", "sammy"], function($, Sammy) {
  // At this point, jQuery and SammyJS are loaded successfully.
  // By depending on "jquery", the "require_jquery.js" file will run; same for sammy.
  // Those require_* files also pass jQuery and Sammy to here, so no more globals!

  var start = function() {
    $(document).ready(function() {
      $("body").html("Hello world!");
    })
  }

  return {"start":start};
}

従来のファイルのRequireJSモジュールラッパー

require_jquery.js

define(["/custom/path/to/my/jquery.js?1.4.2"], function() {
  // Raw jQuery does not return anything, so return it explicitly here.
  return jQuery;
})

require_sammy.js

// These must be in order, so use the "order!" plugin.
define([ "order!jquery"
       , "order!/path/to/custom/sammy/sammy-0.6.2-min.js"
       , "order!/path/to/custom/sammy/plugins/sammy.json-0.6.2-min.js"
       , "order!/path/to/custom/sammy/plugins/sammy.storage-0.6.2-min.js"
       , "order!/path/to/custom/sammy/plugins/sammy.mustache-0.6.2-min.js"
       ]

       , function($) {
           // Raw sammy does not return anything, so return it explicitly here.
           return $.sammy;
         }
      );

5
この答えの良い仕事...うまくいけば、質問者はこれをマークします!
Prisoner ZERO

実際のjqueryファイルに応じてrequire_jqueryモジュールを作成しますが、jqueryはグローバルのままではありませんか?カスタムパスからロードする実際のjqueryファイル1.4.2はrequire.jsモジュールではありませんか?または、requireをそのファイルにラップしましたか?
サンダー2011

3
jQuery(1.7)の最新バージョンでは、すでにモジュールがサポートされているため、通常どおりに必要なだけで機能します。
MikeMurko 2011

1
AMDをサポートするrequireJS2(w / shim)+ jQuery 1.7+の実行方法を反映するために、誰かがこの回答を更新できますか?
ヘンリー

1
私は最善の方法は、非AMD JavaScriptファイルとの依存関係のサポートは今で達成することを指摘したいと思いシム設定が2.0+ RequireJSで見つかったあなたはまだ1.1必要使用している場合は、シムに前駆体を使用することができます、wrapjs
Johann

32

この質問は少なくとも2年前のものですが、これがRequireJS 2.0の問題であることに気付きました(require-jquery.jsはjQuery 1.8.0を使用しますが、最新バージョンは1.8.2です)。

この質問が表示された場合は、require-jquery.jsがrequire.jsとjquery.jsだけになり、マッシュアップさ れていることに注意してくださいrequire-jquery.jsを編集して、jQueryパーツを新しいバージョンに置き換えるだけです

更新(2013年5月30日):RequireJSにパスとシムが追加されたため、jQueryおよびjQueryプラグインをインポートする新しい方法があり、古い方法は不要になり、推奨されなくなりました。現在のメソッドの要約版は次のとおりです。

requirejs.config({
    "paths": {
      "jquery": "//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min"
    }
});

define(["jquery"], function($) {
    $(function() {
    });
});

詳細については、http://requirejs.org/docs/jquery.htmlを参照してください。


おかげで、これはまだ関連しています:)
Naor 2012

まだjQuery1.3.8を使用していますか?:)
クリス

これを指摘していただきありがとうございます。1.8の古いバージョンには、最新で解決された問題があることを読みました。
ブレインマックロウ2012

確かに。それらはcurCSSのjQueryUIの問題ではありませんでしたか?
クリス

1
@AHMED:どちらも機能します。違いは、defineがモジュールを明示的に指定することです。パスについてより明確であるため、defineをほぼ排他的に使用することを好む傾向があります:stackoverflow.com/questions/16087635/…–
Chris

9

最善のアプローチは、jQueryをRequireJSビルドの外に置くことです。

HTMLにjquery.min.jsを含めるだけです。次に、次のようなjquery.jsファイルを作成します...

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

従来はスクリプトタグを使用してロードする必要のあるJSファイルがいくつかあり、それらはjQueryに依存しているため、これは適切な回避策です。
jingtao 2014年

3

JasonSmithの回答は非常に役立ち、おそらくRequireJSのドキュメントよりも役立つことがわかりました。

ただし、(小さな)定義宣言モジュール( "require_jquery" "require_sammy")に対して個別のAJAXリクエストが発生しないように最適化する方法があります。r.jsは最適化の段階でそれを行うと思いますが、Path、BaseURIシステムと戦わないように、事前にそれを行うことができます。

index.html:

<html>
  <head>
    <script data-main="js/loader.js" src="js/require.js"></script>
  </head>
</html>

loader.js:

// We are going to define( dependencies by hand, inline.
// There is one problem with that through (inferred from testing):
// Dependencies are starting to load (and execute) at the point of declaring the inline
// define, not at the point of require(
// So you may want to nest the inline-defines inside require( 
// this is, in a way, short replacement for Order plug in, but allows you to use
// hand-rolled defines, which the Order plug in, apparently does not allow.

var jQueryAndShims = ['jquery']

if(window.JSON == null){
    jQueryAndShims.push('json2')
    define(
        'json2'
        , ['js/libs/json2.min.js']
        , function() {
            return window.JSON
        }
    )
}
// will start loading the second we define it.
define(
    'jquery'
    , ['js/libs/jquery_custom.min.js']
    , function() {
        // we just pick up global jQuery here. 
        // If you want more than one version of jQuery in dom, read a more complicated solution discussed in
        // "Registering jQuery As An Async-compatible Module" chapter of
        // http://addyosmani.com/writing-modular-js/
        return window.jQuery 
    }
)

// all inline defines for resources that don't rely on other resources can go here.

// First level require(
// regardless of depends nesting in 'myapp' they will all start downloading 
// at the point of define( and exec whenever they want, 
// async in many browsers. Actually requiring it before the nested require makes
// sure jquery had *executed and added jQuery to window object* before
// all resolved depends (jquery plugins) start firing.
require(jQueryAndShims, function($) {

    // will start loading the second we define it.        
    define(
        'sammy_and_friends'
        , ['jquery','js/libs/jquery_pluginone.min.js','js/libs/jquery_plugintwo.min.js','js/libs/sammy.min.js']
        , function($) {
            // note, all plugins are unaltered, as they are shipped by developers.
            // in other words, they don't have define(.. inside.
            // since they augment global $ (window.jQuery) anyway, and 'jquery' define above picks it up
            // , we just keep on returning it.
            // Sammy is attached to $ as $.sammy, so returning just Sammy makes little sense
            return $
        }
    )

    // second level require - insures that Sammy (and other jQuery plugins) - 'sammy_and_friends' - is
    // loaded before we load Sammy plugins. I normally i would inline all sammy plugins i need 
    // (none, since i use none of them preferring jQuery's direct templating API
    // and no other Sammy plug in is really of value. )  right into sammy.js file. 
    // But if you want to keep them separate:
    require(['sammy_and_friends'], function() {

        // will start loading the second we define it.
        define(
            'sammy_extended'
            , ['sammy_and_friends','js/libs/sammy_pluginone.min.js','js/libs/sammy_plugintwo.min.js']
            , function($) {
                // as defined above, 'sammy_and_friends' actually returns (globall) jQuery obj to which
                // Sammy is attached.  So we continue to return $
                return $
            }
        )
        // will start loading the second we define it.
        define(
            'myapp'
            , ['sammy_extended', 'js/myapplication_v20111231.js'] 
            , function($, myapp_instantiator) {
                // note, myapplication may, but does not have to contain RequireJS-compatible define
                // that returns something. However, if it contains something like 
                // "$(document).ready(function() { ... " already it MAY fire before 
                // it's depends - 'sammy_extended' is fully loaded.
                // Insdead i recommend that myapplication.js returns a generator 
                // (app-object-generating function pointer)
                // that takes jQuery (with all loaded , applied plugins) 
                // The expectation is that before the below return is executed, 
                // all depends are loaded (in order of depends tree)
                // You would init your app here like so:
                return myapp_instantiator($)
                // then "Run" the instance in require( as shown below
            }
        )

        // Third level require - the one that actually starts our application and relies on
        // dependency pyramid stat starts with jQuery + Shims, followed by jQuery plugins, Sammy, 
        // followed by Sammy's plugins all coming in under 'sammy_extended'
        require(['jquery', 'myapp'], function($, myappinstance) {
            $(document).ready(function() {myappinstance.Run()})
        })
    }) // end of Second-level require
}) // end of First-level require

最後に、myapplication.js:

// this define is a double-wrap.
// it returns application object instantiator that takes in jQuery (when it's available) and , then, that
// instance can be "ran" by pulling .Run() method on it.
define(function() {
    // this function does only two things:
    // 1. defines our application class 
    // 2. inits the class and returns it.
    return function($) {
        // 1. defining the class
        var MyAppClass = function($) {
            var me = this
            this._sammy_application = $.sammy(function() {
                this.raise_errors = true
                this.debug = true
                this.run_interval_every = 300
                this.template_engine = null
                this.element_selector = 'body'
                // ..
            })
            this._sammy_application.route(...) // define your routes ets...
            this.MyAppMethodA = function(blah){log(blah)}  // extend your app with methods if you want
            // ...
             // this one is the one we will .Run from require( in loader.js
            this.Run = function() {
                me._sammy_application.run('#/')
            }
        }
        // 2. returning class's instance
        return new MyAppClass($) // notice that this is INITED app, but not started (by .Run) 
        // .Run will be pulled by calling code when appropriate
    }
})

この構造(RequireJSのOrderプラグインを大まかに置き換えます(重複しますか?))を使用すると、AJAXに必要なファイル数を削減して、依存ツリーと依存ツリーの定義をより細かく制御できます。

jQueryを個別にロードすることにも大きなボーナスがあります(通常は100kで提供されます)。サーバーでのキャッシュを制御したり、jQueryをブラウザーのlocalStorageにキャッシュしたりできます。ここhttps://github.com/jensarps/AMD-cacheでAMD-Cacheプロジェクトを見て から、define(ステートメントを「cache!」を含むように変更してください:そしてそれは(永遠に:))ユーザーのブラウザでスタックします。

define(
    'jquery'
    , ['cache!js/libs/jquery_old.min.js']
    , function() {
        // we just pick up global jQuery here. 
        // If you want more than one version of jQuery in dom, read a more complicated solution discussed in
        // "Registering jQuery As An Async-compatible Module" chapter of
        // http://addyosmani.com/writing-modular-js/
        return window.jQuery 
    }
)

jQuery 1.7.x +に関する注意事項ウィンドウオブジェクトにアタッチされなくなったため、上記は変更されていないjQuery 1.7.x +ファイルでは機能しません。そこで、jquery **。jsをカスタマイズして、 "})(window);"を閉じる前にこれを含める必要があります。

;window.jQuery=window.$=jQuery

コンソールに「jQueryundefined」エラーがある場合は、使用しているjQueryバージョンがウィンドウにアタッチされていないことを示しています。

コードライセンス:パブリックドメイン。

開示:上記のJavaScriptは、はるかに詳細な製品コードの言い換え(手作業による剪定)であるため、「擬似コード」のにおいがします。上記のコードは動作が保証されておらず、表示どおりに動作するようにテストされていません。監査し、テストします。セミコロンはJS仕様では必須ではなく、セミコロンがないとコードの見栄えが良くなるため、意図的に省略されています。


RequireJS(定義を尊重せず、順序が狂ってロードされているもの、ネストが必要、その他の魔法の不正行為)と戦った後、Curl.JSに切り替えて、夜はぐっすり眠り始めました。それは誇大宣伝ではありませんが、くそー、それは安定していて扱いやすいです!
ddotsenko 2012

1

jhsの回答に加えて、README.mdファイルのrequire- jquerygithubページにある最新の手順を参照してください。結合されたjquery / require.jsファイルを使用する最も単純なアプローチと、個別のjquery.jsを使用する方法の両方について説明します。

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