Tôi muốn sử dụng requestJS và tôi đang sử dụng jQuery. Tôi không muốn sử dụng phiên bản kết hợp của requestJS và jQuery vì tôi không sử dụng phiên bản jQuery mới nhất. Cách tốt nhất để tôi làm việc với RequestJS là gì?
Tôi muốn sử dụng requestJS và tôi đang sử dụng jQuery. Tôi không muốn sử dụng phiên bản kết hợp của requestJS và jQuery vì tôi không sử dụng phiên bản jQuery mới nhất. Cách tốt nhất để tôi làm việc với RequestJS là gì?
Câu trả lời:
Đó cũng là câu hỏi chính xác của tôi! Tôi cũng phải sử dụng jQuery cũ hơn, nhưng cũng có nhiều thư viện javascript "truyền thống" hơn. Kỹ thuật tốt nhất để làm điều đó là gì? (Tôi có thể chỉnh sửa câu hỏi của bạn để làm cho nó rộng hơn nếu bạn không phiền.) Đây là những gì tôi học được.
Tác giả của RequestJS, James Burke, đã giải thích những ưu điểm của tệp RequestJS + jQuery kết hợp . Bạn nhận được hai điều.
Một mô-đun, jquery
có sẵn, và đó là đối tượng jQuery. Điều này là an toàn:
// My module depends on jQuery but what if $ was overwritten?
define(["jquery"], function($) {
// $ is guaranteed to be jQuery now */
})
jQuery đã được tải trước bất kỳ require()
hoặc define()
nội dung nào. Tất cả các mô-đun được đảm bảo rằng jQuery đã sẵn sàng. Bạn thậm chí không cần require/order.js
plugin vì jQuery về cơ bản đã được mã hóa cứng để tải trước.
Đối với tôi, số 2 không hữu ích lắm. Hầu hết các ứng dụng thực đều có nhiều .js
tệp phải tải theo đúng thứ tự — thật đáng buồn nhưng đúng. Ngay khi bạn cần Sammy hoặc Underscore.js, tệp RequestJS + jQuery kết hợp không giúp được gì.
Giải pháp của tôi là viết các trình bao bọc RequestJS đơn giản để tải các tập lệnh truyền thống của tôi bằng cách sử dụng plugin "order".
Giả sử ứng dụng của tôi có các thành phần này (theo phụ thuộc).
Theo suy nghĩ của tôi, mọi thứ ở trên kết thúc bằng .js
một kịch bản "truyền thống". Tất cả mọi thứ không có .js
là một plugin RequiJS. Điều quan trọng là: những thứ cấp cao (greatapp, my_sammy) là các mô-đun và ở các cấp độ sâu hơn, nó trở lại .js
các tệp truyền thống .
Tất cả bắt đầu bằng một phần mềm khởi động nói với RequestJS cách bắt đầu.
<html>
<head>
<script data-main="js/boot.js" src="js/require.js"></script>
</head>
</html>
Trong js/boot.js
tôi chỉ đặt cấu hình và cách khởi động ứng dụng.
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(); }
);
Trong greatapp.js
tôi có một mô-đun trông bình thường.
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;
}
);
Câu hỏi này hiện đã có ít nhất hai năm, nhưng tôi nhận thấy đây là một vấn đề vẫn còn xảy ra với RequestJS 2.0 (request-jquery.js sử dụng jQuery 1.8.0, nhưng phiên bản mới nhất là 1.8.2).
Nếu bạn tình cờ thấy câu hỏi này, hãy lưu ý rằng request-jquery.js bây giờ chỉ là request.js và jquery.js, được trộn với nhau. Bạn chỉ có thể chỉnh sửa request-jquery.js và thay thế các phần jQuery bằng một phiên bản mới hơn .
Cập nhật (ngày 30 tháng 5 năm 2013) : Hiện tại, RequiJS đã có đường dẫn và miếng đệm, có một cách mới để nhập các plugin jQuery và jQuery và phương pháp cũ không còn cần thiết nữa cũng không được khuyến khích . Đây là phiên bản rút gọn của phương thức hiện tại:
requirejs.config({
"paths": {
"jquery": "//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min"
}
});
define(["jquery"], function($) {
$(function() {
});
});
Xem http://requirejs.org/docs/jquery.html để biết thêm thông tin.
Tôi đã tìm thấy cách tiếp cận tốt nhất là giữ jQuery bên ngoài bản dựng RequestJS của mình.
Chỉ cần bao gồm jquery.min.js trong HTML của bạn. Sau đó, tạo tệp jquery.js với một cái gì đó như thế này ...
define([], function() {
return window.$;
});
Tìm thấy anwer của JasonSmith vô cùng hữu ích, có lẽ còn hơn cả tài liệu của RequestJS.
Tuy nhiên, có cách để tối ưu hóa nó để tránh có các yêu cầu AJAX riêng biệt cho các mô-đun khai báo xác định (nhỏ) ("request_jquery" "request_sammy"). Tôi nghi ngờ r.js sẽ làm điều đó ở giai đoạn tối ưu hóa, nhưng bạn có thể làm điều đó trước thời hạn để không chiến đấu với hệ thống 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
cuối cùng, 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
}
})
Cấu trúc này (thay thế một cách lỏng lẻo (trùng lặp?) Plugin Đặt hàng của RequestJS, nhưng) cho phép bạn cắt bớt số lượng tệp bạn cần để AJAX, thêm nhiều quyền kiểm soát hơn đối với định nghĩa của cây phụ thuộc và phụ thuộc.
Ngoài ra còn có một phần thưởng lớn khi tải jQuery riêng (thường có giá 100k) - bạn có thể kiểm soát bộ nhớ đệm tại máy chủ hoặc lưu trữ jQuery vào bộ nhớ đệm của trình duyệt. Hãy xem dự án AMD-Cache tại đây https://github.com/jensarps/AMD-cache sau đó thay đổi định nghĩa (câu lệnh để bao gồm "cache!": Và nó sẽ bị kẹt (mãi mãi :)) trong trình duyệt của người dùng.
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
}
)
Lưu ý về jQuery 1.7.x + Nó không còn tự gắn vào đối tượng window, vì vậy điều trên sẽ KHÔNG hoạt động với tệp jQuery 1.7.x + chưa sửa đổi. Ở đó, bạn phải tùy chỉnh jquery **. Js của mình để bao gồm cái này trước khi đóng "}) (window);":
;window.jQuery=window.$=jQuery
Nếu bạn gặp lỗi "jQuery undefined" trong bảng điều khiển, đó là dấu hiệu phiên bản jQuery bạn đang sử dụng không tự gắn vào window.
Giấy phép mã: Miền công cộng.
Tiết lộ: JavaScript ở trên có mùi "mã giả" vì nó là cách diễn giải (cắt tỉa bằng tay) của mã sản xuất chi tiết hơn nhiều. Mã như được trình bày ở trên không được đảm bảo hoạt động và KHÔNG được kiểm tra để hoạt động như đã trình bày. Kiểm tra, kiểm tra nó. Mục đích bỏ qua dấu chấm phẩy vì chúng không bắt buộc theo thông số JS và mã trông đẹp hơn nếu không có chúng.
Ngoài câu trả lời của jhs, hãy xem hướng dẫn mới hơn trên trang github request-jquery từ tệp README.md. Nó bao gồm cả cách tiếp cận đơn giản nhất của việc sử dụng tệp jquery / Requi.js kết hợp và cả cách sử dụng một tệp jquery.js riêng biệt.