web-dev-qa-db-ja.com

Shim Twitter Bootstrap

RequireJS docs IEの古いバージョンをサポートするには、enforceDefine: true

したがって、Internet Explorerをサポートし、ロードエラーをキャッチし、直接define()呼び出しまたはshim configを介してモジュールコードを使用する場合は、常にforceDefineをtrueに設定します。例については、次のセクションを参照してください。

注:forceDefine:trueを設定し、data-main = ""を使用してメインJSモジュールをロードする場合、そのメインJSモジュールはrequire()の代わりにdefine()を呼び出して必要なコードをロードする必要があります。メインの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>

後でモジュールがbootstrap=を依存関係として必要とするとき、エラーメッセージが表示されます。

Error: No define call for bootstrap

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

ドキュメントを正しく理解していれば、enforceDefineはシムを無視すべきですが、そうではありません。

ここで何が間違っていますか?

37
Johan Alkstål

文書によると、「スクリプトは、読み込みのためにチェックできるグローバル文字列プロパティを指定したshim構成の一部であり、そのチェックが失敗した場合にスローされます。」

これを修正するには、スクリプトが正常にロードされたかどうかをRequireJSが確認できるように、shim構成にエクスポート値を追加する必要があります。 Bootstrapの場合、Bootstrapはjqueryプラグインの束だけでプロパティグローバル変数を「エクスポート」しないため、少し注意が必要ですが、これらのプラグインのいずれかをエクスポート値として使用できます。 $.fn.popover

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

Shimで魔法をかける代わりに、bootstrap JSをモジュールに変換しました。

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

CDNからjQueryを取得しているため、フォーラムやstackoverflowで見つかった他のすべては機能しませんでした。 http://requirejs.org/docs/api.html のrequireJSドキュメントで説明されているように問題にぶつかったためだと思います

ビルドでCDNロードとshim configを混在させないでください。シナリオ例:CDNからjQueryをロードしますが、shim configを使用して、jQueryに依存するBackboneのストックバージョンのようなものをロードします。ビルドを行うときは、ビルドファイルでjQueryをインライン化し、CDNからロードしないでください。それ以外の場合、Backboneはビルドファイルにインライン化され、CDNがロードされたjQueryがロードされる前に実行されます。これは、shim configが依存関係がロードされるまでファイルのロードを遅らせるだけで、defineの自動ラッピングを行わないためです。ビルド後、依存関係は既にインライン化されており、shim configはnon-define() 'dコードの実行を後まで遅らせることはできません。 define() 'dモジュールは、依存関係がロードされるまで実行されない定義ファクトリ関数でソースを適切にラップするため、ビルド後にCDNロードコードで動作します。したがって、教訓:shim configは、非モジュラーコード、レガシーコードのストップギャップ測定です。 define() 'dモジュールの方が優れています。

bootstrapを通常のAMDモジュールに変換し、shim configを削除すると解決しました。唯一の欠点:bootstrap CDNからbootstrapを取得できません。

14
Patrick Hammer

プロジェクト内でこの構成を使用します。

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
         // ...
11
lexeme

@lexeme&@benjaminbenbenは、シムを作成し、jQueryを必要とし、jQueryを返すRequireJSプラグインでこの概念をラップする方法については、これを手動で含める必要はありませんか?

bootstrapコンポーネントを使用するには、単に以下を使用します。

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

そして、この require-bootstrap-plugin を使用して機能させます。

4
Jasper Moelker