1. ホーム
  2. javascript

[解決済み] RequireJSを使ったBackboneとUnderscoreの読み込み

2022-04-22 23:04:05

質問

RequireJSでBackboneとUnderscore(とjQuery)を読み込もうとしています。BackboneとUnderscoreの最新バージョンでは、ちょっと厄介なことになっているようです。ひとつは、Underscoreは自動的にモジュールとして登録されるが、BackboneはUnderscoreがグローバルに利用可能であると仮定していることだ。また、Backboneは自分自身をモジュールとして登録しないようなので、他のライブラリとの一貫性がないことにも注意が必要だ。これは、私が思いついた中で、最もうまく動作するmain.jsです。

require(
{
    paths: {
        'backbone': 'libs/backbone/backbone-require',
        'templates': '../templates'
    }
},
[
    // jQuery registers itself as a module.
    'http://cdnjs.cloudflare.com/ajax/libs/jquery/1.7/jquery.min.js',

    // Underscore registers itself as a module.
    'http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.2.1/underscore-min.js'
], function() {

    // These nested require() calls are just due to how Backbone is built.  Underscore basically says if require()
    // is available then it will automatically register an "underscore" module, but it won't register underscore
    // as a global "_".  However, Backbone expects Underscore to be a global variable.  To make this work, we require
    // the Underscore module after it's been defined from within Underscore and set it as a global variable for
    // Backbone's sake.  Hopefully Backbone will soon be able to use the Underscore module directly instead of
    // assuming it's global.
    require(['underscore'], function(_) {
        window._ = _;
    });

    require([
        'order!http://cdnjs.cloudflare.com/ajax/libs/backbone.js/0.5.3/backbone-min.js',
        'order!app'
    ], function(a, app) {
        app.initialize();
    })
});

この方法では、オプティマイザが処理に詰まることを指摘しておきます。 次のように表示されます。

Tracing dependencies for: main
js: "/home/httpd/aahardy/requirejs/r.js", line 7619: exception from uncaught JavaScript throw: Error: Error: Error evaluating module "undefined" at location "/home/httpd/aahardy/phoenix/trunk/ui/js/../../ui-build/js/underscore.js":
JavaException: java.io.FileNotFoundException: /home/httpd/aahardy/phoenix/trunk/ui/js/../../ui-build/js/underscore.js (No such file or directory)
fileName:/home/httpd/aahardy/phoenix/trunk/ui/js/../../ui-build/js/underscore.js
lineNumber: undefined
http://requirejs.org/docs/errors.html#defineerror
In module tree:
    main

何か良い処理方法はないでしょうか? ありがとうございます。

どのように解決するのですか?

RequireJS 2.X は、Backbone や Underscore などの非 AMD モジュールに有機的に対応し、新しい shim を設定しました。

shim の構成はシンプルである。(1) 一つは依存関係 ( deps ) がある場合 (これは paths の設定、またはそれ自体が有効なパスである可能性があります)。(2) (オプションで) シムするファイルからグローバル変数名を指定し、それを必要とするモジュール関数にエクスポートします。(エクスポートを指定しない場合、require/define 関数には何も渡されないので、単にグローバルを使う必要があります)。

以下、簡単な使用例として shim を使ってBackboneを読み込んでいます。 また、依存関係がないにもかかわらず、アンダースコアのエクスポートを追加しています。

require.config({
  shim: {
    underscore: {
      exports: '_'
    },
    backbone: {
      deps: ["underscore", "jquery"],
      exports: "Backbone"
    }
  }
});

//the "main" function to bootstrap your code
require(['jquery', 'underscore', 'backbone'], function ($, _, Backbone) {   // or, you could use these deps in a separate module using define

});

この簡略化したコードは、この "main" コードと同じディレクトリにある "jquery.js", "backbone.js", "underscore.js" というファイル(これが require の baseURL となります)に jquery, backbone, underscore があると仮定したものです。 もしそうでない場合は、このコードと同じディレクトリにある パスコンフィグ .

個人的には、内蔵の shim の機能は、Backbone & Underscoreのフォークされたバージョンを使用しない利点は、他の一般的な回答で推奨されているAMDフォークを使用する利点を上回りますが、どちらの方法でも機能します。