require/define/requirejs をリネームするには?§ 1

この機能を使用するには、RequireJS とその最適化ツールがバージョン 0.26.0 以上である必要があります。

なぜこれを行う必要があるのでしょうか?グローバル名前空間に非常に厳格な要件がある場合や、すでに require/define を定義しているコードを使用しており、干渉を避けたい場合などです。

この機能に関するいくつかの注意点

  • minify版ではなく、RequireJSのソースバージョンを使用してください。
  • 名前空間設定が機能するように、RequireJSファイルの内容が変更されるため、最適化にRequireJSのバージョンが含まれていることを確認してください。
  • モジュールは通常どおり require/define を使用してコードを記述し、値を名前空間化するためのビルドを実行します。名前空間化された require/define を使用してモジュールをコード化しないでください。コードの移植性と他のユーザーによる使用が困難になります。
  • この変換/最適化は 1 回のみ機能します。この最適化の出力を別の最適化/ビルド ステージへの入力として使用しないでください。

次の最適化構成の例は、最適化ページの例で使用されているディレクトリ構造に基づいています。この構成では、require.js と main.js を組み合わせて新しい foo.js ファイルを作成します。define() は foo.define() に、require() は foo.require() にリネームされます。


{
    appDir: "../",
    baseUrl: "scripts",
    dir: "../../appdirectory-build",

    //Put in a mapping so that 'requireLib' in the
    //modules section below will refer to the require.js
    //contents.
    paths: {
        requireLib: 'require'
    },

    //Indicates the namespace to use for require/requirejs/define.
    namespace: "foo",

    modules: [
        {
            name: "foo",
            include: ["requireLib", "main"],
            //True tells the optimizer it is OK to create
            //a new file foo.js. Normally the optimizer
            //wants foo.js to exist in the source directory.
            create: true
        }
    ]
}

この最適化が完了したら、require.js を参照していた HTML を foo.js を参照するように変更する必要があります。

名前空間設計にご協力いただいた Ryan Florence に感謝します。


リネームする別の方法として、コンテンツをより直接的に制御したい場合や、修正されたソース コードをコミットしたい場合は、以下の方法があります。この方法は、上記の「名前空間」最適化と組み合わせて使用しないでください

1) require.js のソースを修正する

require 関数を任意の名前を設定できるように、require.js コードをラップする必要があります。

var myGlobalRequire = (function () {
    //Define a require object here that has any
    //default configuration you want for RequireJS. If
    //you do not have any config options you want to set,
    //just use an simple object literal, {}. You may need
    //to at least set baseUrl.
    var require = {
        baseUrl: '..'
    };

    //INSERT require.js CONTENTS HERE

    return require;
}());

2) ロードされたファイルを修正する

この新しい関数でロードするファイルで、require が何らかの形で参照されている場合は、require の値を手順 1 で設定した新しい関数名にするために、それらのファイルを匿名関数でラップする必要があります。

(function (require) {

    //Regular require references now work correctly in here.

}(myGlobalRequire));

上記の手順に従うと、最適化ツールを使用してスクリプトを効果的に結合できるようになります。最適化されたスクリプトにリネームされた require 定義を含める場合は、最適化オプションの include で修正した require.js を直接参照するか、そのファイルを直接最適化する場合は name オプションとして参照します。

このソリューションの一部をご提案いただいた Alex SextonTobie Langel に感謝します。

CSS のロードはどうすればいいですか?§ 2

理想的には、RequireJS は CSS ファイルを依存関係としてロードできます。ただし、特に Gecko/Firefox でファイルを別のドメインからロードした場合、CSS ファイルがいつロードされたかを把握するのに問題があります。これまでの経緯については、この Dojo チケットをご覧ください。

ファイルがロードされたタイミングを把握することは重要です。スタイルシートがロードされた後でのみ DOM 要素のサイズを取得したい場合があるためです。

一部の人々は、スタイルシートがロードされたかどうかを知るために、特定の HTML 要素に適用される既知のスタイルを探すというアプローチを実装しています。このソリューションの特殊性から、RequireJS にはうまく適合しないでしょう。link 要素が参照ファイルをロードしたタイミングを把握することが最も堅牢な解決策となります。

ファイルがロードされたタイミングを確実に把握することはできないため、RequireJS のロードで CSS ファイルを明示的にサポートするのは適切ではありません。ブラウザの動作によりバグレポートにつながる可能性があるためです。ファイルがいつロードされるかを気にしないのであれば、次の方法でオンデマンドで CSS をロードする独自の関数を簡単に記述できます。

function loadCss(url) {
    var link = document.createElement("link");
    link.type = "text/css";
    link.rel = "stylesheet";
    link.href = url;
    document.getElementsByTagName("head")[0].appendChild(link);
}