使用方法 § 1

JavaScriptファイルを読み込む § 1.1

RequireJSは、従来の<script>タグとは異なる方法でスクリプトを読み込みます。高速に動作し、最適化も良好ですが、主な目標はモジュール化されたコードを推奨することです。その一環として、スクリプトタグのURLではなく、**モジュールID**を使用することを推奨しています。

RequireJSは、すべてのコードをbaseUrlを基準にして相対的に読み込みます。baseUrlは通常、ページに読み込むトップレベルのスクリプトのdata-main属性で使用されるスクリプトと同じディレクトリに設定されます。data-main属性は、require.jsがスクリプトの読み込みを開始するためにチェックする特別な属性です。この例では、baseUrlは**scripts**になります。

<!--This sets the baseUrl to the "scripts" directory, and
    loads a script that will have a module ID of 'main'-->
<script data-main="scripts/main.js" src="scripts/require.js"></script>

または、RequireJSの設定を使用してbaseUrlを手動で設定することもできます。明示的な設定がなく、data-mainが使用されていない場合、デフォルトのbaseUrlはRequireJSを実行しているHTMLページを含むディレクトリになります。

RequireJSはデフォルトですべての依存関係がスクリプトであると想定しているため、モジュールIDの末尾に「.js」が付いていることを期待していません。RequireJSは、モジュールIDをパスに変換するときに自動的に追加します。パス設定を使用すると、スクリプトのグループの場所を設定できます。これらの機能により、従来の<script>タグと比較して、スクリプトに短い文字列を使用できます。

スクリプトを直接参照し、それを検索するための「baseUrl + パス」ルールに従わないようにしたい場合があります。モジュールIDに次のいずれかの特徴がある場合、IDは「baseUrl + パス」設定を通過せず、ドキュメントを基準とした通常のURLとして扱われます。

  • 「.js」で終わる。
  • 「/」で始まる。
  • 「http:」または「https:」のようなURLプロトコルを含む。

ただし、一般的には、baseUrlと「paths」設定を使用してモジュールIDのパスを設定することをお勧めします。そうすることで、最適化ビルドのためにパスを別の場所に名前変更および設定する際に、より柔軟に対応できます。

同様に、多くの設定を避けるために、スクリプトの深いフォルダ階層を避け、代わりにすべてのスクリプトをbaseUrlに保持するか、ライブラリ/ベンダー提供のコードとアプリコードを分離する場合は、次のようなディレクトリレイアウトを使用します。

  • www/
    • index.html
    • js/
      • app/
        • sub.js
      • lib/
        • jquery.js
        • canvas.js
      • app.js
      • require.js

index.html内

<script data-main="js/app.js" src="js/require.js"></script>

app.js内

requirejs.config({
    //By default load any module IDs from js/lib
    baseUrl: 'js/lib',
    //except, if the module ID starts with "app",
    //load it from the js/app directory. paths
    //config is relative to the baseUrl, and
    //never includes a ".js" extension since
    //the paths config could be for a directory.
    paths: {
        app: '../app'
    }
});

// Start the main app logic.
requirejs(['jquery', 'canvas', 'app/sub'],
function   ($,        canvas,   sub) {
    //jQuery, canvas and the app/sub module are all
    //loaded and can be used here now.
});

この例の一部として、jQueryのようなベンダーライブラリはファイル名にバージョン番号が含まれていません。バージョン情報を追跡したい場合は、別のテキストファイルに保存することをお勧めします。または、voloのようなツールを使用すると、package.jsonにバージョン情報が記録されますが、ディスク上のファイルは「jquery.js」のままになります。これにより、各ライブラリの「paths」設定にエントリを追加する必要がなく、最小限の設定で済みます。たとえば、「jquery」を「jquery-1.7.2」に設定します。

理想的には、読み込むスクリプトはdefine()を呼び出すことによって定義されたモジュールになります。ただし、define()を介して依存関係を表現しない、従来の/レガシーな「ブラウザグローバル」スクリプトを使用する必要がある場合があります。これらのスクリプトの場合、shim設定を使用して依存関係を適切に表現できます。

依存関係を表現しないと、RequireJSは速度のためにスクリプトを非同期に、かつ順番どおりに読み込まないため、読み込みエラーが発生する可能性があります。

data-main エントリポイント § 1.2

data-main属性は、require.jsがスクリプトの読み込みを開始するためにチェックする特別な属性です。

<!--when require.js loads it will inject another script tag
    (with async attribute) for scripts/main.js-->
<script data-main="scripts/main" src="scripts/require.js"></script>

通常、data-mainスクリプトを使用して構成オプションを設定し、最初のアプリケーションモジュールを読み込みます。注:require.jsがdata-mainモジュール用に生成するスクリプトタグには、async属性が含まれています。これは、**data-mainスクリプトの読み込みと実行が、同じページで後で参照される他のスクリプトよりも前に終了すると想定できない**ことを意味します。

たとえば、'foo'モジュールのrequire.configパスが後でrequire()される前に設定されていない場合、この配置はランダムに失敗します。

<script data-main="scripts/main" src="scripts/require.js"></script>
<script src="scripts/other.js"></script>
// contents of main.js:
require.config({
    paths: {
        foo: 'libs/foo-1.1.3'
    }
});
// contents of other.js:

// This code might be called before the require.config() in main.js
// has executed. When that happens, require.js will attempt to
// load 'scripts/foo.js' instead of 'scripts/libs/foo-1.1.3.js'
require(['foo'], function(foo) {

});

HTMLページでrequire()呼び出しを実行する場合は、data-mainを使用しないことをお勧めします。data-mainは、ページにメインエントリポイントが1つだけ(data-mainスクリプト)ある場合にのみ使用することを目的としています。インラインrequire()呼び出しを実行するページの場合は、設定のrequire()呼び出し内にネストすることをお勧めします。

<script src="scripts/require.js"></script>
<script>
require(['scripts/config'], function() {
    // Configuration loaded now, safe to do other require calls
    // that depend on that config.
    require(['foo'], function(foo) {

    });
});
</script>

モジュールを定義する § 1.3

モジュールは、グローバル名前空間を汚染しない、適切にスコープされたオブジェクトを定義するという点で、従来のスクリプトファイルとは異なります。依存関係を明示的にリストし、グローバルオブジェクトを参照せずにそれらの依存関係のハンドルを取得できます。代わりに、モジュールを定義する関数の引数として依存関係を受け取ります。RequireJSのモジュールはモジュールパターンの拡張であり、他のモジュールを参照するためにグローバル変数を必要としないという利点があります。

RequireJSのモジュール構文により、モジュールをできるだけ高速に、順番に関係なく読み込むことができますが、正しい依存関係の順序で評価されます。また、グローバル変数が作成されないため、ページに複数のバージョンのモジュールを読み込むことができます。

(CommonJSモジュールに精通している場合、または使用している場合は、RequireJSモジュール形式がCommonJSモジュールにどのようにマッピングされるかについては、CommonJSに関する注意事項も参照してください)。

ディスク上のファイルごとにモジュール定義は**1つだけ**にする必要があります。モジュールは、最適化ツールによって最適化されたバンドルにグループ化できます。

単純な名前/値のペア § 1.3.1

モジュールに依存関係がなく、名前と値のペアの集合体である場合は、オブジェクトリテラルをdefine()に渡します。

//Inside file my/shirt.js:
define({
    color: "black",
    size: "unisize"
});

定義関数 § 1.3.2

モジュールに依存関係がないが、セットアップ作業を行うために関数を使用する必要がある場合は、自身を定義し、関数を define() に渡します。

//my/shirt.js now does setup work
//before returning its module definition.
define(function () {
    //Do setup work here

    return {
        color: "black",
        size: "unisize"
    }
});

