ローダー
このサイトは作成途中のものを公開しています。 また、Webpackのバージョンが1.13.0の頃に作成されたものですが、2017年2月現在Webpackは1系を非推奨として2の使用を勧めています。
はじめに
ローダーはrequire()
、またはそれらを"load"(読み込む)ことでファイルのプリプロセス(予め変換やトランスパイルすること)を可能にします。
ローダーは他のビルドツールでいうところの"タスク"の類であり、
フロントエンドのビルド手順を処理するための強力な方法を提供してくれます。
ローダーはCoffeeScriptからJavaScriptのような異なる言語の変換、data URIのインライン画像などの変換を行うことが可能です。
ローダーは正式なCSSファイルをJavaScriptでrequire()
するといったことも可能にしてくれます。
ローダーを使用してモジュールを変換する事をwebpackに伝えるために、
require
の呼び出しのようなモジュールのリクエスト時に、ローダーを指定することが可能です。
var moduleWithOneLoader = require("my-loader!./my-awesome-module");
モジュールのパスとローダーを区切る!
構文に注意してください。
ローダーはモジュールのように、ローダーの名前の代わりに相対パス(必要とあらば)を指定することも可能です。
require("./loaders/my-loader!./my-awesome-module");
!
を使用してローダーを区切ることで、ローダーをチェーンさせて纏めることも可能です。
これはファイルに対して、パイプラインのようにして複数の変換を適用する際に便利です。
require("style-loader!css-loader!less-loader!./my-styles.less");
パラメーター
ローダーはクエリー・パラメーターを受け取ることが可能です。
require("loader?with=parameter!./file");
クエリー文字列のフォーマットはローダーに依ります。 そのため、ローダーのドキュメントを調べて、ローダーが受け入れるパラーメーターについて理解しておく必要があります。 ただし、一般的に多くのローダーは伝統的なクエリー文字列のフォーマットをサポートします。
設定(ファイル)によるローダーの指定
各モジュールのリクエストでローダーを指定することは、コードを壊れやすく冗長なものにしてしまいます。 webpackは設定ファイル内で、異なるタイプのファイルに対して、どのローダーを適用するのかを指定する方法を提供します。 設定にローダーを指定することは、 コードに特定のビルド構文を追加する必要が無くなり、再利用性が高まることから、ほとんどのケースで推奨されています。
{
module: {
loaders: [
{ test: /\.coffee$/, loader: "coffee-loader" }
],
preLoaders: [
{ test: /\.coffee$/, loader: "coffee-hint-loader" }
]
}
};
ローダーの設定の詳細については、設定のページを参照してください。
ローダーの順番
ファイルシステムからのファイルの読み込み後、ローダーは次の順序でそれに対しての実行が行われます。
- 設定に指定されている
preloaders
- 設定に指定されている
loaders
- リクエストで指定されるローダー (例:
require('raw!./file.js')
) - 設定に指定されている
postLoaders
また、特殊なケースを想定して、設定によるローダー順序をモジュールのリクエストで上書きすることも可能です。
-
リクエストに
!
を追加すると、設定されたpreLoaders
を無効にします。require("!raw!./script.coffee")
-
リクエストに
!!
を追加すると、設定で指定されている全てのローダーを無効にします。require("!!raw!./script.coffee")
-
リクエストに
-!
を追加すると、設定で指定されている全てのpreLoaders
とloaders
を無効にします。ただし、postLoaders
は無効になりません。require("-!raw!./script.coffee")
推奨
手順2の後は、結果がJavaScriptになることが推奨されます。
非JavaScriptからJavaScriptへの変換は、手順1(またはそれらがグローバルに適用されない場合は手順2)で適用することが推奨されます。
同じ言語の状態が継続される場合、それはpreまたはpostのローダー内で行うことが推奨されます。
上書きしたいソースコードが非JavaScriptからJavaScriptへの変換の場合、!
接頭辞(prefix)を使用するべきです。
(つまり、別の方法で変換するケース)
!!
と-!
接頭辞(prefix)を使用してローダーを無効化することは、
別のローダーからのケースを除いて推奨されません。
- preLoaderに適した例: イメージ圧縮
- loader(設定内)に適した例: coffee-script変換
- loader(リクエスト)に適した例: バンドル・ローダー
- postLoaderに適した例: コード・カバレッジの計測
ローダーを作る(書く)には
ローダーを書くのは、非常に単純です。 ローダーは関数をexportする単なるファイルです。 コンパイラはこの関数を呼び出し、1つ前のローダーの結果、または取り込まれたリソース・ファイルを渡します。
この関数のthis
コンテキストにはコンパイラによって便利なメソッドが提供され、
ローダーで様々な事を行ったり、要求形式を非同期またはgetクエリーのパラメーターに変換することを可能にしてくれます。(翻訳に自信なし)
最初のローダーには1つの引数が渡されますが、それはリソース・ファイルの中身になります。
コンパイラは最後のローダーの結果を待ち受けます。 その結果は、JavaScriptのモジュールのソースコードとして表される文字列、または(文字列に変換される)バッファにする必要があります。 任意にSourceMapの結果(JSONオブジェクトとして)を渡すことも可能です。
単一の結果は同期(sync)モードで返すことが可能です。
複数の結果は、this.callback
が呼び出されなければいけません。
非同期(async)モードでは、this.async()
が呼び出されなければいけません。
非同期モードが許可されていれば、this.callback
が返されます。
その後ローダーはundefined
を返すか、コールバックを呼びださなければいけません。
エラーは同期モードであればスローするか、
またはerrorによるthis.callback
の呼び出しが可能です。
webpack
は、あらゆるケースで非同期モードを使用することが出来ます。
enhanced-require
は、非同期モードでrequire.ensure
またはAMDrequire
でのみ使用することが出来ます。
より詳しい説明とガイドラインが必要であれば、ローダーの書き方を参照してください。
例
同期(sync)ローダー
module.exports = function(content) {
return someSyncOperation(content);
};
非同期(async)ローダー
module.exports = function(content) {
var callback = this.async();
if(!callback) return someSyncOperation(content);
someAsyncOperation(content, function(err, result) {
if(err) return callback(err);
callback(null, result);
});
};
注意:
同期モードのフォールバックとして、非同期ローダーを与えることが推奨されています。
webpackで必須とされるわけではありませんが、enhanced-require
を使用したローダー同期の実行を可能にしてくれます。
rawローダー
デフォルトでは、リソース・ファイルはutf-8
文字列として扱われ、ローダーに文字列として渡されます。
raw
をtrueに設定することで、そのローダーには生(raw)のBufferが渡されます。
各ローダーは、文字列またはBufferとして、その結果を受け渡しすることが可能になっています。 コンパイラはローダー間でそれらを変換します。
module.exports = function(content) {
assert(content instanceof Buffer);
return someSyncOperation(content);
// 戻り値もBufferとすることが可能。
// これはローダーが"raw"出ない場合にも可能です。
};
module.exports.raw = true;
pitchingローダー
ローダーは右から左へ呼びだされます。
ただし、ローダーが前のローダー、またはリソースの結果を考慮しないケースがあります。
それらはメタデータのみを考慮します。
ローダーのpitch
メソッドは、ローダーが呼び出される前に左から右へ呼びだされます。
ローダーがpitch
メソッドの結果を送る場合、その処理は反転し残りのローダーをスキップし、
左側のローダーの呼び出しを継続します。(翻訳に自信なし)
データはpitch
と通常呼び出しとの間で受け渡されます。
module.exports = function(content) {
return someSyncOperation(content, this.data.value);
};
module.exports.pitch = function(remainingRequest, precedingRequest, data) {
if(someCondition()) {
// fast exit
return "module.exports = require(" + JSON.stringify("-!" + remainingRequest) + ");";
}
data.value = 42;
};
ローダーのコンテキスト
これは、ローダー内のthis
上で使用できるものの事です。
例として、/abc/file.js
内で次のようなrequireがされたとします。
require("./loader1?xyz!loader2!./resource?rrr");
- version
- context
- request
- query
- data
- cacheable
- loaders
- loaderIndex
- resource
- resourcePath
- resourceQuery
- emitWarning()
- emitError()
- exec()
- resolve()
- resolveSync()
- addDependency()
- addContextDependency()
- clearDependencies()
- value
- inputValue
- options
- debug
- minimize
- sourceMap
- target
- webpack
- emitFile()
- _compilation
- _compiler
version
ローダーのAPIのバージョンです。現在は1
です。
context
モジュールのディレクトリを示す文字列です。 別の事を解決するのにコンテキストとして使用することが出来ます。
この例では、resource.js
がこのディレクトリ内にあるため、/abc
となります。
request
解決されたリクエストの文字列です。
この例では、"/abc/loader1.js?xyz!/abc/node_modules/loader2/index.js!/abc/resource.js?rrr"
になります。
query
現在のローダーに対するリクエストのクエリー文字列です。
この例では、loader1では"?xyz"
、loader2では""
になります。
data
pitchと標準フェーズ間で共有されるデータ・オブジェクトです。
cacheable
cacheable(flag = true: boolean)
このローダーの結果をキャッシュ可能にするか否かを決定します。 デフォルトは、キャッシュ不可です。
キャッシュ可能なローダーは、入力と依存するものが変わらなければ、決定的な(deterministic)結果(状態に左右されない一定の結果)を持たなければいけません。
これはローダーが、this.addDependency
によって指定されたもの以外の依存性を持つべきでは無いことを意味します。
ほとんどのローダーは、決定的であり、尚且つキャッシュ可能です。
loaders
loaders = [{request: string, path: string, query: string, module: function}]
全てのローダーの配列です。 pitchフェーズで書き込み可能です。
下記はこの配列の例になります。
[
{ request: "/abc/loader1.js?xyz",
path: "/abc/loader1.js",
query: "?xyz",
module: [Function]
},
{ request: "/abc/node_modules/loader2/index.js",
path: "/abc/node_modules/loader2/index.js",
query: "",
module: [Function]
}
]
loaderIndex
ローダーの配列内においての現在のローダーのインデックス番号です。
この例では、loader1は0
、loader2は1
になります。
resource
クエリーを含むリクエストのリソース部分です。
この例では、"/abc/resource.js?rrr"
になります。
resourcePath
リソースファイルです。
この例では、"/abc/resource.js"
になります。
resourceQuery
リソースのクエリーです。
この例では、"?rrr"
になります。
emitWarning()
emitWarning(message: string)
警告を発します。
emitError()
emitError(message: string)
エラーを発します。
exec()
exec(code: string, filename: string)
モジュールのようなコード断片を実行します。
助言:
require(this.resourcePath)
を使用せずに、この関数を使用してローダーをチェーン可能にしてください。
resolve()
resolve(context: string, request: string, callback: function(err, result: string))
require式のようなリクエストを解決します。
resolveSync()
resolveSync(context: string, request: string) -> string
require式のようなリクエストを解決します。
addDependency()
addDependency(file: string)
dependency(file: string) // shortcut
監視を可能にするために、ローダーの結果の依存性としてファイルを追加します。
addContextDependency()
addContextDependency(directory: string)
ローダーの結果の依存性として、ディレクトリを追加します。
clearDependencies()
clearDependencies()
ローダーの結果の全ての依存性を削除します。 初期の依存性と他のローダーのものでさえも対象になります。 pitchの使用を検討してください。
value
次のローダーに渡す値です。 もし、exportされる結果が分かり、モジュールとして実行される場合、ここにこの結果を設定します。(唯一の要素の配列として)
inputValue
最後のローダーから渡された値です。 モジュールとして入力された引数を実行する場合、この値の読み取りを検討してください。(パフォーマンスを考慮して)
options
コンパイラに渡されるオプションです。
debug
真偽値のフラグです。 デバッグモードにする際に設定されます。
minimize
結果を圧縮(minimized)します。
sourceMap
SourceMapを生成します。
target
コンパイルの対象を示します。
設定オプションから渡されます。
値の例として、"web"
、"node"
などがあります。
webpack
webpackによってコンパイルされている場合に、trueが設定されます。
emitFile()
emitFile(name: string, content: Buffer|String, sourceMap: {...})
Emit a file. This is webpack-specific
_compilation
Hacky access to the Compilation object of webpack.
_compiler
Hacky access to the Compiler object of webpack.
© 2010 - 2017 STUDIO KINGDOM