web-dev-qa-db-ja.com

RequireJS:複数のベースURLを実現する方法はありますか?

JavaScriptフレームワークとして別のドメインを使用したいのですが、アプリから拡張できる基本のrequire configが作成されます。

foo.example.com
    main.js
    lib/foo-specific.js
framework.example.com
    framework.js <-- entry point
    lib/jquery.js
    lib/etc...

最適には、「lib/foo-specific」および/または「lib/jquery」を要求し、パスをうまく解決できるようにしたいのですが、私が見つけたものから、これを行う方法はありませんかフレームワーク内のすべてのjsファイルに特定のパスキー/値を使用します。現時点では、別のベースURLで指定されたパスをロードするためのカスタムプラグインがあります(例:fw!lib/jquery)、ただし、[text!プラグイン。プラグインチェーンはサポートされていないため、機能しません。

私が現在持っているものについては https://github.com/jpillora/js-framework を、そして https://github.com/jpillora/prettyprinter も参照してくださいユースケース。

これを解決するきれいな方法はありますか?または複数のベースURLを実現するには?

注:複数のrequireインスタンスも調べましたが、アプリがフレームワークの構成にアクセスできるようにしたいので、これはうまくいきません。

36
jpillora

RequireJS Github IssueのページでJames Burkeが回答: Issue#447:複数のベースURL・jrburke/requirejs

data-mainがスクリプトへの唯一のエントリポイントである場合、非常に単純であることがわかります(詳細はコメント)、私は特定の問題を解決しました以下:

私のアプリの_index.html_:

_<script src="http://framework.jpillora.com/js/lib/require.js" 
  data-main="http://framework.jpillora.com/js/framework" > </script>
_

requirejsエントリポイントが_framework.js_に設定されています:

_var framework = ... //set using script elements src attribute

require.config({

    baseUrl: 'js/',

    //Framework paths
    paths: {
      'framework': framework,
      'lib'      : framework + 'js/lib',
      'ext'      : framework + 'js/ext',
      'util'     : framework + 'js/util'
    },

    //Shortcuts
    map: {
      '*': {
        ...
      }
    },

    //Non-modularised libraries with deps
    shim: {
      ...
    }
});

require(['main']);
_

そのため、通常は_index.html->main.js_を実行する代わりに、追加のステップ_index.html->framework.js->main.js_を追加します。これにより、フレームワークコードへのパスに関するアプリコードの知識が得られます。

たとえば、アプリ http://prettyprint.jpillora.com/ では、requireが_framework.js_をロードすると、_lib/..._へのパスをセットアップします http://framework.jpillora.com/ およびbaseUrlを_./js/_として設定すると、mainが必要になると、ベースURLが独自のドメインに設定され、libが別のドメインを指すようになります。

結果はrequire(['lib/foo', 'view/bar']);に解決されます:

_http://framework.jpillora.com/js/lib/foo.js_および_http://prettyprint.jpillora.com/js/view/bar.js_

ここに表示されているように、アプリは_main.js_にすぎません。他のすべてはframeworkから取得されます。

chrome devtools loaded app

したがって、最後に、上記の_main.js_を使用してアプリの_framework.js_をロードするたびに、よく使用するすべてのライブラリとユーティリティクラスにアクセスできます。アプリのソースをご覧ください。

また、_r.js_オプティマイザーとNiceローカルファイル構造を使用すると、アプリを単一のjsファイルに最適化して、frameworkから必要なものだけを取得することもできます。

35
jpillora

問題

テスト環境をセットアップしようとしたときに、同様の問題が発生しました。私はこのようなファイル構造を持っていました:

myApp/
    src/
        js/
            app.js
            data.js
            lib/underscore.js
    test/
        karma.conf.js
        test-main.js
        matchers.js
        spec/
            data.js

ここで注意が必要です。私のアプリスクリプト(app.jsおよびdata.js)は、datasrc/js/data.jsに、lib/underscoresrc/js/lib/underscore.jsなどに解決するRequireJS構成を想定しているため、テスト環境でもその構成が必要です。

test/test-main.js
-----------------
require.config({
  // Karma serves files under /base, which is the basePath from your config file
  baseUrl: '/base/src/js',
  // ...
});

これでテストを書くことができます:

test/spec/data.js
-----------------
define(['data', '../../test/matchers'], function(dataModule) {
    describe('The data module', function() {
        it('should satisfy my custom matcher', function() {
            expect(dataModule).toSatisfyMyCustomMatcher();
        });
    });
});

いくつかのカスタムマッチャーを使用:

test/matchers.js
----------------
define([], function() {
    beforeEach(function() {
        this.addMatchers({
            toSatisfyMyCustomMatcher: function() {
                return this.actual.isGood;
            },
        });
    });
});

しかし、その'../../test/matchers'の部分はひどく醜いです。テスト仕様は、他のモジュールへのファイルパスを知っていることに煩わされるべきではありません。それは、RequireJSの仕事です。代わりに、シンボリック名を使用します。

ソリューション

RequireJS paths config は、ディレクトリをマップすることもできます。

モジュール名に使用されるパスには拡張子を含めないでください。パスマッピングはディレクトリ用である可能性があるためです。

したがって、解決策は単純なパス構成です:

test/test-main.js
-----------------
require.config({
  baseUrl: '/base/src/js',
  paths: {
      test: '../../test',
  },
  // ...
});

これで、testディレクトリをbaseUrlの子であるかのように参照できます。

test/spec/data.js
-----------------
define(['data', 'test/matchers'], function(dataModule) {
    // ...
});

私の場合、これは、複数のbaseUrlsを使用できる場合とほぼ同じように効果的に得られます。

10
Emil Lundberg

requirejs multiversion

これを試して

context:ロード中のコンテキストに付ける名前。これにより、各トップレベルのrequire呼び出しが一意のコンテキスト文字列を指定している限り、require.jsがページにモジュールの複数のバージョンをロードできます。正しく使用するには、「マルチバージョンのサポート」セクションを参照してください。

大規模な製品開発のためのリファレンスアーキテクチャである BoilerplateJS で、ルーティングとコンテキストの処理方法をご覧ください。ライブラリ crossroads.js を使用して、モジュールとUIコンポーネントをルーティングしました。やらなければならないことは、パス/ハッシュをルートのセットに追加することだけで、フレームワークを通じてルーティングされます。

example として、UIコンポーネントのすべてのパスがURLコントローラオブジェクトに追加されます。

アプリケーション全体のフレームワーク構成情報へのアクセスに関しては、構成/設定を、アプリケーション内でアクセスできるグローバルコンテキストオブジェクトにアタッチできます。

0
Himeshi