依存関係を持つ定義関数§ 1.3.3

モジュールに依存関係がある場合、最初の引数は依存関係名の配列、2 番目の引数は定義関数である必要があります。この関数は、すべての依存関係がロードされた後にモジュールを定義するために呼び出されます。関数は、モジュールを定義するオブジェクトを返す必要があります。依存関係は、依存関係配列と同じ順序で、関数引数として定義関数に渡されます。

//my/shirt.js now has some dependencies, a cart and inventory
//module in the same directory as shirt.js
define(["./cart", "./inventory"], function(cart, inventory) {
        //return an object to define the "my/shirt" module.
        return {
            color: "blue",
            size: "large",
            addToCart: function() {
                inventory.decrement(this);
                cart.add(this);
            }
        }
    }
);

この例では、my/shirt モジュールが作成されます。これは my/cart と my/inventory に依存しています。ディスク上では、ファイルは次のように構成されています。

  • my/cart.js
  • my/inventory.js
  • my/shirt.js

上記の関数呼び出しは、「cart」と「inventory」の 2 つの引数を指定しています。これらは、"./cart" および "./inventory" モジュール名で表されるモジュールです。

この関数は、my/cart モジュールと my/inventory モジュールがロードされるまで呼び出されず、関数はモジュールを「cart」および「inventory」引数として受け取ります。

グローバル変数を定義するモジュールは、モジュールの複数のバージョンがページに同時に存在できるように、明示的に推奨されません(高度な使用方法を参照)。また、関数引数の順序は依存関係の順序と一致する必要があります。

関数呼び出しからの戻りオブジェクトは、「my/shirt」モジュールを定義します。この方法でモジュールを定義することにより、「my/shirt」はグローバルオブジェクトとして存在しません。

関数をモジュールとして定義する§ 1.3.4

モジュールはオブジェクトを返す必要はありません。関数からの有効な戻り値はすべて許可されます。モジュール定義として関数を返すモジュールの例を次に示します。

//A module definition inside foo/title.js. It uses
//my/cart and my/inventory modules from before,
//but since foo/title.js is in a different directory than
//the "my" modules, it uses the "my" in the module dependency
//name to find them. The "my" part of the name can be mapped
//to any directory, but by default, it is assumed to be a
//sibling to the "foo" directory.
define(["my/cart", "my/inventory"],
    function(cart, inventory) {
        //return a function to define "foo/title".
        //It gets or sets the window title.
        return function(title) {
            return title ? (window.title = title) :
                   inventory.storeName + ' ' + cart.name;
        }
    }
);

簡略化された CommonJS ラッパーを使用してモジュールを定義する§ 1.3.5

従来の CommonJS モジュール形式 で記述されたコードを再利用する場合、上記の依存関係の配列に再加工するのが難しい場合があり、依存関係名と、その依存関係に使用されるローカル変数を直接対応させたい場合があります。このような場合は、簡略化された CommonJS ラッパー を使用できます。

define(function(require, exports, module) {
        var a = require('a'),
            b = require('b');

        //Return the module value
        return function () {};
    }
);

このラッパーは、Function.prototype.toString() に依存して、関数内容の有用な文字列値を提供します。これは、PS3 や一部の古い Opera モバイルブラウザなど、一部のデバイスでは機能しません。これらのデバイスで使用する場合は、オプティマイザ を使用して、配列形式の依存関係を抽出してください。

詳細については、CommonJS ページ、および AMD の理由ページの「シュガー」セクション を参照してください。

名前付きモジュールを定義する§ 1.3.6

define() の最初の引数としてモジュールの名前を含む define() 呼び出しが発生する場合があります。

    //Explicitly defines the "foo/title" module:
    define("foo/title",
        ["my/cart", "my/inventory"],
        function(cart, inventory) {
            //Define foo/title object in here.
       }
    );

これらは通常、最適化ツール によって生成されます。モジュールに明示的に名前を付けることもできますが、モジュールの移植性が低下します。ファイルを別のディレクトリに移動すると、名前を変更する必要があります。通常は、モジュールに名前を付けるコードを避け、最適化ツールにモジュール名を書き込ませるのが最善です。最適化ツールは、ブラウザでの読み込みを高速化するために、複数のモジュールを 1 つのファイルにバンドルできるように、名前を追加する必要があります。

その他のモジュールに関する注意事項§ 1.3.7

ファイルごとに 1 つのモジュール。:モジュール名からファイルパスへのルックアップアルゴリズムの性質上、JavaScript ファイルごとに 1 つのモジュールのみを定義する必要があります。複数のモジュールを最適化されたファイルにグループ化するには、最適化ツール のみを使用する必要があります。

define() 内の相対モジュール名:define() 関数呼び出し内で発生する可能性のある require("./relative/name") 呼び出しについては、相対名が正しく解決されるように、依存関係として「require」を要求してください。

define(["require", "./relative/name"], function(require) {
    var mod = require("./relative/name");
});

または、CommonJS の変換 モジュールで使用できる短縮構文を使用することをお勧めします。

define(function(require) {
    var mod = require("./relative/name");
});

この形式は、Function.prototype.toString() を使用して require() 呼び出しを見つけ、それらを「require」とともに依存関係配列に追加するため、コードは相対パスで正しく機能します。

相対パスは、ディレクトリ内にいくつかのモジュールを作成する場合に非常に便利です。ディレクトリを他の人や他のプロジェクトと共有し、ディレクトリの名前を知らなくても、そのディレクトリ内の兄弟モジュールを取得できるようにするためです。

相対モジュール名は、パスではなく他の名前に対して相対的です: ローダーは、パスではなく名前でモジュールを内部的に保存します。そのため、相対名参照の場合、参照を行っているモジュール名に対して相対的に解決され、そのモジュール名、つまり ID は、ロードする必要がある場合にパスに変換されます。「main」モジュールと「extras」モジュールを含む「compute」パッケージのコード例

* lib/
    * compute/
        * main.js
        * extras.js

main.js モジュールは次のようになります。

define(["./extras"], function(extras) {
    //Uses extras in here.
});

これがパス設定の場合

require.config({
    baseUrl: 'lib',
    paths: {
      'compute': 'compute/main'
    }
});

そして、require(['compute']) が実行されると、lib/compute/main.js は「compute」というモジュール名を持ちます。 './extras' を要求すると、これは 'compute' に対して相対的に解決されるため、 'compute/./extras' となり、これは単に 'extras' に正規化されます。そのモジュール名に対応するパス設定がないため、生成されるパスは 'lib/extras.js' になります。これは正しくありません。

この場合、パッケージ設定 の方が適しています。メインモジュールを「compute」として設定できますが、内部的にはローダーはモジュールを「compute/main」の ID で保存するため、「./extras」の相対参照が機能します。

別のオプションは、lib/compute.js に define(['./compute/main'], function(m) { return m; }); であるモジュールを作成することです。そうすれば、パスまたはパッケージの設定は必要ありません。

または、そのパスまたはパッケージを設定せず、トップレベルの require 呼び出しを require(['compute/main']) として実行します。

モジュールを基準とした URL の生成: モジュールを基準とした URL を生成する必要がある場合があります。そのためには、「require」を依存関係として要求し、require.toUrl() を使用して URL を生成します。

define(["require"], function(require) {
    var cssUrl = require.toUrl("./style.css");
});

コンソールデバッグ: JavaScript コンソールで require(["module/name"], function(){}) 呼び出しによって既にロードしたモジュールを操作する必要がある場合は、モジュールの文字列名のみを使用してフェッチする require() 形式を使用できます。

require("module/name").callSomeFunction()

