Cách làm cho một plugin jQuery có thể tải được với requestjs


88

Tôi đang làm việc với Requijs + jquery và tôi đã tự hỏi liệu có cách nào thông minh để làm cho một plugin jQuery hoạt động tốt với request hay không.

Ví dụ, tôi đang sử dụng jQuery-cookie. Nếu tôi hiểu đúng, tôi có thể tạo một tệp có tên jquery-cookie.js và bên trong làm

define(["jquery"], // Require jquery
       function($){
// Put here the plugin code. 
// No need to return anything as we are augmenting the jQuery object
});
requirejs.config( {
    "shim": {
        "jquery-cookie"  : ["jquery"]
    }
} );

Tôi tự hỏi liệu tôi có thể làm những thứ như jQuery làm không, giống như thế này:

if ( typeof define === "function" && define.amd && define.amd.jQuery ) {
    define( "jquery", [], function () { return jQuery; } );
}

hoặc nếu đây là cách duy nhất để làm cho các plugin jQuery tương thích với requestj hoặc bất kỳ amd nào

Câu trả lời:


67

Bạn chỉ cần làm điều đó

define(["jquery"], // Require jquery
       function($){
// Put here the plugin code. 
// No need to return anything as we are augmenting the jQuery object
});

ở cuối jquery-cookie.js, HOẶC

requirejs.config( {
    "shim": {
        "jquery-cookie"  : ["jquery"]
    }
} );

ở bất kỳ đâu trước khi bạn bao gồm jquery-cookie (chẳng hạn như bất kỳ nơi nào mà data-main trỏ đến).

Khối mã cuối cùng bạn đã đăng rất tốt cho những thứ như jQuery được phân phối lại và có thể có hoặc không trong môi trường AMD. Lý tưởng nhất là mọi plugin jQuery đều đã được thiết lập sẵn.

Tôi muốn giữ cho các thư viện được bao gồm càng không bị sửa đổi càng tốt, vì vậy cấu hình shim toàn cục một lần trên mỗi trang có vẻ như là giải pháp sạch nhất đối với tôi . Bằng cách đó, nâng cấp an toàn hơn và CDN trở thành một khả năng.


1
Nếu tôi không làm cả hai xác định và điều shim không làm việc, tôi nhận được một $ .cookie không là một thông điệp hàm lỗi
Nicola Peluchetti

Theo kinh nghiệm của tôi, việc không trả về bất cứ thứ gì từ hàm xác định là không đủ, requestjs sẽ không nhận ra rằng mô-đun đã được tải. Điều này có thể được woked xung quanh bằng cách shim: {plugins: {phụ thuộc: [ 'jquery'], xuất khẩu: 'plugins'}
honzajde

Bạn nên lưu ý rằng tập lệnh plugin jQuery cần thực sự chạy. Tôi không phải là chuyên gia nhưng tôi đã tìm thấy một giải pháp đơn giản, theo đó bạn có một giải pháp duy nhất, require(['plugin1', 'plugin2']);v.v. Không có lệnh gọi lại nào được chuyển vào nên không có gì sẽ chạy ngoại trừ chính các tập lệnh plugin. Điều này có nghĩa là sau đó họ sẽ tự thêm mình vào jQuery.fnnên bạn có thể chỉ cần liệt kê 'jquery' như một phần phụ thuộc và chúng sẽ được đưa vào. Như tôi đã nói, tôi còn khá mới với điều này và có thể có một cách tiếp cận tốt hơn (chẳng hạn như chỉ sử dụng một scriptthẻ) nhưng cách này có hiệu quả.
Joshua Bambrick

3
Josh: Bạn đang đánh bạc rằng mọi thứ sẽ tải theo đúng thứ tự. Một số người dùng trên trang web của bạn có thể nhìn thấy những thứ bị hỏng. Vấn đề không phải là nhiều tải plugin, đó là khi tải plugin và những gì khác được thực hiện vào thời điểm đó. Lý do chính để sử dụng request là để đảm bảo một thứ tự hợp lý của các hoạt động dựa trên các phụ thuộc thay vì phỏng đoán.
Hans,

104

Có một số lưu ý khi sử dụng cấu hình shim trong RequestJS, được chỉ ra trên http://requirejs.org/docs/api.html#config-shim . Cụ thể, "Không kết hợp tải CDN với cấu hình shim trong một bản dựng" khi bạn đang sử dụng trình tối ưu hóa.

Tôi đang tìm cách sử dụng cùng một mã plugin jQuery trên các trang web có và không có RequiJS. Tôi đã tìm thấy đoạn mã này cho các plugin jQuery tại https://github.com/umdjs/umd/blob/master/jqueryPlugin.js . Bạn bọc plugin của mình trong mã này và nó sẽ hoạt động bình thường theo cả hai cách.

(function (factory) {
if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module depending on jQuery.
    define(['jquery'], factory);
} else {
    // No AMD. Register plugin with global jQuery object.
    factory(jQuery);
}
}(function ($) {

    $.fn.yourjQueryPlugin = function () {
        // Put your plugin code here
    };  

}));

