2012-11-14 41 views
37

RequireJS docs nói rằng để hỗ trợ các phiên bản cũ hơn của IE, bạn cần phải định cấu hình enforceDefine: true.Shim Twitter Bootstrap cho RequireJS

Vì vậy, nếu bạn muốn hỗ trợ Internet Explorer, bắt lỗi tải và có mã mô-đun thông qua lệnh gọi define() hoặc cấu hình shim trực tiếp, luôn đặt bắt buộc phải xác định là đúng. Xem phần tiếp theo để biết ví dụ. Chú ý: Nếu bạn đặt lệnh executeceDefine: true và bạn sử dụng data-main = "" để tải mô-đun JS chính của bạn, thì mô-đun JS chính đó phải gọi define() thay vì require() để tải mã nó nhu cầu. Mô-đun JS chính vẫn có thể gọi các yêu cầu/requirejs để đặt các giá trị cấu hình, nhưng để tải các mô-đun, nó nên sử dụng hàm define().

Vì Twitter Bootstrap không phải là mô-đun AMD, tôi cần phải kích hoạt nó để hoạt động. Đây là cách tôi cấu hình nó;

<script type="text/javascript"> 
    var require = { 
     paths: { 
      "bootstrap": "../bootstrap", 
      "jquery": "../jquery-1.8.2" 
     }, 
     shim: { 
      "bootstrap": ["jquery"] 
     }, 
     enforceDefine: true 
    }; 
</script> 

Sau đó, khi mô-đun của tôi muốn khởi động làm phụ thuộc, tôi vẫn kết thúc với thông báo lỗi;

Error: No define call for bootstrap 

http://requirejs.org/docs/errors.html#nodefine

Nếu tôi đã hiểu các tài liệu một cách chính xác, enforceDefine nên bỏ qua miếng chêm nhưng nó không phải.

Tôi đang làm gì sai ở đây?

Trả lời

37

Theo tài liệu bị lỗi sẽ được ném nếu "Tập lệnh là một phần của cấu hình tạm thời đã chỉ định thuộc tính chuỗi chung có thể được kiểm tra để tải và kiểm tra đó không thành công".

Để khắc phục điều này, bạn cần thêm giá trị xuất vào cấu hình tạm thời để RequireJS có thể kiểm tra xem tập lệnh có được tải thành công hay không. Trong trường hợp Bootstrap hơi phức tạp vì Bootstrap không 'xuất' một biến toàn cục thích hợp chỉ là một loạt các plugin jquery, nhưng bạn có thể sử dụng bất kỳ plugin nào như một giá trị xuất khẩu, ví dụ: $.fn.popover:

{ 
    paths: { 
     "bootstrap": "../bootstrap", 
     "jquery": "../jquery-1.8.2" 
    }, 
    shim: { 
     "bootstrap": { 
      deps: ["jquery"], 
      exports: "$.fn.popover" 
     } 
    }, 
    enforceDefine: true 
} 
+2

Đối với những người mới sử dụng JS, bạn sẽ sử dụng popover trong mã của riêng mình như thế nào? Với yêu cầu tôi có thể nói "var $ = require ('jquery') tôi sẽ viết" var popover = require ("$. Fn.popover")? – KingAndrew

+1

No. Yêu cầu có đường dẫn mô-đun trong hệ thống tệp làm đối số. Bạn chỉ có thể yêu cầu ("bootstrap") trong trường hợp này và sau đó chỉ cần sử dụng nó $ ("# example"). Popover(). Bạn có thể yêu cầu các plugin bootstrap riêng lẻ nếu bạn đã sử dụng các phiên bản chưa được biên dịch, nhưng điều đó đòi hỏi phải thiết lập nhiều hơn. Nói chung, các plugin jQuery đính kèm vào $ .fn không tương thích với triết lý mô-đun CJS/AMD. – Karolis

+1

Điều gì xảy ra nếu bạn cần truy cập nhiều plugin? Có cách nào để có nhiều lần xuất với requirejs không? hoặc bạn sẽ có nhiều miếng chêm cho mỗi plugin? hoặc cái gì khác? –

14

Thay vì làm điều kỳ diệu với shim, tôi chuyển bootstrap JS vào một module:

define([ "jquery" ], function($) { 
    // bootstrap JS code 
}); 

Mọi thứ khác tôi tìm thấy trong các diễn đàn và trên stackoverflow không làm việc cho tôi vì tôi lấy jQuery từ CDN. Tôi giả sử vì tôi đã nhấn vào vấn đề như được mô tả trong tài liệu requireJS trên http://requirejs.org/docs/api.html

Không trộn CDN với cấu hình shim trong bản dựng. Ví dụ kịch bản: bạn tải jQuery từ CDN nhưng sử dụng cấu hình shim để tải một cái gì đó giống như phiên bản cổ phiếu của xương sống phụ thuộc vào jQuery. Khi bạn thực hiện bản dựng, hãy đảm bảo nội tuyến jQuery trong tệp được tạo và không tải từ CDN. Nếu không, Backbone sẽ được inline trong tệp được xây dựng và nó sẽ thực thi trước khi jQuery nạp CDN sẽ tải. Đây là vì cấu hình tạm thời chỉ trì hoãn việc tải các tệp cho đến khi phụ thuộc được tải, nhưng không thực hiện bất kỳ tự động định nghĩa nào. Sau khi xây dựng, các phụ thuộc đã được gạch chân, cấu hình shim không thể trì hoãn việc thực hiện mã không xác định() cho đến sau này. define() 'd module làm việc với mã được nạp CDN sau khi xây dựng vì chúng đúng cách bọc nguồn của chúng trong xác định chức năng nhà máy sẽ không thực thi cho đến khi phụ thuộc được tải. Vì vậy, bài học: shim config là một biện pháp ngăn chặn khoảng cách cho mã phi mô-đun, mã kế thừa. define() 'd modules là tốt hơn.