これは、「module/name」が require の非同期バージョン: require(["module/name"]) によって以前にロードされた場合にのみ機能することに注意してください。 './module/name' のような相対パスを使用する場合、それらは define 内でのみ機能します。

循環依存関係§ 1.3.8

循環依存関係(「a」は「b」を必要とし、「b」は「a」を必要とする)を定義した場合、「b」のモジュール関数が呼び出されると、「a」に undefined 値が渡されます。「b」は、モジュールが定義された後に require() メソッドを使用して「a」をフェッチできます(「a」を検索するために正しいコンテキストが使用されるように、require を依存関係として指定してください)。

//Inside b.js:
define(["require", "a"],
    function(require, a) {
        //"a" in this case will be null if "a" also asked for "b",
        //a circular dependency.
        return function(title) {
            return require("a").doSomething();
        }
    }
);

通常、モジュールをフェッチするために require() を使用する必要はなく、代わりにモジュールが引数として関数に渡されることに依存する必要があります。循環依存関係はまれであり、通常は設計を見直す必要があることを示しています.ただし、必要な場合があり、その場合は上記のように require() を使用します。

CommonJS モジュールに精通している場合は、代わりに **exports** を使用して、他のモジュールがすぐに参照できるモジュールの空のオブジェクトを作成できます。循環依存関係の両側でこれを行うことにより、もう一方のモジュールを安全に保持できます。これは、各モジュールが関数の値ではなく、モジュールのオブジェクトをエクスポートしている場合にのみ機能します。

//Inside b.js:
define(function(require, exports, module) {
    //If "a" has used exports, then we have a real
    //object reference here. However, we cannot use
    //any of "a"'s properties until after "b" returns a value.
    var a = require("a");

    exports.foo = function () {
        return a.bar();
    };
});

または、依存関係配列アプローチを使用している場合は、特別な 'exports' 依存関係: を要求します。

//Inside b.js:
define(['a', 'exports'], function(a, exports) {
    //If "a" has used exports, then we have a real
    //object reference here. However, we cannot use
    //any of "a"'s properties until after "b" returns a value.

    exports.foo = function () {
        return a.bar();
    };
});

JSONP サービスの依存関係を指定する§ 1.3.9

JSONP は、JavaScript で一部のサービスを呼び出す方法です。ドメインをまたがって機能し、スクリプトタグを介した HTTP GET のみが必要なサービスを呼び出すための確立されたアプローチです。

RequireJS で JSONP サービスを使用するには、コールバックパラメータの値として「define」を指定します。これは、JSONP URL の値をモジュール定義であるかのように取得できることを意味します。

JSONP API エンドポイントを呼び出す例を次に示します。この例では、JSONP コールバックパラメータは「callback」と呼ばれているため、「callback=define」は API に JSON 応答を「define()」ラッパーでラップするように指示します。

require(["http://example.com/api/data.json?callback=define"],
    function (data) {
        //The data object will be the API response for the
        //JSONP data call.
        console.log(data);
    }
);

JSONP のこの使用方法は、初期アプリケーションのセットアップのための JSONP サービスに限定する必要があります。JSONP サービスがタイムアウトすると、define() を介して定義した他のモジュールが実行されない可能性があるため、エラー処理は堅牢ではありません.

JSON オブジェクトである JSONP 戻り値のみがサポートされています。配列、文字列、または数値である JSONP 応答は機能しません。

この機能は、リアルタイムストリーミングを処理する API であるロングポーリング JSONP 接続には使用しないでください。これらの種類の API は、各応答を受信した後にさらにスクリプトクリーンアップを実行する必要があり、RequireJS は JSONP URL を一度だけフェッチします。require() または define() 呼び出しで依存関係として同じ URL を後続で使用すると、キャッシュされた値が取得されます。

JSONP サービスの読み込みエラーは通常、スクリプトタグの読み込みではネットワークの問題に関する詳細が提供されないため、サービスのタイムアウトによって表面化されます。エラーを検出するには、requirejs.onError() をオーバーライドしてエラーを取得できます。 エラーの処理 セクションに詳細情報があります。

モジュールの定義解除§ 1.3.10

モジュールの定義を解除できるグローバル関数 **requirejs.undef()** があります。ローダーの内部状態をリセットして、モジュールの以前の定義を忘れます。

**ただし**、既に定義されていて、実行時に依存関係としてそのモジュールを処理した他のモジュールからモジュールを削除することはありません。したがって、他のモジュールがモジュール値を処理していないエラー状況、またはそのモジュールを使用する可能性のある将来のモジュール読み込みの一部として使用する場合にのみ役立ちます。例については、errback セクション を参照してください。

定義解除作業のために、より高度な依存関係グラフ分析を実行する場合は、半プライベートの onResourceLoad API が役立つ場合があります.

メカニズム § 2

RequireJS は、head.appendChild() を使用して、各依存関係をスクリプトタグとしてロードします。

RequireJS は、すべての依存関係がロードされるのを待ち、モジュールを定義する関数を呼び出す正しい順序を決定し、それらの関数の依存関係が呼び出された後にモジュール定義関数を呼び出します。特定のモジュール定義関数の依存関係は、それらの副依存関係とネットワークのロード順序により、任意の順序で呼び出すことができることに注意してください。

同期読み込みを持つサーバーサイド JavaScript 環境で RequireJS を使用するには、require.load() を再定義するだけで済みます。ビルドシステムはこれを実行します。その環境の require.load メソッドは、build/jslib/requirePatch.js にあります。

将来的には、このコードは require/ ディレクトリにオプションモジュールとして取り込まれる可能性があります。このモジュールを環境にロードすることで、ホスト環境に基づいた適切なロード動作を実現できます。

設定オプション § 3

トップレベルのHTMLページ(またはモジュールを定義していないトップレベルのスクリプトファイル)でrequire()を使用する場合、設定オブジェクトを最初のオプションとして渡すことができます。

<script src="scripts/require.js"></script>
<script>
  require.config({
    baseUrl: "/another/path",
    paths: {
        "some": "some/v1.0"
    },
    waitSeconds: 15
  });
  require( ["some/module", "my/module", "a.js", "b.js"],
    function(someModule,    myModule) {
        //This function will be called when all the dependencies
        //listed above are loaded. Note that this function could
        //be called before the page is loaded.
        //This callback is optional.
    }
  );
</script>

data-main エントリポイントから require.config を呼び出すこともできますが、data-main スクリプトは非同期にロードされることに注意してください。 data-main とその require.config が常にスクリプトのロード前に実行されると誤って想定している他のエントリポイントスクリプトは避けてください。

また、設定オブジェクトをグローバル変数 require として require.js がロードされる**前**に定義し、値を自動的に適用することもできます。 この例では、require.js が require() を定義するとすぐにロードされるいくつかの依存関係を指定しています。

<script>
    var require = {
        deps: ["some/module1", "my/module2", "a.js", "b.js"],
        callback: function(module1, module2) {
            //This function will be called when all the dependencies
            //listed above in deps are loaded. Note that this
            //function could be called before the page is loaded.
            //This callback is optional.
        }
    };
</script>
<script src="scripts/require.js"></script>

注意: var require = {} を使用することをお勧めします。 window.require = {} を使用しないでください。IE では正しく動作しません。

設定をメインモジュールのロードから分離するためのいくつかのパターンがあります。

サポートされている設定オプション

baseUrl: すべてのモジュール検索に使用するルートパス。上記の例では、「my/module」のスクリプトタグの src は「/another/path/my/module.js」になります。 baseUrl は、プレーンな .js ファイル(スラッシュで始まり、プロトコルを持ち、または .js で終わる依存関係文字列で示される)のロード時には使用され**ません**。これらの文字列はそのまま使用されるため、a.js と b.js は上記のコードスニペットを含む HTML ページと同じディレクトリからロードされます。

