Shim Twitter Bootstrap for RequireJS
RequireJS 文档说,要支持旧版本的IE,你需要configurationenforceDefine: true
。
所以,如果你想支持Internet Explorer,捕捉加载错误,并通过直接define()调用或填充configuration模块化代码,总是设置enforceDefine为true。 请参阅下一部分的示例。
注意:如果你设置了enforceDefine:true,并且你使用了data-main =“”加载你的主JS模块,那么这个主JS模块必须调用define()而不是require()来加载它需要的代码。 主JS模块仍然可以调用require / requirejs来设置configuration值,但是对于加载模块,它应该使用define()。
由于Twitter Bootstrap不是AMD模块,因此我需要为它启动而努力。 这是我如何configuration它;
<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
应该忽略垫片,但不是。
我在这里做错了什么?
根据文档说,如果“脚本是指定全局string属性,可以检查加载,并检查失败的填充configuration的一部分脚本的错误。
为了解决这个问题,你需要在shimconfiguration文件中添加exports值,以便RequireJS可以检查脚本是否被成功载入。 在引导程序的情况下,这有点棘手,因为Bootstrap不会“导出”一个全局variables只有一堆jQuery插件,但你可以使用任何插件作为出口值,例如$.fn.popover
:
{ paths: { "bootstrap": "../bootstrap", "jquery": "../jquery-1.8.2" }, shim: { "bootstrap": { deps: ["jquery"], exports: "$.fn.popover" } }, enforceDefine: true }
而不是用垫片做魔术,我把自举JS转换成一个模块:
define([ "jquery" ], function($) { // bootstrap JS code });
我在论坛和stackoverflow中find的其他东西都不适用于我,因为我从CDN获取jQuery。 我假设是因为我遇到http://requirejs.org/docs/api.html上的requireJS文档中描述的问题;
不要在构build中将CDN加载与shimconfiguration混合。 示例场景:从CDN加载jQuery,但使用shimconfiguration来加载类似于依赖于jQuery的Backbone的股票版本。 在构build时,请确保在构build的文件中内联jQuery,并且不要从CDN加载它。 否则,Backbone将被内置在构build的文件中,并且会在载入CDN的jQuery之前执行。 这是因为shimconfiguration只是延迟加载文件,直到依赖加载,但不做任何自定义的自动换行。 在构build之后,依赖关系已经被内联,shimconfiguration不能延迟执行非define()的d代码,直到稍后。 define()'d模块在编译后可以使用CDN加载的代码,因为它们将自己的源代码正确地封装在定义工厂函数中,直到加载依赖关系才会执行。 所以课程:shim config是非模块化代码,遗留代码的一个权宜之计。 define()'d模块更好。
将bootstrap转换成一个普通的AMD模块,并删除shimconfiguration文件解决了我的问题。 唯一的缺点:你不能从引导CDN检索bootstrap。
我在我的项目中使用这个configuration:
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 // ...
@lexeme&@benjaminbenben如何将这个概念包装在创build填充程序的RequireJS插件中,需要jQuery并返回jQuery,因此您不需要手动包含它?
要使用引导程序组件,只需使用:
define(['bootstrap!tooltip'], function($){ $('[data-toggle="tooltip"]').tooltip(); });
你可以使用这个require-bootstrap-plugin来使它工作。