Chuyển bootstrap thành mô-đun AMD thông thường và xóa cấu hình shim đã giải quyết nó cho tôi. Chỉ có nhược điểm: bạn không thể lấy bootstrap từ CDN bootstrap.

+0

Sau đó, có lẽ tốt hơn là không nên sử dụng CDN bootstrap vì nó không cho phép bạn chạy Trình biên dịch đóng cửa để loại bỏ các chức năng không sử dụng, v.v. –

+0

Lưu ý, phiên bản hiện tại của tài liệu tham khảo Bootstrap 3 jQuery không $, vì vậy bây giờ bạn thực sự có để chuyển vào: 'define ('bootstrap', ['jquery'], hàm (jQuery) {' –

11

tôi sử dụng cấu hình này bên trong dự án của tôi:

startup.js

require.config({ 
    paths: { 
     /* other paths are omitted */ 
     'bootstrap': '../libs/bootstrap' 
    }, 
    shim: { 
     'bootstrap/bootstrap-slider': { deps: ['jquery'], exports: '$.fn.slider' }, 
     'bootstrap/bootstrap-affix': { deps: ['jquery'], exports: '$.fn.affix' }, 
     'bootstrap/bootstrap-alert': { deps: ['jquery'], exports: '$.fn.alert' }, 
     'bootstrap/bootstrap-button': { deps: ['jquery'], exports: '$.fn.button' }, 
     'bootstrap/bootstrap-carousel': { deps: ['jquery'], exports: '$.fn.carousel' }, 
     'bootstrap/bootstrap-collapse': { deps: ['jquery'], exports: '$.fn.collapse' }, 
     'bootstrap/bootstrap-dropdown': { deps: ['jquery'], exports: '$.fn.dropdown' }, 
     'bootstrap/bootstrap-modal': { deps: ['jquery'], exports: '$.fn.modal' }, 
     'bootstrap/bootstrap-popover': { deps: ['jquery'], exports: '$.fn.popover' }, 
     'bootstrap/bootstrap-scrollspy': { deps: ['jquery'], exports: '$.fn.scrollspy'  }, 
     'bootstrap/bootstrap-tab': { deps: ['jquery'], exports: '$.fn.tab' }, 
     'bootstrap/bootstrap-tooltip': { deps: ['jquery'], exports: '$.fn.tooltip' }, 
     'bootstrap/bootstrap-transition': { deps: ['jquery'], exports: '$.support.transition' }, 
     'bootstrap/bootstrap-typeahead': { deps: ['jquery'], exports: '$.fn.typeahead' }, 
    } 
}); 

require(['domReady', 'app'], function(domReady, app) { 
    domReady(function() { 
     app.init(); 
    }); 
}); 

sau đó trong mã của tôi, tôi sử dụng này:

define(['jquery', 'underscore', 'backbone', 'text!templates/photos-list.html'], function($, _, Backbone, html) { 
    var PhotosListView = Backbone.View.extend({ 
     viewImageFullscreen: function(e) { 
      e.preventDefault(); 

      require(['bootstrap/bootstrap-modal', 'text!templates/photo-modal.html'], function(modal, htmlModal) { 
       var modalTemplate = _.template(htmlModal, options); 
       $('body').append(modalTemplate); 

       // setup 
       $(selector + '_modal').modal({ 
        backdrop: true, 
        keyboard: true, 
        show: false 
       }).css({ 
        'width': function() { return ($(document).width() * 0.55) + 'px'; }, 
        'margin-left': function() { return -($(this).width() * 0.5); } 
       }); 

       // trigger `modal` 
       $(selector + '_modal').modal('show'); 
      }); // require() call 
     // ... 
+2

Tôi thích cách tiếp cận này, đây là các phần cập nhật cho bootstrap 3 - https://gist.github.com/benfoxall/ 8844292 – benjaminbenben

+0

@benjaminbenben gần đây tôi đã tìm thấy tài nguyên thú vị này: http://matznermatzner.de/en/bernd/2013/11/loading-non-amd-modules-requirejs-part-1-jquery-ui – lexeme

+0

và cái này : http://matznermatzner.de/en/bernd/2013/12/loading-non-amd-modules-requirejs-part-2-zurb-foundation – lexeme

4

@lexeme & @benjaminbenben thế nào về gói khái niệm này trong một plugin RequireJS tạo ra shim, yêu cầu jQuery và cũng trả về jQuery, do đó bạn sẽ không không cần phải bao gồm điều này bằng tay?

Để sử dụng một thành phần bootstrap bạn chỉ đơn giản sẽ sử dụng:

define(['bootstrap!tooltip'], function($){ 
    $('[data-toggle="tooltip"]').tooltip(); 
}); 

Và bạn sẽ sử dụng require-bootstrap-plugin này để làm cho nó hoạt động.

+0

Điều này là khá trơn. Tuy nhiên, hãy thận trọng vì nếu plugin có phụ thuộc, điều này sẽ không hoạt động.Ví dụ: cửa sổ bật lên yêu cầu chú giải công cụ. –