設定で baseUrl が明示的に設定されていない場合、デフォルト値は require.js をロードする HTML ページの場所になります。 data-main 属性が使用されている場合、そのパスが baseUrl になります。

baseUrl は、require.js をロードするページとは異なるドメインの URL にすることができます。 RequireJS スクリプトのロードは、ドメインをまたいで機能します。唯一の制限は、text! プラグインによってロードされるテキストコンテンツです。これらのパスは、少なくとも開発中は、ページと同じドメイン上にある必要があります。最適化ツールは text! プラグインリソースをインライン化するため、最適化ツールを使用した後は、別のドメインから text! プラグインリソースを参照するリソースを使用できます。

paths: baseUrl の直下で見つからないモジュール名のパスマッピング。パス設定は、パス設定が "/" で始まるか、URL プロトコル("http:" など)が含まれていない限り、baseUrl を基準とすると想定されます。上記のサンプル設定を使用すると、「some/module」のスクリプトタグは src="/another/path/some/v1.0/module.js" になります。

モジュール名に使用されるパスには、拡張子を含めては**いけません**。パスマッピングはディレクトリ用である可能性があるためです。パスマッピングコードは、モジュール名をパスにマッピングするときに自動的に .js 拡張子を追加します。 require.toUrl() が使用されている場合、テキストテンプレートなどの場合は適切な拡張子が追加されます。

ブラウザで実行する場合、パスのフォールバックを指定して、CDN の場所からのロードを試み、CDN の場所のロードに失敗した場合はローカルの場所にフォールバックすることができます。

bundles: RequireJS 2.1.10 で導入されました。複数のモジュールIDを別のスクリプトで見つけることができるように設定できます。例

requirejs.config({
    bundles: {
        'primary': ['main', 'util', 'text', 'text!template.html'],
        'secondary': ['text!secondary.html']
    }
});

require(['util', 'text'], function(util, text) {
    //The script for module ID 'primary' was loaded,
    //and that script included the define()'d
    //modules for 'util' and 'text'
});

この設定では、モジュール 'main'、'util'、'text'、'text!template.html' は、モジュール ID 'primary' をロードすることで見つかります。モジュール 'text!secondary.html' は、モジュール ID 'secondary' をロードすることで見つかります。

これは、複数の define() が定義されたモジュールを含むスクリプト内でモジュールを見つける場所を設定するだけです。これらのモジュールをバンドルのモジュール ID に自動的にバインドするわけではありません。バンドルのモジュール ID は、モジュールのセットを見つけるためにのみ使用されます。

paths 設定でも同様のことが可能ですが、はるかに冗長になり、paths 設定ルートでは設定にローダープラグインリソース ID を使用できません。paths 設定値はパスセグメントであり、ID ではないためです。

bundles 設定は、ビルドを実行していて、そのビルドターゲットが既存のモジュール ID でなかった場合、またはビルドされた JS ファイルにローダープラグインによってロードされるべきでないローダープラグインリソースがある場合に役立ちます。 **キーと値はモジュールID**であり、パスセグメントではないことに注意してください。 paths 設定map 設定 のようなモジュール ID プレフィックスではなく、絶対モジュール ID です。 また、bundle 設定は、map 設定が 1 対 1 のモジュール ID 関係であるのに対し、bundle 設定は複数のモジュール ID をバンドルのモジュール ID に指し示すためのものなので、map 設定とは異なります。

RequireJS 2.2.0 以降、オプティマイザは bundles 設定を生成し、トップレベルの requirejs.config() 呼び出しに挿入できます。 詳細については、bundlesConfigOutFile ビルド設定オプションを参照してください。

shim: define() を使用して依存関係を宣言し、モジュール値を設定しない、従来の "ブラウザグローバル" スクリプトの依存関係、エクスポート、およびカスタム初期化を設定します。

例を示します。RequireJS 2.1.0+ が必要で、backbone.js、underscore.js、jquery.js が baseUrl ディレクトリにインストールされていると想定しています。そうでない場合は、パス設定を行う必要があるかもしれません。

requirejs.config({
    //Remember: only use shim config for non-AMD scripts,
    //scripts that do not already call define(). The shim
    //config will not work correctly if used on AMD scripts,
    //in particular, the exports and init config will not
    //be triggered, and the deps config will be confusing
    //for those cases.
    shim: {
        'backbone': {
            //These script dependencies should be loaded before loading
            //backbone.js
            deps: ['underscore', 'jquery'],
            //Once loaded, use the global 'Backbone' as the
            //module value.
            exports: 'Backbone'
        },
        'underscore': {
            exports: '_'
        },
        'foo': {
            deps: ['bar'],
            exports: 'Foo',
            init: function (bar) {
                //Using a function allows you to call noConflict for
                //libraries that support it, and do other cleanup.
                //However, plugins for those libraries may still want
                //a global. "this" for the function will be the global
                //object. The dependencies will be passed in as
                //function arguments. If this function returns a value,
                //then that value is used as the module export value
                //instead of the object found via the 'exports' string.
                //Note: jQuery registers as an AMD module via define(),
                //so this will not work for jQuery. See notes section
                //below for an approach for jQuery.
                return this.Foo.noConflict();
            }
        }
    }
});

//Then, later in a separate file, call it 'MyModel.js', a module is
//defined, specifying 'backbone' as a dependency. RequireJS will use
//the shim config to properly load 'backbone' and give a local
//reference to this module. The global Backbone will still exist on
//the page too.
define(['backbone'], function (Backbone) {
  return Backbone.Model.extend({});
});

RequireJS 2.0.* では、shim 設定の "exports" プロパティは文字列ではなく関数にすることができました。その場合、上記のように "init" プロパティと同じように機能しました。 "init" パターンは RequireJS 2.1.0+ で使用されるため、exports の文字列値を enforceDefine に使用できますが、ライブラリがロードされたことがわかれば機能的な作業を許可します。

モジュール値をエクスポートする必要のない jQuery または Backbone プラグインである "モジュール" の場合、shim 設定は依存関係の配列にすることができます。

requirejs.config({
    shim: {
        'jquery.colorize': ['jquery'],
        'jquery.scroll': ['jquery'],
        'backbone.layoutmanager': ['backbone']
    }
});

ただし、パスのフォールバックまたは errbacks を使用できるように、IE で 404 ロード検出を取得する場合は、ローダーがスクリプトが実際にロードされたかどうかを確認できるように、文字列のエクスポート値を指定する必要があります(init からの戻り値は enforceDefine チェックには使用され**ません**)。

requirejs.config({
    shim: {
        'jquery.colorize': {
            deps: ['jquery'],
            exports: 'jQuery.fn.colorize'
        },
        'jquery.scroll': {
            deps: ['jquery'],
            exports: 'jQuery.fn.scroll'
        },
        'backbone.layoutmanager': {
            deps: ['backbone']
            exports: 'Backbone.LayoutManager'
        }
    }
});

