RequireJS'yi kullanmak istiyorum ve jQuery kullanıyorum. En son jQuery sürümünü kullanmadığım için requireJS ve jQuery'nin birleşik sürümünü kullanmak istemiyorum. RequireJS ile çalışmanın en iyi yolu nedir?
RequireJS'yi kullanmak istiyorum ve jQuery kullanıyorum. En son jQuery sürümünü kullanmadığım için requireJS ve jQuery'nin birleşik sürümünü kullanmak istemiyorum. RequireJS ile çalışmanın en iyi yolu nedir?
Yanıtlar:
Benim de tam sorum bu! Ayrıca daha eski bir jQuery kullanmalıyım, ama aynı zamanda daha "geleneksel" javascript kitaplıkları. Bunu yapmak için en iyi teknik nedir? (Sakıncası yoksa sorunuzu daha geniş hale getirmek için düzenleyebilirim.) İşte öğrendiklerim.
RequireJS yazarı James Burke, birleştirilmiş RequireJS + jQuery dosyasının avantajlarını açıkladı . İki şey alırsın.
Bir modül jquery
mevcuttur ve bu jQuery nesnesidir. Bu güvenlidir:
// My module depends on jQuery but what if $ was overwritten?
define(["jquery"], function($) {
// $ is guaranteed to be jQuery now */
})
jQuery zaten herhangi önce yüklenen require()
veya define()
malzeme. Tüm modüller jQuery'nin hazır olduğu garantilidir. require/order.js
Eklentiye bile ihtiyacınız yok çünkü jQuery temelde ilk olarak yüklenmek üzere sabit kodlandı.
Bana göre # 2 pek yardımcı olmuyor. Çoğu gerçek uygulamalar var birçok .js
dosya olmalıdır doğru sırayla-acı ama gerçek yüklüyoruz. Sammy veya Underscore.js'ye ihtiyacınız olduğu anda, birleştirilmiş RequireJS + jQuery dosyası yardımcı olmaz.
Benim çözümüm, "order" eklentisini kullanarak geleneksel komut dosyalarımı yükleyen basit RequireJS paketleyicileri yazmaktır.
Uygulamamın bu bileşenlere sahip olduğunu varsayalım (bağımlılığa göre).
Bence yukarıdaki ile biten her şey .js
"geleneksel" bir yazı. Olmayan her şey .js
bir RequireJS eklentisidir. Anahtar şudur: üst düzey öğeler (harika uygulama, my_sammy) modüllerdir ve daha derin düzeylerde, geleneksel .js
dosyalara geri döner .
Her şey, RequireJS'e nasıl başlayacağını söyleyen bir destekçiyle başlar.
<html>
<head>
<script data-main="js/boot.js" src="js/require.js"></script>
</head>
</html>
Sadece js/boot.js
yapılandırmayı ve uygulamayı nasıl başlatacağımı koydum.
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(); }
);
İçinde greatapp.js
normal görünümlü bir modülüm var.
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};
}
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;
}
);
Bu soru şu anda en az iki yaşında, ancak bunun hala RequireJS 2.0 ile ilgili bir sorun olduğunu fark ettim (required-jquery.js jQuery 1.8.0 kullanıyor, ancak en son sürüm 1.8.2).
Bu soruyu görürseniz, require-jquery.js'nin artık sadece require.js ve jquery.js'nin birlikte karıştırıldığını unutmayın. Yalnızca require-jquery.js'yi düzenleyebilir ve jQuery parçalarını daha yeni bir sürümle değiştirebilirsiniz .
Güncelleme (30 Mayıs 2013) : RequireJS'de artık yollar ve şim var, jQuery ve jQuery eklentilerini içe aktarmanın yeni bir yolu var ve eski yöntem artık gerekli değil ve önerilmiyor . İşte mevcut yöntemin kısaltılmış bir versiyonu:
requirejs.config({
"paths": {
"jquery": "//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min"
}
});
define(["jquery"], function($) {
$(function() {
});
});
Daha fazla bilgi için http://requirejs.org/docs/jquery.html adresine bakın .
En iyi yaklaşımın jQuery'yi RequireJS yapımın dışında tutmak olduğunu buldum.
HTML'nize jquery.min.js eklemeniz yeterlidir. Ardından, bunun gibi bir jquery.js dosyası oluşturun ...
define([], function() {
return window.$;
});
JasonSmith'in cevabını muazzam derecede yararlı buldu, muhtemelen RequireJS'nin belgelerinden daha fazla.
Ancak, (küçük) tanımlama-tanımlayıcı modüller için ayrı AJAX isteklerinden kaçınmak için optimizasyon yapmanın bir yolu vardır ("require_jquery" "require_sammy"). R.js'nin bunu optimizasyon aşamasında yapacağından şüpheleniyorum, ancak Path, BaseURI sistemi ile savaşmamak için bunu önceden yapabilirsiniz.
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
son olarak 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
}
})
Bu yapı (gevşek bir şekilde değiştirilir (yinelenir?) RequireJS's Order eklentisi, ancak) AJAX'a ihtiyacınız olan dosya sayısını azaltmanıza, bağımlı ve bağımlı ağaç tanımına daha fazla kontrol eklemenize izin verir.
Ayrıca jQuery'yi ayrı olarak yüklemenin büyük bir avantajı da vardır (ki bu genellikle 100k'de gelir) - sunucuda önbelleğe almayı kontrol edebilir veya jQuery'yi tarayıcının localStorage'ına önbelleğe alabilirsiniz. AMD-Cache projesine buradan https://github.com/jensarps/AMD-cache bir göz atın ve ardından tanımlamayı (ifadeleri "önbellek!" İçerecek şekilde değiştirin: ve kullanıcının tarayıcısında (sonsuza kadar :)) sıkışacaktır.
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 + hakkında not Artık kendisini pencere nesnesine bağlamaz, bu nedenle yukarıdakiler değiştirilmemiş jQuery 1.7.x + dosyasıyla çalışmayacaktır. Burada jquery **. Js'nizi "}) (pencere);" kapanışından önce bunu içerecek şekilde özelleştirmelisiniz:
;window.jQuery=window.$=jQuery
Konsolda "jQuery tanımsız" hatalarınız varsa, bu kullandığınız jQuery sürümünün kendisini pencereye eklemediğinin bir işaretidir.
Kod lisansı: Kamu malı.
Açıklamalar: Yukarıdaki JavaScript, çok daha ayrıntılı üretim kodunun başka bir deyişle (elle budama) olması nedeniyle "sözde kod" kokuyor. Yukarıda sunulduğu şekliyle kodun çalışması garanti edilmez ve sunulduğu gibi çalıştığı test EDİLMEMİŞTİR. Denetim, test et. JS spesifikasyonuna göre gerekli olmadıklarından ve kodlar olmadan daha iyi göründüğünden noktalı virgül bilerek ihmal edilir.
Jhs'in cevabına ek olarak , README.md dosyasındaki required -jquery github sayfasındaki daha yeni talimatlara bakın . Hem birleşik bir jquery / require.js dosyası kullanmanın en basit yaklaşımını hem de ayrı bir jquery.js'nin nasıl kullanılacağını kapsar.