用于RequireJS的Shim Twitter Bootstrap

Joh*_*tål 37 requirejs twitter-bootstrap

RequireJS 文档说,要支持旧版本的IE,您需要进行配置enforceDefine: true.

因此,如果您想支持Internet Explorer,捕获加载错误,并通过直接的define()调用或shim配置获得模块化代码,请始终将enforceDefine设置为true.有关示例,请参阅下一节.

注意:如果你设置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>
Run Code Online (Sandbox Code Playgroud)

后来当我的模块想要bootstrap作为依赖项时,我仍然得到一条错误消息;

Error: No define call for bootstrap
Run Code Online (Sandbox Code Playgroud)

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

如果我理解正确的文档,enforceDefine应该忽略垫片,但事实并非如此.

我在这做错了什么?

Kar*_*lis 37

根据文档,如果"脚本是指定可以检查加载的全局字符串属性的shim配置的一部分,并且该检查失败,则抛出错误."

要解决此问题,您需要在shim配置中添加导出值,以便RequireJS可以检查脚本是否已成功加载.在Bootstrap的情况下,稍微有点棘手,因为Bootstrap没有"导出"一个属性全局变量只有一堆jquery插件,但你可以使用任何这些插件作为导出值,例如$.fn.popover:

{
    paths: {
        "bootstrap": "../bootstrap",
        "jquery": "../jquery-1.8.2"
    },
    shim: {
        "bootstrap": {
          deps: ["jquery"],
          exports: "$.fn.popover"
        }
    },
    enforceDefine: true
}
Run Code Online (Sandbox Code Playgroud)

  • Bootstrap扩展了jQuery(和$)所以在'exports'中你可以简单地使用'$'(我一直在使用它)同时我认为'exports'值可以是一个函数,你可以在其中组合所有引导程序新命名空间中的插件.我还没试过. (10认同)
  • 对于我们这些刚接触JS的人,您如何在自己的代码中使用popover?有了require,我可以说"var $ = require('jquery')我会写"var popover = require("$.fn.popover")吗? (2认同)

Pat*_*mer 14

我没有用垫片做魔术,而是将引导程序JS转换为模块:

define([ "jquery" ], function($) {
  // bootstrap JS code
});
Run Code Online (Sandbox Code Playgroud)

我在论坛和stackoverflow上找到的其他所有东西都不适合我,因为我从CDN获得了jQuery.我假设因为我按照http://requirejs.org/docs/api.html上的requireJS文档中的描述来解决问题

不要在构建中混合使用CDN加载和shim配置.示例场景:您从CDN加载jQuery但使用shim配置加载类似于依赖于jQuery的Backbone的股票版本.在进行构建时,请确保在构建的文件中内联jQuery,并且不要从CDN加载它.否则,Backbone将在构建文件中内联,并且将在加载CDN的jQuery之前执行.这是因为shim配置只会延迟加载文件,直到加载依赖项,但不会对define进行任何自动换行.在构建之后,依赖关系已经内联,shim配置不能延迟执行非define()'d代码,直到以后.define()模块在构建之后可以使用CDN加载的代码,因为它们正确地将它们的源包装在定义工厂函数中,该函数在加载依赖项之前不会执行.所以上课:shim config是非模块化代码遗留代码的一种权宜之计.define()'d模块更好.

将引导程序转换为普通的AMD模块并删除shim配置解决了它.唯一的缺点:您无法从引导程序CDN检索引导程序.


lex*_*eme 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();
    });
});
Run Code Online (Sandbox Code Playgroud)

然后在我的代码中我使用这个:

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
         // ...
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢这种方法,这里是bootstrap 3的更新垫片 - https://gist.github.com/benfoxall/8844292 (2认同)