"shim" 設定に関する重要な注意事項

  • shim 設定は、コードの関係を設定するだけです。 shim 設定の一部であるモジュール、または shim 設定を使用するモジュールをロードするには、通常の require/define 呼び出しが必要です。 shim を単独で設定しても、コードのロードはトリガーされません。
  • shim されたスクリプトの依存関係として、他の "shim" モジュール、または依存関係がなく、グローバル(jQuery や lodash など)を作成した後に define() を呼び出す AMD ライブラリのみを使用してください。 そうしないと、AMD モジュールを shim 設定モジュールの依存関係として使用すると、ビルド後に、ビルドで shim されたコードが実行されるまで AMD モジュールが評価されず、エラーが発生する可能性があります。 究極の解決策は、すべての shim されたコードをアップグレードして、オプションの AMD define() 呼び出しを持つようにすることです。
  • shim されたコードを AMD define() 呼び出しを使用するようにアップグレードできない場合、RequireJS 2.1.11 以降、オプティマイザには、ビルドのために shim されたコードを define() で自動的にラップしようとする wrapShim ビルドオプション があります。 これにより、shim された依存関係のスコープが変更されるため、常に機能するとは限りませんが、たとえば、AMD バージョンの Backbone に依存する shim された依存関係には役立ちます。
  • init 関数は、AMD モジュールに対しては呼び出され**ません**。 たとえば、shim init 関数を使用して jQuery の noConflict を呼び出すことはできません。 jQuery の代替アプローチについては、noConflict を使用するモジュールのマッピング を参照してください。
  • Shim 設定は、RequireJS を介してノードで AMD モジュールを実行している場合はサポートされていません(ただし、オプティマイザの使用では機能します)。 shim されているモジュールによっては、ノードはブラウザと同じグローバル環境を持っていないため、ノードで失敗する可能性があります。 RequireJS 2.1.7 以降、shim 設定がサポートされていないことをコンソールに警告します。動作するかどうかは保証されません。そのメッセージを抑制したい場合は、requirejs.config({ suppress: { nodeShim: true }}); を渡すことができます。

"shim" 設定に関する重要なオプティマイザの注意事項:

  • shim 設定を見つけるファイルの場所を指定するには、mainConfigFile ビルドオプション を使用する必要があります。 そうしないと、オプティマイザは shim 設定を認識しません。 もう 1 つのオプションは、ビルドプロファイルで shim 設定を複製することです。
  • ビルドで CDN ローディングと shim 設定を混在させないでください。 例のシナリオ:CDN から jQuery をロードしますが、shim 設定を使用して jQuery に依存する Backbone のストックバージョンなどをロードします。 ビルドを行うときは、必ず jQuery をビルドファイルにインライン化し、CDN からロードしないでください。 そうしないと、Backbone はビルドファイルにインライン化され、CDN でロードされた jQuery がロードされる前に実行されます。 これは、shim 設定は依存関係がロードされるまでファイルのロードを遅延させるだけで、define の自動ラッピングは行わないためです。 ビルド後、依存関係はすでにインライン化されており、shim 設定は define() でないコードの実行を後で遅延させることはできません。 define() で定義されたモジュールは、ビルド後に CDN でロードされたコードで動作します。ソースを依存関係がロードされるまで実行されない define ファクトリ関数で適切にラップするためです。 教訓:shim 設定は、非モジュールコード、レガシーコードのための一時的な対策です。 define() で定義されたモジュールの方が優れています。
  • ローカルのマルチファイルビルドの場合、上記の CDN のアドバイスも適用されます。 shim されたスクリプトの場合、その依存関係は shim されたスクリプトが実行される**前**にロードする必要があります。 これは、依存関係を shim されたスクリプトを含むビルドレイヤーに直接ビルドするか、require([], function (){}) 呼び出しで依存関係をロードしてから、shim されたスクリプトを含むビルドレイヤーに対してネストされた require([]) 呼び出しを行うことを意味します。
  • uglifyjs を使用してコードを縮小する場合、uglify オプションの toplevel を true に設定し**ないでください**。 また、コマンドラインを使用している場合は、-mt を渡し**ないでください**。 このオプションは、shim がエクスポートを見つけるために使用するグローバル名をマングルします。

map: 指定されたモジュールプレフィックスの場合、指定された ID でモジュールをロードする代わりに、別のモジュール ID を代用します。

この種の機能は、2 つの異なるバージョンの 'foo' を使用する必要がある 2 セットのモジュールがあるが、それでも互いに連携する必要がある大規模プロジェクトにとって非常に重要です。

これは、コンテキストに裏付けられたマルチバージョンサポートでは不可能です。 さらに、paths 設定 は、モジュール ID のルートパスを設定するためのものであり、あるモジュール ID を別のモジュール ID にマッピングするためのものではありません。

map の例

requirejs.config({
    map: {
        'some/newmodule': {
            'foo': 'foo1.2'
        },
        'some/oldmodule': {
            'foo': 'foo1.0'
        }
    }
});

モジュールがディスク上にこのように配置されている場合

  • foo1.0.js
  • foo1.2.js
  • some/
    • newmodule.js
    • oldmodule.js

'some/newmodule' が `require('foo')` を実行すると foo1.2.js ファイルを取得し、'some/oldmodule' が `require('foo')` を実行すると foo1.0.js ファイルを取得します。

この機能は、define() を呼び出して匿名モジュールとして登録する、真の AMD モジュールであるスクリプトに対してのみ有効に機能します。 また、map 設定には**絶対モジュール ID のみ**を使用してください。 相対 ID ('../some/thing' など) は機能しません。

「*」マップ値もサポートされています。これは「ロードされたすべてのモジュールに対して、このマップ設定を使用する」という意味です。より具体的なマップ設定がある場合、そちらがスター設定よりも優先されます。例


requirejs.config({
    map: {
        '*': {
            'foo': 'foo1.2'
        },
        'some/oldmodule': {
            'foo': 'foo1.0'
        }
    }
});

これは、「some/oldmodule」を除くすべてのモジュールで、「foo」が必要な場合は代わりに「foo1.2」を使用することを意味します。「some/oldmodule」の場合のみ、「foo」が要求されたときに「foo1.0」を使用します。

注意: マップ設定を使用してビルドを行う場合、マップ設定をオプティマイザに渡す必要があります。また、ビルド出力には、マップ設定をセットアップするrequirejs設定呼び出しが引き続き含まれている必要があります。プロジェクト内の一部の依存関係参照は、実行時の変数の状態に依存する可能性があるため、オプティマイザはビルド中にIDの名前変更を行いません。そのため、オプティマイザは、ビルド後にマップ設定の必要性を無効にしません。

config: モジュールに設定情報を渡す必要があることがよくあります。その設定情報は通常、アプリケーションの一部として知られており、それをモジュールに渡す方法が必要です。RequireJSでは、これはrequirejs.config()のconfigオプションを使用して行われます。モジュールは、特別な依存関係「module」を要求し、module.config()を呼び出すことで、その情報を読み取ることができます。例

requirejs.config({
    config: {
        'bar': {
            size: 'large'
        },
        'baz': {
            color: 'blue'
        }
    }
});

//bar.js, which uses simplified CJS wrapping:
//https://requirejs.dokyumento.jp/docs/whyamd.html#sugar
define(function (require, exports, module) {
    //Will be the value 'large'
    var size = module.config().size;
});

//baz.js which uses a dependency array,
//it asks for the special module ID, 'module':
//https://github.com/requirejs/requirejs/wiki/Differences-between-the-simplified-CommonJS-wrapper-and-standard-AMD-define#wiki-magic
define(['module'], function (module) {
    //Will be the value 'blue'
    var color = module.config().color;
});

パッケージに設定を渡す場合は、パッケージIDではなく、パッケージ内のメインモジュールをターゲットにします。

requirejs.config({
    //Pass an API key for use in the pixie package's
    //main module.
    config: {
        'pixie/index': {
            apiKey: 'XJKDLNS'
        }
    },
    //Set up config for the "pixie" package, whose main
    //module is the index.js file in the pixie folder.
    packages: [
        {
            name: 'pixie',
            main: 'index'
        }
    ]
});

packages: CommonJSパッケージからのモジュールのロードを設定します。詳細はパッケージのトピックを参照してください。