Tín dụng được chuyển đến jrburke; giống như rất nhiều javascript, nó là các hàm bên trong các hàm hoạt động trên các hàm khác. Nhưng tôi nghĩ rằng tôi đã giải nén những gì nó đang làm.

Đối số hàm factorytrong dòng đầu tiên tự nó là một hàm được gọi để xác định plugin trên $đối số. Khi không có trình tải tương thích với AMD, nó được gọi trực tiếp để xác định plugin trên jQueryđối tượng chung. Đó cũng giống như thành ngữ định nghĩa plugin phổ biến:

function($)
{
  $.fn.yourjQueryPlugin = function() {
    // Plugin code here
  };
}(jQuery);

Nếu có một trình tải mô-đun, thì nó factoryđược đăng ký làm lệnh gọi lại để trình tải gọi ra sau khi tải jQuery. Bản sao được tải của jQuery là đối số. Nó tương đương với

define(['jquery'], function($) {
  $.fn.yourjQueryPlugin = function() {
     // Plugin code here
  };
})

3
Tôi thích câu trả lời này vì mặc dù câu hỏi là về một plugin jQuery, nhưng nó hoạt động cho bất kỳ loại mô-đun hoặc thư viện nào, không chỉ jQuery. Tôi đã mất một phút để xem mã của bạn, nhưng một khi tôi đã làm như vậy, nó hoàn toàn hợp lý.
Adam Tuttle

1
Nó chắc chắn là javascript không thể xuyên thủng. Tôi đã thêm một số giải thích về cách nó hoạt động.
Carl Raymond

Bất kỳ mẹo nào về cách thực hiện việc này và tạo một plugin hoạt động với jQuery hoặc Zepto? Bạn có thể dễ dàng thay thế mã không phải của AMD bằng factory(jQuery || Zepto);, nhưng tôi không biết bạn sẽ thực hiện phần AMD như thế nào. Tôi nghĩ bạn sẽ phải đặt "đường dẫn" jQuery thành zepto ?? paths: { jquery: 'vendor/zepto/zepto.min' }
Ryan Wheale

wow tôi đã muốn hiểu đoạn mã này từ lâu. Cảm ơn rất nhiều, Không phải về shimcơ bản chỉ làm như vậy sao? Tôi đoán là không .. bởi vì bạn đã nói rằng bạn đang mã hóa nó theo cách thủ công như ở trên.
eugene

Protip cho những kẻ ngốc như tôi: nơi nó nói $.fn.jqueryPlugintrong đoạn mã, hãy đổi jqueryPluginthành tên plugin !!
Matt Lacey

2

Cũng giống như FYI cho tất cả một số plugin jquery đã sử dụng amd / request, vì vậy bạn không cần phải khai báo bất kỳ điều gì trong miếng đệm. Trên thực tế, làm như vậy có thể gây ra vấn đề cho bạn trong một số trường hợp.

Nếu bạn nhìn trong JS cookie jquery, bạn sẽ thấy các cuộc gọi xác định và yêu cầu (["jquery"]).

và trong jquery.js, bạn sẽ thấy lời gọi định nghĩa ("jquery", [], function () ...

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.