61

Backbone、RequireJS、Handlebarsを使用して重要なWebアプリケーションを構築していますが、興味があります。現時点では、各モデルは次のようになっています。

define(['Backbone', 'js/thing/a', 'js/thing/b', 'js/lib/bob'], function(a, b, bob) {
  return Backbone.Router.extend({
    // stuff here
  });
});

ここで、thing / a、thing / bはどちらも、たとえばハンドルバーテンプレートなどに独自の依存関係を持っています。今、私のmain.jsでは、すべての「トップレベル」ルーターが読み込まれ、初期化されます。各トップレベルルーターには一連の依存関係(モデル、ビューなど)があり、それぞれに独自の依存関係(テンプレート、ヘルパー、ユーティリティなど)があります。基本的に、大きな木の構造。

この場合の問題は、このツリー全体が解決され、ページの読み込み時に読み込まれることです。最終的にオプティマイザーを実行し、1つの大きな単一ファイルになってしまうので(RequireJSを基本的にモジュール化フレームワークに減らします)、それは気になりません。ただし、ビューやテンプレートなどを「オンデマンド」でロードできるかどうかは気になります。

ここで説明されている「簡略化されたCommonJSラッピング」があるので、それを試しました。

define(function(require) {
  Backbone = require('Backbone');
  return Backbone.Router.extend({
    doStuff: function() {
      var MyView = require('js/myView');
      new MyView().render();
    }
  });
});

ただし、Chromeのネットワークインスペクターを見ると、RequireJSは、doStuffハンドラーをトリガーするルートをトリガーしなくても、どういうわけか、myView依存関係をロードしているようです。質問:

  • これは実際に可能ですか?RequireJSに、実際にルートrequire()をトリガーせずにへの呼び出しを探す黒い魔術師はいますか?doStuff
  • これは、RequireJSモジュールとリソースの「オンデマンド」で遅延読み込みを行うための理論的に正しい方法ですか?
  • この表記を使用した場合でも、r.jsオプティマイザーはアドバタイズされたとおりに機能しますか?
4

2 に答える 2

52

これは実際に可能ですか?doStuff ルートを実際にトリガーせずに require() の呼び出しを探す RequireJS に黒魔術がありますか?

「sugar」構文を使用するFunction.prototype.toStringと、正規表現を使用して参照を抽出requireし、関数を実行する前にそれらを依存関係としてリストします。基本的には第一引数に deps の配列を定義する通常のスタイルになります。

requireこのため、require 呼び出しがどこにあるかは気にせず、条件ステートメントが無視されるのはそのためです (これらの呼び出しで変数ではなく文字列リテラルを使用する必要がある理由も説明しています)。

これは、RequireJS モジュールとリソースを「オンデマンド」で遅延読み込みする理論的に正しい方法ですか?

シュガー構文を使用すると、これまで見てきたように条件付き読み込みが許可されません。私が思いついた唯一の方法はrequire、dep の配列とコールバックを使用して呼び出しを使用することです。

define(function(require) {
    var module1 = require('module1');

    // This will only load if the condition is true
    if (true) {
        require(['module2'], function(module2) {

        });
    }

    return {};
});

唯一の欠点は別のネストされた関数ですが、パフォーマンスを重視する場合、これは有効なルートです。

この表記法を使用しても、r.js オプティマイザーは広告どおりに動作しますか?

「sugar」構文を使用している場合は、オプティマイザは正常に機能します。例:

モジュール/test.js

define(function(require) {
    var $ = require('jquery');
    var _ = require('underscore');

    return {
        bla: true
    }
});

r.js でコンパイルすると、次のようになります。

define('modules/test', ['require', 'jquery', 'underscore'], function(require) {
    var $ = require('jquery');
    var _ = require('underscore');

    return {
        bla: true
    }
});

結論として、条件付きでロードできますが、おっしゃったように、r.js を使用してプロジェクトを最適化する場合は、sugar 構文を使用するだけでは大きなオーバーヘッドはありません。

于 2012-06-06T12:34:30.857 に答える