nodeIdCompat: Nodeは、モジュールID `example.js` と `example` を同じものとして扱います。デフォルトでは、RequireJSではこれらは2つの異なるIDです。npmからインストールされたモジュールを使用する場合は、解決の問題を回避するために、この設定値を `true` に設定する必要がある場合があります。このオプションは、".js"サフィックスを異なる方法で扱う場合にのみ適用され、.jsonファイルの処理(JSON処理にはとにかく 'json!' ローダープラグインが必要です)など、他のノードの解決と評価のマッチングは行いません。2.1.10以降で使用可能です。

waitSeconds: スクリプトのロードをあきらめるまでの待機秒数。0に設定するとタイムアウトが無効になります。デフォルトは7秒です。

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

deps: ロードする依存関係の配列。require.jsがロードされる前にrequireが設定オブジェクトとして定義されている場合に、require()が定義されるとすぐにロードする依存関係を指定する場合に便利です。depsの使用は、`require([])` 呼び出しを実行するのと同じですが、ローダーが設定を処理するとすぐに実行されます。他のrequire()呼び出しがモジュールに対するリクエストを開始することをブロックしません。設定ブロックの一部として非同期的にロードするモジュールを指定する方法です。

callback: depsがロードされた後に実行する関数。require.jsがロードされる前にrequireが設定オブジェクトとして定義されている場合に、設定のdeps配列がロードされた後にrequireする関数を指定する場合に便利です。

enforceDefine: trueに設定すると、define()を呼び出さない、またはチェックできるshimエクスポート文字列値を持たないスクリプトがロードされた場合にエラーがスローされます。詳細は、IEでのロードエラーのキャッチを参照してください。

xhtml: trueに設定すると、document.createElementNS()を使用してスクリプト要素が作成されます。

urlArgs: RequireJSがリソースの取得に使用するURLに追加される追加のクエリ文字列引数。ブラウザまたはサーバーが正しく設定されていない場合のキャッシュ対策に最も役立ちます。urlArgsのキャッシュ対策設定の例

urlArgs: "bust=" +  (new Date()).getTime()

RequireJS 2.2.0以降、urlArgsは関数にすることができます。関数の場合、モジュールIDとURLをパラメーターとして受け取り、URLの末尾に追加される文字列を返す必要があります。引数がない場合は空の文字列を返します。URLの既存の状態に応じて、「?」または「&」を追加するように注意してください。例

requirejs.config({
    urlArgs: function(id, url) {
        var args = 'v=1';
        if (url.indexOf('view.html') !== -1) {
            args = 'v=2'
        }

        return (url.indexOf('?') === -1 ? '?' : '&') + args;
    }
});

開発中はこれを使用すると便利ですが、コードをデプロイする前に必ず削除してください。

scriptType: RequireJSによってドキュメントに挿入されるscriptタグに使用されるtype=""属性の値を指定します。デフォルトは "text/javascript"です。FirefoxのJavaScript 1.8機能を使用するには、 "text/javascript;version=1.8"を使用します。

skipDataMain: RequireJS 2.1.9で導入: `true`に設定すると、モジュールのロードを開始するために行われるdata-main属性のスキャンをスキップします。RequireJSがページ上の他のRequireJSライブラリと対話する可能性のあるユーティリティライブラリに埋め込まれており、埋め込まれたバージョンがdata-mainのロードを実行すべきでない場合に便利です。

高度な使用方法 § 4

パッケージからのモジュールのロード§ 4.1

RequireJSは、CommonJSパッケージディレクトリ構造にあるモジュールのロードをサポートしていますが、動作させるには、いくつかの追加設定を指定する必要があります。具体的には、次のCommonJSパッケージ機能がサポートされています

  • パッケージは、モジュール名/プレフィックスに関連付けることができます。
  • パッケージ設定では、特定のパッケージに対して次のプロパティを指定できます
    • name: パッケージの名前(モジュール名/プレフィックスマッピングに使用)
    • location: ディスク上の場所。場所は、プロトコルが含まれているか、スラッシュ(/)で始まる場合を除き、baseUrl設定値を基準とします。
    • main: 誰かが "packageName"のrequireを実行したときに使用する必要がある、パッケージ内のモジュールの名前。デフォルト値は "main" なので、デフォルトと異なる場合にのみ指定します。値はパッケージフォルダを基準とします。

重要な注意事項

  • パッケージはCommonJSディレクトリレイアウトを持つことができますが、モジュール自体はRequireJSが理解できるモジュール形式である必要があります。ルールの例外:r.js Nodeアダプターを使用している場合、モジュールは従来のCommonJSモジュール形式にすることができます。従来のCommonJSモジュールをRequireJSが使用する非同期モジュール形式に変換する必要がある場合は、CommonJSコンバーターツールを使用できます。
  • プロジェクトコンテキストでは、一度に1つのバージョンのパッケージのみを使用できます。RequireJSの複数バージョンサポートを使用して2つの異なるモジュールコンテキストをロードできますが、1つのコンテキストでパッケージAとBを使用し、それらが異なるバージョンのパッケージCに依存している場合は、問題が発生します。これは将来変更される可能性があります。

スタートガイドで指定されているのと同様のプロジェクトレイアウトを使用する場合、Webプロジェクトの開始は次のようになります(Node / Rhinoベースのプロジェクトも同様で、scriptsディレクトリのコンテンツをトップレベルのプロジェクトディレクトリとして使用します)

  • project-directory/
    • project.html
    • scripts/
      • require.js

2つのパッケージ、cartstoreを使用した例のディレクトリレイアウトは次のとおりです

  • project-directory/
    • project.html
    • scripts/
      • cart/
        • main.js
      • store/
        • main.js
        • util.js
      • main.js
      • require.js

project.htmlには、次のようなscriptタグがあります

<script data-main="scripts/main" src="scripts/require.js"></script>

これは、require.jsにscripts/main.jsをロードするように指示します。main.jsは "packages" 設定を使用して、require.jsを基準としたパッケージ(この場合はソースパッケージ "cart" と "store")を設定します

//main.js contents
//Pass a config object to require
require.config({
    "packages": ["cart", "store"]
});

require(["cart", "store", "store/util"],
function (cart,   store,   util) {
    //use the modules as usual.
});

"cart"のrequireは、 "main" がRequireJSでサポートされているデフォルトのメインモジュール設定であるため、scripts/cart/main.jsからロードされることを意味します。"store/util"のrequireは、scripts/store/util.jsからロードされます。

"store" パッケージが "main.js" 規則に従わず、次のようになっていた場合

  • project-directory/
    • project.html
    • scripts/
      • cart/
        • main.js
      • store/
        • store.js
        • util.js
      • main.js
      • package.json
      • require.js

RequireJSの設定は次のようになります

require.config({
    packages: [
        "cart",
        {
            name: "store",
            main: "store"
        }
    ]
});

冗長性を避けるため、構造に "main" 規則を使用するパッケージを常に使用することを強くお勧めします。

複数バージョンサポート§ 4.2

設定オプションで述べたように、異なる「コンテキスト」設定オプションを使用することにより、1つのページに複数のバージョンのモジュールをロードできます。require.config()は、コンテキスト設定を使用するrequire関数を返します。これは、alphaモジュールとbetaモジュールの2つの異なるバージョンをロードする例です(この例は、テストファイルの1つから引用しています)

<script src="../require.js"></script>
<script>
var reqOne = require.config({
  context: "version1",
  baseUrl: "version1"
});

reqOne(["require", "alpha", "beta",],
function(require,   alpha,   beta) {
  log("alpha version is: " + alpha.version); //prints 1
  log("beta version is: " + beta.version); //prints 1

  setTimeout(function() {
    require(["omega"],
      function(omega) {
        log("version1 omega loaded with version: " +
             omega.version); //prints 1
      }
    );
  }, 100);
});

