RequireJS オプティマイザ
- 必要条件§ 1
- ダウンロード§ 2
- 設定例§ 3
- 基本§ 4
- 1 つの JavaScript ファイルの最適化§ 5
- 高速開発のための浅い除外§ 6
- ネットワーク/CDN リソースのための empty: パス§ 7
- 1 つの CSS ファイルの最適化§ 8
- プロジェクト全体の最適化§ 9
- 複数ページプロジェクトの最適化§ 10
- ターボオプション§ 11
- has.js との統合§ 12
- ソースマップ§ 13
- すべての設定オプション§ 14
- デプロイメント手法§ 15
- よくある落とし穴§ 16
RequireJS には、以下の機能を持つ最適化ツールがあります。
- 関連するスクリプトをビルドレイヤーに結合し、UglifyJS(デフォルト)またはClosure Compiler(Java を使用する場合のオプション)を使用して縮小します。
- @import で参照されている CSS ファイルをインライン化し、コメントを削除することで CSS を最適化します。
オプティマイザは、Node.js と Nashorn 用の r.js アダプターの一部であり、開発が完了し、ユーザー向けにコードをデプロイする準備が整った後に、ビルドまたはパッケージ化ステップの一部として実行されるように設計されています。
オプティマイザは、トップレベルの require および define 呼び出しに渡される文字列リテラルの配列、または簡略化された CommonJS ラップ内の require('name') 文字列リテラル呼び出しで指定されたモジュールのみを結合します。そのため、変数名を使用してロードされたモジュールは検出しません。
var mods = someCondition ? ['a', 'b'] : ['c', 'd'];
require(mods);
しかし、「a」と「b」は次のように指定した場合、含まれます。
require(['a', 'b']);
または
define(['a', 'b'], function (a, b) {});
この動作により、最適化後でもモジュールの動的な読み込みが可能です。**include** オプションを使用することで、オプティマイザの静的解析では見つからないモジュールを明示的に追加できます。
必要条件 § 1
オプティマイザは、Node.js、Rhino または Nashorn を使用した Java、またはブラウザを使用して実行できます。各オプションの必要条件は以下のとおりです。
- Node.js:(推奨)Node.js 0.4.0 以降。
- Java: Java 1.6 以降。
- ブラウザ: 2.1.2 以降、オプティマイザは配列の追加機能を備えたWebブラウザで実行できます。オプティマイザのオプションは下記と同じですが、コマンドラインオプションではなく JavaScript を介して呼び出されます。また、ディレクトリの最適化ではなく、最適化された単一ファイルの生成にのみ適しています。ブラウザの例を参照してください。このオプションは、ライブラリのWebベースのカスタムビルドを提供する場合にのみ本当に役立ちます。
コマンドラインを使用する場合は、Node.js が推奨される実行環境です。オプティマイザは Node.js を使用すると**はるかに高速**に動作します。
このページの例のコマンドはすべて、Node.js の使用と Linux/OS X コマンドラインでの実行を前提としています。Java で実行する方法については、r.js のREADMEを参照してください。
ダウンロード§ 2
1) ツールはダウンロードページからダウンロードできます。
2) NPM を使用した Node.js を使用している場合は、NPM の「requirejs」パッケージの一部として r.js をグローバルにインストールできます。
> npm install -g requirejs
> r.js -o app.build.js
Windows の場合、r.js
の代わりに r.js.cmd
を入力する必要がある場合があります。または、DOSKEY を使用できます。
DOSKEY r.js=r.js.cmd $*
グローバルではなく、npm パッケージとしてプロジェクトに requirejs をローカルにインストールする場合は、
> npm install requirejs
このローカルインストールでは、プロジェクトのnode_modules/.bin
ディレクトリにあるr.js
またはr.js.cmd
ファイルを実行することで、オプティマイザを実行できます。
ローカルインストールでは、Nodeプログラム内で関数呼び出しを介してオプティマイザを使用することもできます。
このページの残りの部分は、r.js がダウンロードページから手動でダウンロードされたことを前提としています。通常、オプティマイザを使用する最も明確で移植性の高い方法です。
設定例§ 3
このページの例では、プロジェクトディレクトリと兄弟関係にあるディレクトリに r.js をダウンロードして保存したことを前提としています。r.js に含まれるオプティマイザはどこにでも配置できますが、これらの例ではそれに応じてパスを調整する必要がある可能性があります。
設定例
- appdirectory
- main.html
- css
- common.css
- main.css
- scripts
- require.js
- main.js
- one.js
- two.js
- three.js
- r.js (ダウンロードページからの r.js オプティマイザ)
main.html には、require.js のスクリプトタグがあり、次のように require 呼び出しを介して main.js をロードします。
<!DOCTYPE html>
<html>
<head>
<title>My App</title>
<link rel="stylesheet" type="text/css" href="css/main.css">
<script data-main="scripts/main" src="scripts/require.js"></script>
</head>
<body>
<h1>My App</h1>
</body>
</html>
main.js は、require 呼び出しを介して one.js、two.js、three.js をロードします。
require(["one", "two", "three"], function (one, two, three) {
});
main.css には、次の様な内容があります。
@import url("common.css");
.app {
background: transparent url(../../img/app.png);
}
基本 § 4
コマンドライン引数は、ビルドプロファイルのプロパティと交換可能です。
コマンドラインでオプションを指定できます。
node r.js -o baseUrl=. paths.jquery=some/other/jquery name=main out=main-built.js
またはビルドプロファイルで指定できます。**build.js** では、同じコマンドライン引数を次のように指定できます。
({
baseUrl: ".",
paths: {
jquery: "some/other/jquery"
},
name: "main",
out: "main-built.js"
})
そして、ビルドプロファイルのファイル名をオプティマイザに渡すだけです。
node r.js -o build.js
コマンドライン引数はビルドプロファイルの設定よりも優先され、両方を組み合わせることができます。
node r.js -o build.js optimize=none
コマンドライン引数の構文には**制限**があります。ドットはオブジェクトプロパティのセパレータと見なされるため、paths.jquery=lib/jquery
のようなものをオプティマイザで次のように変換できます。
paths: {
jquery: 'lib/jquery'
}
しかし、これは「core/jquery.tabs」の paths プロパティの値を値に設定できないことを意味します。これは機能しません: paths.core/jquery.tabs=empty:
、これは次の間違った構造になるためです。
paths: {
'core/jquery': {
tabs: 'empty:'
}
}
「core/jquery.tabs」のようなパスを設定する必要がある場合は、コマンドライン引数を使用する代わりに、ビルドオプションを JavaScript オブジェクトとして指定した build.js ファイルを使用してください。
すべてのオプションのリストについては、すべての設定オプションを参照してください。
相対パスの解決ルール:
一般的に、パスであれば、ビルドオプションを保持するために使用される build.js ファイルを基準とした相対パスです。コマンドライン引数のみを使用する場合は、現在の作業ディレクトリを基準とした相対パスです。ファイルパスの例: **appDir**、**dir**、**mainConfigFile**、**out**、**wrap.startFile**、**wrap.endFile**。
**baseUrl** の場合、**appDir** を基準とした相対パスです。appDir がない場合、baseUrl は build.js ファイルを基準とした相対パスです。コマンドライン引数のみを使用する場合は、現在の作業ディレクトリを基準とした相対パスです。
**paths** と **packages** の場合、require.js と同様に、**baseUrl** を基準とした相対パスです。
モジュールIDであるプロパティは、モジュールIDでなければならず、ファイルパスではありません。例:**name**、**include**、**exclude**、**excludeShallow**、**deps**。
実行時にブラウザでロードされるメインJSモジュールの設定は、**デフォルトではオプティマイザによって読み取られません**。
これは、ビルドの構成設定が最適化目標が複数あるため非常に異なる可能性があるためです。そのため、最適化ツールに対して個別の構成オプションセットを指定する必要があります。
最適化ツールのバージョン1.0.5以降では、**mainConfigFile** オプションを使用して、ランタイム構成の場所を指定できます。メインのJSファイルへのパスを指定すると、そのファイル内にある最初の`requirejs({}), requirejs.config({}), require({}), または require.config({})` が解析され、最適化ツールに渡される構成オプションの一部として使用されます。
mainConfigFile: 'path/to/main.js'
構成の優先順位:コマンドライン、ビルドプロファイル、mainConfigFile。つまり、mainConfigFile構成の優先順位は最も低くなります。
1つのJavaScriptファイルの最適化 § 5
上記の例の設定を使用して、main.jsのみを最適化したい場合は、**appdirectory/scripts** ディレクトリ内から次のコマンドを使用できます。
node ../../r.js -o name=main out=main-built.js baseUrl=.
これにより、**appdirectory/scripts/main-built.js** というファイルが作成され、main.js、one.js、two.js、およびthree.jsの内容が含まれます。
通常、最適化されたファイルを元のプロジェクトソースと共に保存するべきではありません。通常はプロジェクトのコピーに保存しますが、この例を簡単にするためにソースと共に保存します。お好みのディレクトリ(ソースのコピーがあるディレクトリ)に**out=**オプションを変更してください。その後、main-built.jsファイル名をmain.jsに変更して、HTMLページで最適化されたバージョンのファイルを読み込むようにできます。
main.jsソースにrequire.jsを含めたい場合は、次のようなコマンドを使用できます。
node ../../r.js -o baseUrl=. paths.requireLib=../../require name=main include=requireLib out=main-built.js
"require"は予約済みの依存関係名であるため、"requireLib"という依存関係を作成し、それをrequire.jsファイルにマップします。
最適化が完了したら、スクリプトタグを変更して"require.js"ではなく"main-built.js"を参照するようにすると、最適化されたプロジェクトではスクリプトリクエストを1つだけ行う必要があります。
RequireJSのようなAMDローダーがないページで使用できるように、ビルド済みファイルをラップしたい場合は、最適化に関するFAQを参照してください。
高速開発のための浅い除外§ 6
1つのJavaScriptファイルの最適化アプローチを使用して、開発エクスペリエンスを高速化できます。現在開発中のものを除いて、プロジェクト内のすべてのモジュールを1つのファイルに最適化することで、ブラウザでプロジェクトをすばやく再読み込みできますが、モジュールで詳細なデバッグを行うこともできます。
これは、**excludeShallow** オプションを使用することで実現できます。上記の例の設定を使用して、現在two.jsを構築またはデバッグしていると仮定します。この最適化コマンドを使用できます。
node ../../r.js -o name=main excludeShallow=two out=main-built.js baseUrl=.
main-build.jsファイルを縮小したくない場合は、上記のコマンドに**optimize=none**を渡します。
次に、"main"に使用されるパスを"main-built"に設定することで、HTMLページがmain-built.jsファイルを読み込むように構成します。
<!DOCTYPE html>
<html>
<head>
<title>My App</title>
<link rel="stylesheet" type="text/css" href="css/main.css">
<script src="scripts/require.js"></script>
<script>
require.config({
paths: {
//Comment out this line to go back to loading
//the non-optimized main.js source file.
"main": "main-built"
}
});
require(["main"]);
</script>
</head>
<body>
<h1>My App</h1>
</body>
</html>
このページが読み込まれると、"main"のrequire()はmain-built.jsファイルを読み込みます。excludeShallowによってtwo.jsのみが除外されているため、two.jsは別々のファイルとして読み込まれ、ブラウザのデバッガーで別々のファイルとして表示されるため、ブレークポイントを設定して個々の変更をより適切に追跡できます。
empty: ネットワーク/CDNリソースのパス§ 7
コンテンツ配信ネットワーク(CDN)または別のドメイン上の他のサーバーから読み込みたいスクリプトがある場合があります。
最適化ツールはネットワークリソースを読み込むことができないため、ビルドに含めたい場合は、ファイルをモジュール名にマップするpaths構成を作成してください。次に、最適化ツールを実行するために、CDNスクリプトをダウンロードし、モジュール名をローカルファイルパスにマップするpaths構成を最適化ツールに渡します。
ただし、ビルドにそのリソースを含めたくない可能性が高いです。スクリプトに依存関係がない場合、またはその依存関係を含めたくない場合、または別の方法で含める場合は、paths構成で特別な**'empty:'スキーム**を使用して、最適化を実行するときにファイルをスキップできます。
main.jsファイルで、スクリプトにモジュール名を与えるpaths構成を作成します。これは、スクリプトがdefine()の呼び出しによってモジュールを定義していない場合でも実行できます。paths構成は、短いモジュール/スクリプトIDをURLにマップするためにのみ使用されます。これにより、最適化のために異なるpaths構成を使用できます。main.jsでは
requirejs.config({
paths: {
'jquery': 'https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min'
}
});
require(['jquery'], function ($) {
});
次に、最適化ツールを実行するときに、paths構成に'empty:'を使用します。
node ../../r.js -o name=main out=main-built.js baseUrl=. paths.jquery=empty:
または、ビルドプロファイルで
({
baseUrl: ".",
name: "main",
out: "main-built.js",
paths: {
jquery: "empty:"
}
})
1つのCSSファイルの最適化§ 8
上記の例の設定を使用して、main.cssのみを最適化したい場合は、**appdirectory/css** ディレクトリ内から次のコマンドを使用できます。
node ../../r.js -o cssIn=main.css out=main-built.css
これにより、**appdirectory/css/main-build.css** というファイルが作成され、main.cssの内容が含まれ、url()パスが適切に調整され、コメントが削除されます。
1つのJavaScriptファイルの最適化に関するメモを参照して、元のソースツリーに最適化されたファイルを保存しないようにしてください。これは、例を簡素化するためにのみ行われています。
注:url()パスの修正は、**out**ビルドオプションではなく、**cssIn**ビルドオプションのパスを基準にパスを常に修正します。プロジェクト全体の最適化§ 9
最適化ツールは、ビルドプロファイルを使用してプロジェクト内のすべてのCSSファイルとJSファイルを最適化できます。
ビルドプロファイルを作成し、app.build.jsと名付けて**scripts**ディレクトリに入れます。app.build.jsファイルはどこにでも配置できますが、以下の例でパスを適切に調整してください。すべてのパスは、app.build.jsの場所を基準とします。app.build.jsの例
({
appDir: "../",
baseUrl: "scripts",
dir: "../../appdirectory-build",
modules: [
{
name: "main"
}
]
})
このビルドプロファイルは、RequireJSに**appdirectory**全体を**appdirectory-build**という兄弟ディレクトリにコピーし、**appdirectory-build**ディレクトリ内のすべての最適化を適用するように指示します。ソースディレクトリとは異なる出力ディレクトリを使用することを強くお勧めします。そうでなければ、最適化ツールがソースを上書きするため、問題が発生する可能性があります。
RequireJSは、**baseUrl**を使用して、モジュール名のパスを解決します。**baseUrl**は**appDir**を基準とする必要があります。
**modules**配列で、最適化したいモジュール名を指定します(例:「main」)。「main」はプロジェクトの**appdirectory/scripts/main.js**にマップされます。次に、ビルドシステムはmain.jsの依存関係をトレースし、**appdirectory-build/scripts/main.js**ファイルに挿入します。
また、**appdirectory-build**内で見つかったすべてのCSSファイルも最適化します。
ビルドを実行するには、**appdirectory/scripts**ディレクトリ内から次のコマンドを実行します。
node ../../r.js -o app.build.js
ビルドが完了したら、**appdirectory-build**を最適化されたプロジェクトとして使用して、展開の準備ができます。
複数ページプロジェクトの最適化§ 10
requirejs/example-multipageは、複数のページを持つプロジェクトの例ですが、共通の構成と共通の最適化されたビルドレイヤーを共有しています。
ターボオプション§ 11
最適化ツールのデフォルトは、ビルド後の予期せぬ事態を回避するための最も安全で堅牢な一連のアクションを実行することです。ただし、プロジェクトの設定によっては、これらの機能の一部をオフにしてビルドを高速化したい場合があります。
- 最大の時間消費は縮小です。開発ワークフローの一部としてビルドを実行しているだけの場合、**optimize**を「none」に設定します。
- プロジェクト全体の最適化を実行しているが、**modules**オプションで指定されたビルドレイヤーのみを縮小し、ビルド出力ディレクトリの他のJSファイルは縮小したくない場合は、**skipDirOptimize**を「true」に設定できます。
- 通常、プロジェクト全体の最適化を実行するたびに、**dir**で指定された出力ビルドディレクトリがクリーンアップのために削除されます。**onBuildWrite**などのビルドオプションは、同じファイルに対して2回実行すると危険な方法で出力ディレクトリを変更します。ただし、ビルドレイヤーの縮小以外の追加のファイル変換がない単純なビルドを実行している場合は、**keepBuildDir**を「true」に設定して、実行間でビルドディレクトリを保持できます。次に、ビルド実行間で変更されたファイルのみがコピーされます。
バージョン2.1.2以降、**optimize**が「none」に設定されている場合、最適化ツールはデフォルトでいくつかの速度ショートカットを実行します。ただし、**optimize**に「none」を使用していて、最適化ツールの実行後にビルド済みファイルを縮小する予定がある場合は、**normalizeDirDefines**を「all」に設定して、define()呼び出しが縮小に耐えられるように正しく正規化してください。**optimize**オプションを使用して縮小を実行している場合は、このオプションの設定について心配する必要はありません。
has.jsとの統合§ 12
has.jsは、プロジェクトに簡単な機能検出を追加する優れたツールです。has.jsテストのコードパスを最適化するための最適化ツールのサポートがいくつかあります。
コードで次のテストを使用する場合
if (has("someThing")) {
//use native someThing
} else {
//do some workaround
}
いくつかのhas()テストに対してtrueまたはfalseの値を持つ**has**オブジェクトをビルド構成で定義すると、最適化ツールはhas()テストをtrueまたはfalseの値に置き換えます。
ビルドプロファイルが次のようになっている場合
({
baseUrl: ".",
name: "hasTestModule",
out: "builds/hasTestModule.js",
has: {
someThing: true
}
})
最適化ツールは上記コードサンプルを次のように変換します。
if (true) {
//use native someThing
} else {
//do some workaround
}
次に、r.js 0.26.0以降でデフォルトのoptimize設定「uglify」を使用する場合、または**optimize**設定が「closure」に設定されている場合(Javaで実行)、ミニファイアはデッドコードブランチを最適化して削除します!そのため、一連のhas()テストに対して最適化されたコードのカスタムビルドを行うことができます。
ソースマップ§ 13
バージョン2.1.6以降では、ソースマップの実験的なサポートが提供されています。これは、縮小化されバンドルされたコードを、縮小化されていない個別のモジュールにマッピングする場合に機能し、optimizeが"uglify2"
に設定されている場合のみ有効です。"closure"
に設定されている場合、縮小化されバンドルされたコードを、縮小化されていないバンドルされたコードにのみマッピングできます(closureは、JavaとRhinoを使用している場合のみ利用可能です)。縮小化されていないファイルは、開発者ツールに「.src.js」というファイル拡張子で表示されます。
ソースマップの生成を有効にするには、generateSourceMapsをtrue
に設定します。ミニファイアはソースマップを生成するために、縮小化されたファイルに対して完全な制御権を持つ必要があるため、preserveLicenseCommentsはfalse
に明示的に設定する必要があります。縮小化されたソースにいくつかのライセンスコメントを含める方法もあります。
最適化ツールは、(useSourceUrlをtrue
に設定することで)sourceURLをサポートしており、結合されたモジュールを個々のファイルとしてデバッグできます。ただし、これは縮小化されていないコードでのみ機能します。ソースマップは、縮小化されたファイルを縮小化されていないバージョンに変換します。useSourceUrlはソース値を文字列として必要とするため、generateSourceMapsとuseSourceUrlを同時に使用することは意味がありません。generateSourceMapsとの組み合わせで有効な縮小化が行われなくなります。
すべての設定オプション§ 14
requirejs/buildディレクトリには、許容されるすべての最適化ツールの設定オプションの詳細が記載されたexample.build.jsファイルがあります。
デプロイメント手法§ 15
r.js最適化ツールは、その上に他のコードを追加することで、さまざまなデプロイメントシナリオで使用できるいくつかのプリミティブを提供するように設計されています。最適化ツールをそのように使用する方法については、デプロイメント手法に関するwikiページを参照してください。
よくある問題点§ 16
以下の例で問題が発生する場合は、問題の原因となる可能性のある一般的な問題点をいくつかご紹介します。
JavaScriptのソース領域内に出力ディレクトリを指定しないでください。
たとえば、baseUrlが'js'で、ビルド出力が'js/build'に入力される場合、各最適化実行で生成される追加のネストされたファイルに問題が発生する可能性があります。このガイダンスは、単一ファイルの最適化ではない最適化のみに適用されます。
baseUrlの外部にある最適化名を使用しないでください。
たとえば、baseUrlが'js'で、最適化ターゲットが
name: '../main'
の場合、最適化によってファイルが出力ディレクトリの外部に上書きまたは配置される可能性があります。このような場合は、paths設定を作成して、そのファイルを次のようなローカル名にマップします。
paths: {
main: '../main'
}
次に、名前
name: 'main'
を最適化ターゲットとして使用します。
shim設定のビルド上の制限に注意してください。 特に、CDNからshimmedライブラリの依存関係を読み込むことはできません。shim設定のセクションで詳細を確認してください。