2013-01-07 4 views
6

jqueryを、標準のクロージャを使用して定義された標準で非amd対応のjqueryプラグインと一緒に使用したいとします。(function($))($.fn.myplugin = { ... })(jQuery);はすべてjs/libs/jquery/jquery.myplugin.jsの内部にあります。noConflictモードでjQueryを使用してrequire.jsに非AMD互換のjQueryプラグインをロードする正しい方法はありますか?

私は、この設定を使用

require.config({ 
    baseUrl: 'js/', 
    paths: { 
    'jquery':   'libs/jquery/jquery-noconflict', 
    'underscore':  'libs/underscore/underscore', 
    'backbone':  'libs/backbone/backbone', 
    'jquery-myplugin': 'libs/jquery/jquery.myplugin' 
    }, 
    shim: { 
    'backbone': { 
     deps: ['underscore', 'jquery'], 
     exports: 'Backbone' 
    }, 
    'jquery-myplugin': { 
    deps: ['jquery'] 
    } 
}); 

私はグローバル名前空間の汚染したくないbecase私は、libs/jquery/jquery-noconflict.jsで無競合モードでのjQueryをロード:

define(['libs/jquery'], function() { 
    return jQuery.noConflict(true); 
}); 

を、どのように私これは私の主なapp.jsをロードしてください:

define([ 
    'jquery', 
    'underscore', 
    'backbone', 
    'jquery-myplugin'], 
function($, _, Backbone, MyPlugin){ 
    //MyPlugin is always undefined, not even sure if 
    //I should be passing it here if it only extends jQuery? 
}); 

ここで私は経験している問題です。上記のすべてのライブラリを問題なく定義しましたが、AMD以外の対応jqueryプラグインをロードするために正しいshim設定を実行できませんでした。

私はをjquerydepsと設定しようとしましたが、それ以外の方法では動作しませんでした。

私は次のシナリオで問題抱えているように思える:ノー競合モードで

  1. jQueryの負荷を。
  2. 上記のjQueryのインスタンスを拡張するプラグインコード実行
  3. プラグインコードで拡張されたアプリケーション内で$を使用できるため、$ .mypluginを使用できます。
  4. 私が漂って同様の質問を見てきましたが、それらのどれもが、実際に、このような「使用シムの設定」など漠然としか提案を与えて、この問題を解決していない

...

編集

私も使ってみました

"jquery-myplugin": { 
    deps: ["jquery"], 
    exports: "jQuery.fn.myplugin" 
} 

し、プラグイン・メソッドながら

が利用可能に一度AMDモジュールとして、このようにロードされ、私はまだすることができませんアクセス: $('.class').myplugin()ドなどfault $オブジェクトはmypluginコードで拡張されていません。

+0

これでも問題はありますか? – Louis

+0

モジュールの依存関係は配列で表現する必要があります:define(['dep1'、 'dep2' ... 'depn']、function(dep1、dep2、... depn){}); (http://requirejs.org/docs/errors.html#requireargs) – Vikram

+0

良いキャッチが、それはstackoverflow上の私のミスタイプだった、根本的な問題はまだそこにある – rochal

答えて

3

jQuery.noConflict(true)を使用すると、グローバル変数jQueryが削除されます。プラグインが読み込まれると、jQueryにアクセスしようとしますが、プラグインが失敗することはありません。

プラグインがモジュールだった場合、依存関係としてjQueryにアクセスする可能性があります。または、jQueryをグローバルとして利用可能にすることもできます。

+0

おかげでショーン、私はここで何が起こるか知っているrequire.jsを正しく使用することです。モジュールのどれもグローバル変数を作成する必要がなく、他のすべてのモジュールは必要に応じて依存関係としてjQueryをロードします。 – rochal

+1

その場合、変換されていないプラグインを使用することはできません。 jQueryをモジュールとしてのみ使用できるようにするには、jQueryへの依存関係を宣言するためにプラグインを 'define()'を使用するように変換する必要があります。 –

+1

Seanさん、ありがとうございました。シム設定では、グローバル依存関係を使用せずに非AMD対応モジュールを処理できるようになりました。 IMHOサードパーティーのコードを変更してAMDとの連携が必要になる大きな時間を吸います。 – rochal

-1

まず、「//jqueryの-mypluginへのパスは、」実際にwindow.jQueryなく$

noConflictを(拡張していることを保証)が定義されてwindow.jQueryオブジェクトを残しますが、window.$はネイティブのエイリアスに内蔵されているいくつかの新しいブラウザでwindow.$から自身をアンバインドdocument.querySelectorAll機能。

第2に、myplugin自体は使用できないため、自分自身を返す必要はありません。 jQueryを返すので、myplugin呼び出しからjQueryを返します。

最後に、 "path/to/jquery-myplugin"はのモジュールではありません。これはプレーンなJSファイルです。 RequireJSがモジュールのようにロードしようとし、define()呼び出しを見つけられず、混乱を招く可能性があります。実際に ".js"ファイル拡張子を参照に追加してRequireJSに "js!"を使用する必要があることを知らせてください。リソースを読み込むためのプラグイン。

require.config({ 
    paths: { 
     "jquery": "path/to/jquery", 
     "jquery-myplugin": "path/to/jquery-myplugin.js" 
    }, 
    shim: { 
     "jquery": { 
      init: function() { 
      return window.jQuery.noConflict(); 
      }, 
     "jquery-myplugin": { 
      deps: ['jquery'] 
      init: function($) { 
      return $; 
      }, 
     } 
    } 
}); 
+0

これは誤りです。 noConflictのコードはここにある: ''ジャバスクリプト noConflict:関数(深い){ \t \t場合(ウィンドウ$ ===のjQuery。){ \t \t \tウィンドウ$ = $ _;。 \t \t} \t \t IF(===深い&& window.jQuery jQueryの){ \t \t \tウィンドウ。jQuery = _jQuery; \t \t} \t \t return jQuery; \t} 「深い」パラメータを渡すと、window.jQueryのバインドも解除されるので、同じページで複数のバージョンを実行できます。 – Ped

-1

私は今日あなたと同じ問題がありました。ここで私はそれを修正することができる方法である:私のアプリ/ main.jsで今

requirejs.config({ 
    "baseUrl": "js/lib", 
    "paths": { 
     "app": "../app" 
    } 
}); 

// Final version of jQuery with all needed plugins. 
define("jquery", ["jquery-core", "myplugin"], function(jqCore) { 
    return jqCore; 
}); 

// Define core jQuery module. 
define("jquery-core", ["jquery-1.9.1.min"], function() { 
    return jQuery.noConflict(true); 
}); 

// This module exposes jquery module to the global scope and returns previous defined version. 
define("jq-global", ["jquery-core"], function(jqCore) { 
    var tmp = jQuery; 
    jQuery = jqCore; 
    return tmp; 
}); 

// Define your plugin here, and don't forget to reset previous jQuery version. 
define("myplugin", ["jq-global", "jquery.myplugin"], function(jqGlobal, jqPlugin) { 
    jQuery = jqGlobal; 
}); 

// Load the main app module to start the app 
requirejs(["app/main"]); 

は、私は次の操作を行うことができますファイル:

define(["jquery"], function($) { 
    $('body').myplugin(); 
}); 

ここでの考え方は、コードをプラグインする前に一時的にjQueryを公開することですて実行されます。これまでのところ、私はロードするために、より多くのモジュールを搭載した大規模な環境でソリューションをテストしていないので、私はそれが長期的に動作する保証できません。)

編集

このソリューションウォンやってない! requirejsはスクリプトを順番にロードしないので、プラグインjsファイルがjqueryの前にロードされ、実行が失敗する可能性があります。これで申し訳ありません。

誰かが別のアイデアを持っている場合...

関連する問題