var reqTwo = require.config({
      context: "version2",
      baseUrl: "version2"
    });

reqTwo(["require", "alpha", "beta"],
function(require,   alpha,   beta) {
  log("alpha version is: " + alpha.version); //prints 2
  log("beta version is: " + beta.version); //prints 2

  setTimeout(function() {
    require(["omega"],
      function(omega) {
        log("version2 omega loaded with version: " +
            omega.version); //prints 2
      }
    );
  }, 100);
});
</script>

モジュールの依存関係として「require」が指定されていることに注意してください。これにより、関数コールバックに渡されるrequire()関数は、複数バージョンをサポートするためにモジュールを正しくロードするための適切なコンテキストを使用できます。「require」が依存関係として指定されていない場合、エラーが発生する可能性があります。

ページのロード後にコードをロードする§ 4.3

上記の複数バージョンサポートセクションの例は、ネストされたrequire()呼び出しによって後でコードをロードする方法を示しています。

Webワーカーのサポート§ 4.4

リリース0.12以降、RequireJSはWebワーカー内で実行できます。Webワーカー内でimportScripts()を使用してrequire.js(またはrequire()定義を含むJSファイル)をロードし、requireを呼び出します。

require()がロードするスクリプトを見つけられるように、baseUrl 設定オプションを設定する必要があるでしょう。

単体テストで使用されているファイルの1つを見ると、その使用例を確認できます。

Rhinoのサポート§ 4.5

RequireJSは、r.jsアダプターを介してRhinoで使用できます。詳細は、r.js READMEを参照してください。

Nashornのサポート§ 4.6

RequireJS 2.1.16以降、RequireJSは、r.jsアダプターを介して、Java 8以降のJavaScriptエンジンであるNashornで使用できます。詳細は、r.js READMEを参照してください。

エラー処理§ 4.7

一般的なエラークラスは、スクリプトの404(見つかりません)、ネットワークタイムアウト、またはロードされたスクリプトのエラーです。RequireJSには、require固有のエラーバック、 "paths" 配列設定、グローバルrequirejs.onErrorなど、それらを処理するためのツールがいくつかあります。

エラーバックとグローバルrequirejs.onError関数に渡されるエラーオブジェクトには、通常、2つのカスタムプロパティが含まれています

  • requireType: "timeout"、 "nodefine"、 "scripterror" などの一般的な分類を含む文字列値。
  • requireModules: タイムアウトしたモジュール名/URLの配列です。

requireModulesでエラーが発生した場合、そのrequireModules配列内のモジュールに依存する他のモジュールが定義されていないことを意味します。

IEでの読み込み失敗のキャッチ § 4.6.1

Internet Explorerには、errbacks/pathsフォールバックの読み込み失敗を検出することを困難にする問題がいくつかあります。

  • script.onerrorはIE 6-8では動作しません。スクリプトの読み込みが404エラーを生成するかどうかを知る方法がなく、さらに悪いことに、404の場合でも完了状態のonreadystatechangeをトリガーします。
  • script.onerrorはIE 9+では動作しますが、スクリプトの実行直後にscript.onloadイベントハンドラを起動しないというバグがあるため、匿名AMDモジュールを許可する標準的な方法をサポートできません。そのため、script.onreadystatechangeが引き続き使用されます。ただし、onreadystatechangeはscript.onerror関数が起動する前に完了状態で起動します。

そのため、IEでは、AMDモジュールの主要な利点である匿名AMDモジュールと、信頼性の高いエラー検出の両方を許可することは非常に困難です。

ただし、すべてのモジュールの宣言にdefine()を使用することがわかっているプロジェクト、またはdefine()を使用しないすべてのものに文字列エクスポートを指定するためにshim設定を使用するプロジェクトでは、enforceDefine設定値をtrueに設定すると、ローダーはdefine()呼び出しまたはshimのエクスポートグローバル値の存在を確認することでスクリプトの読み込みを確認できます。

そのため、Internet Explorerをサポートし、読み込みエラーをキャッチし、define()呼び出しまたはshim設定を通じてモジュール化されたコードを使用する場合は、常にenforceDefineをtrueに設定してください。例については、次のセクションを参照してください。

注意: enforceDefine: trueを設定し、data-main=""を使用してメインJSモジュールを読み込む場合、そのメインJSモジュールは必要なコードを読み込むためにrequire()ではなくdefine()を呼び出す必要があります。メインJSモジュールは、設定値を設定するためにrequire/requirejsを呼び出すことはできますが、モジュールの読み込みにはdefine()を使用する必要があります。

さらに、almondを使用してrequire.jsなしでコードをビルドする場合、insertRequireビルド設定を使用してメインモジュールにrequire呼び出しを挿入してください。これは、data-mainが行う初期require()呼び出しと同じ目的を果たします。

require([]) errbacks § 4.6.2

Errbacksは、requirejs.undef()と共に使用すると、モジュールの読み込みに失敗したかどうかを検出し、そのモジュールの定義を解除し、設定を別の場所にリセットしてから再試行することができます。

この一般的なユースケースは、CDNでホストされているバージョンのライブラリを使用することですが、それが失敗した場合は、ファイルをローカルで読み込むように切り替えることです。

requirejs.config({
    enforceDefine: true,
    paths: {
        jquery: 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min'
    }
});

//Later
require(['jquery'], function ($) {
    //Do something with $ here
}, function (err) {
    //The errback, error callback
    //The error has a list of modules that failed
    var failedId = err.requireModules && err.requireModules[0];
    if (failedId === 'jquery') {
        //undef is function only on the global requirejs object.
        //Use it to clear internal knowledge of jQuery. Any modules
        //that were dependent on jQuery and in the middle of loading
        //will not be loaded yet, they will wait until a valid jQuery
        //does load.
        requirejs.undef(failedId);

        //Set the path to jQuery to local path
        requirejs.config({
            paths: {
                jquery: 'local/jquery'
            }
        });

        //Try again. Note that the above require callback
        //with the "Do something with $ here" comment will
        //be called if this new attempt to load jQuery succeeds.
        require(['jquery'], function () {});
    } else {
        //Some other error. Maybe show message to the user.
    }
});

`requirejs.undef()`を使用すると、後で別の設定を設定して同じモジュールを読み込もうとした場合でも、ローダーはその依存関係を必要とするモジュールを記憶し、新しく設定されたモジュールが読み込まれたときにそれらの読み込みを完了します。

注意: errbacksは、define()呼び出しではなく、コールバックスタイルのrequire呼び出しでのみ機能します。define()はモジュールの宣言専用です。

paths設定のフォールバック § 4.6.3

読み込みエラーの検出、モジュールのundef()、パスの変更、再読み込みのための上記のパターンは、一般的な要求であるため、そのための省略形もあります。paths設定では、配列値が許可されます。

requirejs.config({
    //To get timely, correct error triggers in IE, force a define/shim exports check.
    enforceDefine: true,
    paths: {
        jquery: [
            'http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min',
            //If the CDN location fails, load from this location
            'lib/jquery'
        ]
    }
});

//Later
require(['jquery'], function ($) {
});

上記のコードはCDNの場所を試しますが、それが失敗した場合は、ローカルのlib/jquery.jsの場所にフォールバックします。

注意: pathsフォールバックは、モジュールIDが完全に一致する場合にのみ機能します。これは、モジュールIDプレフィックスセグメントの任意の部分に適用できる通常のpaths設定とは異なります。フォールバックは、ブラウザでは非効率的であるため、一般的なパス検索パスソリューションではなく、まれなエラーリカバリを対象としています。

