2012-11-14 49 views
37

的RequireJS docs說,支持老版本的IE,你需要配置enforceDefine: true沉Twitter的引導爲RequireJS

所以,如果你想支持Internet Explorer,抓加載錯誤,並有模塊化的代碼,通過直接定義()調用或墊片的配置,總是設置enforceDefine是真實的。有關示例,請參閱下一節。注意:如果你設置了enforceDefine:true,並且你使用了data-main =「」來加載你的主JS模塊,那麼這個主JS模塊必須調用define()而不是require()來加載它的代碼需要。主JS模塊仍然可以調用require/requirejs來設置配置值,但是對於加載模塊,它應該使用define()。

由於Twitter Bootstrap不是AMD模塊,因此我需要爲它啓動而使其工作。 這是我如何配置它;

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

後來,當我想要模塊引導的依賴,我還是結了一個錯誤信息;

Error: No define call for bootstrap 

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

如果我理解正確的文檔,enforceDefine應該忽略墊片,但事實並非如此。

我在這裏做錯了什麼?

回答

37

根據如果引發錯誤的文檔「的腳本是指定的,可以裝載檢查全局字符串屬性墊片配置的一部分,而檢查失敗。」

要解決這個問題,您需要在shim配置文件中添加exports值,以便RequireJS可以檢查腳本是否被成功載入。在Bootstrap的情況下有點棘手,因爲Bootstrap並不是'僅僅輸出'一個全局變量,而只是一堆jquery插件,但是你可以使用任何這些插件作爲輸出值,例如$.fn.popover

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

對於我們這些新來JS的人,你會如何在自己的代碼中使用彈出窗口?與需求我可以說「var $ = require('jquery')我會寫」var popover = require(「$。fn.popover」)? – KingAndrew

+1

否。require將文件系統中的模塊路徑作爲參數。在這種情況下,你只能使用require(「bootstrap」),然後使用$(「#example」)。popover()。如果您使用非未經版本的版本,則可能需要單獨的引導程序插件,但這需要更多設置。一般來說,將自己附加到$ .fn的jQuery插件與CJS/AMD模塊哲學不兼容。 – Karolis

+1

如果您需要訪問多個插件,該怎麼辦?有沒有辦法讓requirejs有多個導出?或者你會爲每個插件有多個墊片?或者是其他東西? –

14

而不是做與墊片的魔力,我轉換引導JS到一個模塊:

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

一切我在論壇和計算器發現不適合我,因爲我從CDN獲取jQuery。我想是因爲我打的問題,因爲在requireJS文檔中描述的http://requirejs.org/docs/api.html

不要在構建墊片配置混合CDN負載。示例場景: 您從CDN加載jQuery,但使用shim配置加載 類似於依賴jQuery的Backbone的股票版本。當您執行 構建時,請務必在構建的文件中內聯jQuery,並且不要從CDN加載 。否則,Backbone將被內聯在構建文件 中,並且它將在加載CDN的jQuery之前執行。這是 ,因爲shim配置只是延遲加載文件,直到加載了 依賴項,但不執行任何自定義的自動換行。 構建完成後,依賴關係已經內聯,shim config 不能延遲執行非define()的d代碼,直到稍後。 限定()'d模塊也與CDN加載代碼的生成,因爲他們 妥善包裝的根源在於定義,直到依賴被加載,這將 不執行出廠功能後工作。所以課程:shim config 是針對非模塊化代碼,遺留代碼的一種權宜之計。 define()'d模塊更好。

將bootstrap轉換成一個普通的AMD模塊,並刪除shim配置爲我解決它。唯一的缺點:您無法從引導CDN檢索引導程序。

+0

然後,最好不要使用CDN引導程序,因爲它不允許您運行Closure Compiler以消除未使用的函數等。 –

+0

請注意,當前版本的Bootstrap 3引用jQuery不是$,所以現在您實際上已經擁有了傳遞:'define('bootstrap',['jquery'],函數(jQuery){' –

11

我使用這個配置我的項目中:

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(); 
    }); 
}); 

然後在我的代碼我用這個:

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

我喜歡這種方法,這裏是引導3的更新墊片 - https://gist.github.com/benfoxall/ 8844292 – benjaminbenben

+0

@benjaminbenben最近我發現了這個很酷的資源:http://matznermatzner.de/en/bernd/2013/11/loading-non-amd-modules-requirejs-part-1-jquery-ui – lexeme

+0

和這個:http://matznermatzner.de/en/bernd/2013/12/loading-non-amd-modules-requirejs-part-2-zurb-foundation – lexeme

4

@lexeme & @benjaminbenben怎麼樣將這個概念包裝在創建填充程序的RequireJS插件中,需要jQuery並返回jQuery,所以你不會是否需要手動添加?

要使用的引導組件,你會簡單地使用:

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

而且你會使用這個require-bootstrap-plugin,使其工作。

+0

這很漂亮。但是,請謹慎使用,因爲如果插件具有依賴關係,則這不起作用。例如,popover需要工具提示。 –