requireJS を使用したいのですが、jQuery を使用しています。最新の jQuery バージョンを使用していないため、requireJS と jQuery を組み合わせたバージョンは使用したくありません。requireJS を使用する最善の方法は何ですか?
5 に答える
それも私の正確な質問です!また、古い jQuery を使用する必要がありますが、より「伝統的な」javascript ライブラリも使用する必要があります。それを行うための最良のテクニックは何ですか?(よろしければ、質問を編集してより広くするかもしれません。)これが私が学んだことです。
RequireJS の作成者である James Burke 氏は、RequireJS + jQuery ファイルを組み合わせることの利点について説明しました。あなたは2つのことを得る。
モジュール
jquery
が利用可能で、それは jQuery オブジェクトです。これは安全です:// My module depends on jQuery but what if $ was overwritten? define(["jquery"], function($) { // $ is guaranteed to be jQuery now */ })
jQuery は、何かの前に既にロードされてい
require()
ますdefine()
。すべてのモジュールは、jQuery の準備が整っていることが保証されています。require/order.js
jQuery は基本的に最初にロードするようにハードコーディングされているため、プラグインは必要ありません。
私にとって、#2はあまり役に立ちません。ほとんどの実際のアプリケーションには、正しい順序でロードする必要がある多くの .js
ファイルがあります。悲しいことですが、本当です。Sammy または Underscore.js が必要になるとすぐに、RequireJS と jQuery を組み合わせたファイルは役に立ちません。
私の解決策は、「order」プラグインを使用して従来のスクリプトをロードする単純な RequireJS ラッパーを作成することです。
例
アプリにこれらのコンポーネントがあるとします (依存関係による)。
- 私のアプリ、greatapp
- greatapp はカスタムjqueryに依存しています(古いバージョンを使用する必要があります)
- greatapp はmy_sammy (SammyJS と、使用する必要があるすべてのプラグイン) に依存しています。これらは順番にある必要があります
- my_sammy はjqueryに依存します(SammyJS は jQuery プラグインです)
- my_sammy は sammy.js に依存します
- my_sammy は sammy.json.js に依存します
- my_sammy は sammy.storage.js に依存します
- 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.js
、構成とアプリケーションの起動方法のみを入れます。
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;
}
);
この質問は少なくとも 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を参照してください。
jQuery を RequireJS ビルドの外に置くことが最善の方法であることがわかりました。
HTML に jquery.min.js を含めるだけです。次に、次のような jquery.js ファイルを作成します...
define([], function() {
return window.$;
});
おそらくRequireJSのドキュメントよりも、JasonSmithの答えが非常に役立つことがわかりました。
ただし、(小さな) 定義宣言モジュール ("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>
ローダー.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 にキャッシュしたりできます。ここで AMD-Cache プロジェクトを見てください https://github.com/jensarps/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
コンソールに「jQuery undefined」エラーがある場合は、使用している jQuery バージョンがウィンドウにアタッチされていないことを示しています。
コード ライセンス: パブリック ドメイン。
開示: 上記の JavaScript は、はるかに詳細な製品コードを言い換え (手作業で剪定) しているため、「疑似コード」の匂いがします。上記のコードは動作が保証されておらず、提示されたとおりに動作することはテストされていません。監査、テストします。JS 仕様ではセミコロンは必須ではなく、セミコロンがないと見栄えがよくなるため、意図的にセミコロンを省略しています。
jhs の回答に加えて、README.md ファイルのrequire-jquery github ページにある最新の手順を参照してください。jquery/require.js ファイルを組み合わせて使用する最も単純な方法と、個別の jquery.js を使用する方法の両方をカバーしています。