グローバルrequirejs.onError関数 § 4.6.4

ローカルerrbacksでキャッチされないエラーを検出するには、requirejs.onError()をオーバーライドします。

requirejs.onError = function (err) {
    console.log(err.requireType);
    if (err.requireType === 'timeout') {
        console.log('modules: ' + err.requireModules);
    }

    throw err;
};

ローダープラグイン § 5

RequireJSはローダープラグインをサポートしています。これは、プレーンなJSファイルではないが、スクリプトがその作業を行う前に読み込まれていることが重要な依存関係をサポートする方法です。RequireJS wikiにはプラグインのリストがあります。このセクションでは、RequireJSと共にメンテナンスされている特定のプラグインについて説明します。

テキストファイルの依存関係の指定§ 5.1

スクリプトでDOM構造を構築する代わりに、通常のHTMLタグを使用してHTMLを構築すると便利です。ただし、JavaScriptファイルにHTMLを埋め込む良い方法はありません。できることはせいぜいHTMLの文字列を使用することですが、特に複数行のHTMLの場合は管理が難しい場合があります。

RequireJSには、この問題に役立つプラグインtext.jsがあります。依存関係にtext!プレフィックスが使用されている場合、自動的に読み込まれます。詳細については、text.js READMEを参照してください。

ページ読み込みイベントのサポート/DOM Ready§ 5.2

RequireJSを使用すると、DOMの準備ができる前にスクリプトを十分に速く読み込んで完了させることができます。DOMと対話しようとする作業は、DOMの準備ができるまで待つ必要があります。最新のブラウザでは、これはDOMContentLoadedイベントを待つことによって行われます。

ただし、使用されているすべてのブラウザがDOMContentLoadedをサポートしているわけではありません。domReadyモジュールは、DOMの準備ができたことを判別するためのクロスブラウザメソッドを実装しています。モジュールをダウンロードし、プロジェクトで次のように使用します。

require(['domReady'], function (domReady) {
  domReady(function () {
    //This function is called once the DOM is ready.
    //It will be safe to query the DOM and manipulate
    //DOM nodes in this function.
  });
});

DOM readyは一般的なアプリケーションのニーズであるため、理想的には上記のAPIのネストされた関数は回避できます。domReadyモジュールはローダープラグインAPIも実装しているため、ローダープラグイン構文(domReady依存関係のに注意)を使用して、require()コールバック関数が実行される前にDOMの準備ができるまで強制的に待機させることができます。

domReady
は、ローダープラグインとして使用されると、現在のドキュメントを返します。

require(['domReady!'], function (doc) {
    //This function is called once the DOM is ready,
    //notice the value for 'domReady!' is the current
    //document.
});

注意: ドキュメントの読み込みに時間がかかる場合(ドキュメントが非常に大きい場合、またはHTMLスクリプトタグが完了するまでDOMの完了をブロックする大きなJSファイルを読み込んでいる場合など)、domReadyをローダープラグインとして使用すると、RequireJSの「タイムアウト」エラーが発生する可能性があります。これが問題になる場合は、waitSeconds設定を増やすか、domReadyをモジュールとして使用し、require()コールバック内でdomReady()を呼び出してください。

I18Nバンドルの定義§ 5.3

Webアプリがある程度の規模と人気になると、インターフェースの文字列をローカライズし、他のロケール固有の情報を提供することがより便利になります。ただし、複数のロケールをサポートするために適切にスケールするスキームを作成するのは面倒な場合があります。

RequireJSを使用すると、すべてのロケール固有の情報を前もって提供することを強制することなく、ローカライズされた情報を持つ基本モジュールを設定できます。時間の経過とともに追加でき、ロケール間で変化する文字列/値のみをロケール固有のファイルで定義できます。

i18nバンドルのサポートは、i18n.jsプラグインによって提供されます。モジュールまたは依存関係がi18n!プレフィックスを指定すると、自動的に読み込まれます(詳細は以下)。プラグインをダウンロードし、アプリのメインJSファイルと同じディレクトリに配置します。

バンドルを定義するには、それを「nls」というディレクトリに配置します。i18n!プラグインは、「nls」を含むモジュール名がi18nバンドルを示していると想定しています。名前の「nls」マーカーは、i18nプラグインにロケールディレクトリの場所を指示します(nlsディレクトリの直接の子である必要があります)。「my」モジュールセットに色の名前のバンドルを提供する場合、次のようなディレクトリ構造を作成します。

  • my/nls/colors.js

そのファイルの内容は次のようになります。

//my/nls/colors.js contents:
define({
    "root": {
        "red": "red",
        "blue": "blue",
        "green": "green"
    }
});

「root」プロパティを持つオブジェクトリテラルがこのモジュールを定義します。これは、後のローカライズ作業の準備をするために必要なすべてです。

その後、上記のモジュールを別のモジュール、たとえばmy/lamps.jsファイルで使用できます。

//Contents of my/lamps.js
define(["i18n!my/nls/colors"], function(colors) {
    return {
        testMessage: "The name for red in this locale is: " + colors.red
    }
});

my/lampsモジュールには、「testMessage」というプロパティが1つあり、colors.redを使用して赤色のローカライズされた値を表示します。

後で、特定の翻訳をファイルに追加する場合、たとえばfr-frロケールの場合、my/nls/colorsを次のように変更します。

//Contents of my/nls/colors.js
define({
    "root": {
        "red": "red",
        "blue": "blue",
        "green": "green"
    },
    "fr-fr": true
});

次に、次の内容を持つファイルをmy/nls/fr-fr/colors.jsに定義します。

//Contents of my/nls/fr-fr/colors.js
define({
    "red": "rouge",
    "blue": "bleu",
    "green": "vert"
});

RequireJSは、ブラウザのnavigator.languages、navigator.language、またはnavigator.userLanguageプロパティを使用して、my/nls/colorsに使用するロケール値を決定するため、アプリを変更する必要はありません。ロケールを設定する場合は、モジュール設定を使用してロケールをプラグインに渡すことができます。

requirejs.config({
    config: {
        //Set the config for the i18n
        //module ID
        i18n: {
            locale: 'fr-fr'
        }
    }
});

注意 RequireJSは大文字と小文字の問題を回避するために、常にロケールを小文字バージョンで使用するため、i18nバンドルのディスク上のすべてのディレクトリとファイルは小文字のロケールを使用する必要があります。

RequireJSは、my/nls/colorsによって提供されるものに最も近いロケールバンドルを賢く選択します。たとえば、ロケールが「en-us」の場合、「root」バンドルが使用されます。ロケールが「fr-fr-paris」の場合、「fr-fr」バンドルが使用されます。

RequireJSはバンドルも組み合わせるため、たとえば、フランス語のバンドルが次のように定義されている場合(赤の値を省略)、

//Contents of my/nls/fr-fr/colors.js
define({
    "blue": "bleu",
    "green": "vert"
});

「root」の赤の値が使用されます。これはすべてのロケールピースで機能します。以下のすべてのバンドルが定義されている場合、RequireJSは次の優先順位(最上位のものが最も優先されます)で値を使用します。

  • my/nls/fr-fr-paris/colors.js
  • my/nls/fr-fr/colors.js
  • my/nls/fr/colors.js
  • my/nls/colors.js

ルートバンドルをトップレベルモジュールに含めない場合は、通常のロケールバンドルのように定義できます。その場合、トップレベルモジュールは次のようになります。

//my/nls/colors.js contents:
define({
    "root": true,
    "fr-fr": true,
    "fr-fr-paris": true
});

ルートバンドルは次のようになります。

//Contents of my/nls/root/colors.js
define({
    "red": "red",
    "blue": "blue",
    "green": "green"
});