webpackのconfiguration

記事作成日15/04/12
記事更新日15/05/20

※ 編集途中
※ 訳に自信ないので原文見ること configration

知っておくと良いこと

node.jsのメソッドやグローバルオブジェクトに関しては Node.js v0.10.26 マニュアル & ドキュメンテーション

// CLI
// webpack.config.jsを用意するかコマンドに--configオプションを付け設定ファイルを指定する
module.exports = {
// configuration
};
// ----------------------------------------
// node.js API
webpack({
// configuration
}, callback);

context

entryオプションを解決するためのベースとなるディレクトリ (絶対パス)。Output.pathinfo が設定されている場合このディレクトリに含まれてpathinfoが短縮される。
デフォルトはprocess.cwd()
補足:process.cwd()はnode.jsのメソッド。プロセスのカレントワーキングディレクトリを返す

// ワーキングディレクトリのmyscript.jsをコンパイルして同階層にbundle.jsを作成する
module.exports = {
context : process.cwd(), // 絶対パスで指定
entry : "./myscript.js",
output : {
filename : "bundle.js"
}
}

entry

エントリーポイントの設定。文字列、配列、オブジェクトが渡せる

文字列

文字列が起動時に読み込まれているモジュールを解決

// child.js
module.exports = function(){
document.write("child");
}

// myscript.js
require('./child.js')();

myscript.jsがchild.jsに依存している上記のような状態で

module.exports = {
entry : "./myscript", // jsであれば拡張子を省略できる
output : {
filename : "bundle.js"
}
}
// とすると、myscriptの依存性を解決しbundle.jsを出力する

配列

配列を渡すことでエントリーポイントを複数にすることも出来る。

module.export = {
entry : [
"./myscript2", // jsであれば拡張子を省略できる
"./myscript"
output : {
filename : "bundle.js"
}
}

オブジェクト

オブジェクトを渡すとエントリの複数のバンドルが生成される。
ページごとに違うjsを読み込ませたいときなどに利用出来る。値は文字列か配列を指定出来る。

module.exports = {
entry : {
toppage : "./toppage",
items : ["./subpage-common","./items"]
},
output : {
path : "dist", // 複数ファイルが生成されるので、とりあえずdist以下に出力
filename : "[name].bundle.js" // dist以下にtoppage.bundle.jsとitems.bundle.jsが出来る
}
}

output

ファイル出力の設定。プロパティによって[id]や[name]など何かしらの文字列に置換されるキーワードが利用出来る。
以下、例

module.exports = {
entry : {
toppage : "./toppage",
items : ["./subpage-common","./items"]
},
output : {
path : "dist",
filename : "[name].bundle.js",
chunkFilename : "[id].[name].bundle.js",
sourceMapFilename : "[file].map"
}
}

output.path

出力ディレクトリを絶対パスで指定 (必須)

output.filename

エントリチャンクのファイル名。output.pathからの相対パス。output.path絶対パスで指定しておく必要がある。

[name]チャンクの名前に置き換えられる(チャンクの名前はentryのキー)
[hash]コンパイル時?のハッシュに置き換えられる
原文:[hash] is replaced by the hash of the compilation.
[chunkhash]チャンクのハッシュに置き換えられる

output.chunkFilename

エントリされていないチャンクのファイル名。

output.sourceMapFilename

ソースマップのファイル名を指定。devtoolを#source-map等にする必要がある

[file]JSのファイル名に置き換えられる
[id]チャンクのidに置き換えられる
[hash]コンパイル時のハッシュに置き換えられる

output.devtoolModuleFilenameTemplate

ソースマップのsources配列のテンプレート設定
※ ソースマップの仕組みがわからないので検証は後日

[resource]ファイルを解決するためにwebpackに利用されるパスに置換される。もしあれば右端のローダーにクエリパラメータが追加される。( ナニヲイッテルンダー?
原文:[resource] is replaced by the path used by Webpack to resolve the file, including the query params to the rightmost loader (if any).
[resource-path][resource-path]は[resource]と同じですが、ローダークエリパラメータ?は無し
[loaders] 
[all-loaders] 
[id]モジュールのidに置き換えられる
[hash] 
[absolute-resource-path] 
Default (devtool=[inline-]source-map): "webpack:///[resource-path]"
Default (devtool=eval): "webpack:///[resource-path]?[loaders]"
Default (devtool=eval-source-map): "webpack:///[resource-path]?[hash]"

output.devtoolFallbackModuleFilenameTemplate

 output.devtoolModuleFilenameTemplateに似ているがモジュール識別子?が重複している場合に利用する

Default: "webpack:///[resourcePath]?[hash]"

output.devtoolLineToLine

すべて/指定されたモジュールの line to line マップモードを有効にする。
line to line マップモードは生成されたソースのそれぞれの行をオリジナルソースと同じ行にマッピングするというシンプルなソースマップを利用し、これはパフォーマンスの最適化にもなる。入力した行と生成した行が一致しており、パフォーマンスをより良くしたい場合に限り利用する。

trueで全ての line to line マップモードを有効にしますが、推薦されてません。
オブジェクトだと{test:true}みたいな感じ?
原文:An object {test, include, exclude} similar to module.loaders enables it for specific files. 

Default: disabled

output.hotUpdateChunkFilename

livereload辺りと関係がありそうなので後回し

output.hotUpdateMainFilename

livereload辺りと関係がありそうなので後回し

output.publicPath

公開用パス(devサーバーとかにも)

// webpack-dev-serverでdevサーバーを利用する場合

// ----------------------------------
// package.json
// ----------------------------------
{
...
"scripts" : {
"dev" : "webpack-dev-server"
}
...
}

// ----------------------------------
// webpack.config.js
// ----------------------------------
module.exports = {
...
output : {
filename : '[name].bundle.js',
publicPath : '/dist/'
},
devServer : {
host : 'localhost',
port : '8090'
}
...
}

として、ワーキングディレクトリで

$ npm run dev

とすると
http://localhsot:8090/dist/[name].bundle.js
にアクセス出来る

output.jsonpFunction

 

output.hotUpdateFunction

 

output.pathinfo

 

output.library

 

module

通常のモジュールに影響を与えるオプション (NormalModuleFactory)

module.loaders

自動的に適用されるloaderの配列
各項目はそれぞれ以下のプロパティを持つことが出来ます。

  • test:ファイルが?条件を満たす必要があります
  • exclude:パスが?条件を満たしてはいけません(除外ファイルの設定)
  • include:パスが?条件を満たす必要があります
  • loader:”!”区切りのloaderの文字列
  • loders:loader文字列の配列

A condition may be a RegExp, a string containing the absolute path, or an array of one of these combined with “and”.

値は絶対パスを含む文字列か正規表現です。それらを含む配列も使えます。
an array of one of these combined with “and”.の意味がわからない。

詳しくはloaders

!!重要!!
The loaders here are resolved relative to the resource which they are applied to. The means they are not resolved relative the the configuration file.

このloaderはソースへの相対的なパスで解決されますが、設定ファイルへのパスは相対パスではありません。っていう意味・・・かな? ※ 読めない
– – – – – – – – –
もしnpmでインストールされたloaderを持っており、node_modulesディレクトリが全てのソースファイルの親ディレクトリの中になければ、webpackはloaderを見つけることが出来ません。
その場合、設定ファイル等のresolveLoader.rootオプションに絶対パスでnode_modulesディレクトリをパスを追記しなければなりません。

resolveLoader: { root: path.join(__dirname, "node_modules") }

module.preLoaders, module.postLoaders

module.loadersのような構文
配列を受けれ入れます。

module.noParse

正規表現か正規表現の配列。マッチしたファイルをパースしません。
大きなライブラリを無視するとパフォーマンスが上げることが出来ます。
ファイルにはrequireやdefine、もしくはそのようなものが無いことを期待します。
それらはexportsとmodule.exportsを使用することを受け入れます。

automatically created contexts defaults module.xxxContextXxx
自動生成されたコンテキストの初期値

これは自動生成されたコンテキストに対して初期値を設定するためのオプションです。
自動生成されたコンテキストは3種類に定義されます。

  • exprContext:依存関係としての式 ( すなわち require(expr)
  • wrappedContext:式に加えて接頭接尾の文字列 ( すなわち require(“./template/” + expr)
  • unknownContext:その他requireでパース不可能なもの ( すなわち require

4つのオプションが自動生成されたコンテキストに対して可能です。

  • request:コンテキストのリクエスト
  • recursive:サブディレクトリも走査
  • regExp:式に対する正規表現
  • critical:この依存性のタイプはクリティカルとして考慮する (警告を出します)

全てのオプションと初期値

unknownContextRequest = “.”,
unknownContextRecursive = true,
unknownContextRegExp = /^\.\/.*$/, unknownContextCritical = true

exprContextRequest = “.”,
exprContextRegExp = /^\.\/.*$/,
exprContextRecursive = true,
exprContextCritical = true

wrappedContextRegExp = /.*/,
wrappedContextRecursive = true,
wrappedContextCritical = false

!メモ!
module.wrappedContextRegExpは正規表現全体の中間部分の参照だけします。
※ 中間部分って部分一致のことかも
残りは接頭辞と接尾から生成されます。

{
module: {
// Disable handling of unknown requires
unknownContextRegExp: /$^/,
unknownContextCritical: false,
// Disable handling of requires with a single expression
exprContextRegExp: /$^/,
exprContextCritical: false,
// Warn for every expression in require
wrappedContextCritical: true
}
}

resolve

モジュールの解決に影響するオプション

resolve.alias

他のモジュールかパスによってモジュールを置き換えます。

期待される値はキーがモジュール名でプロパティが新しいパスになっているオブジェクトです。
これは置換に似ていますが、置換よりもすこし賢いものです。
もし、キー名が$で終わっていて、評価対象の文字列と$を抜いたキー名が完全一致だった場合、置き換えられます。
※ xyz$ == xyz -> true | xyz$ == xyz/file.js -> false

もし、値が相対パスであれば、requireを含むファイルに対して相対的になるでしょう?
※ 例を見たほうが良い

例:/abc/entry.jsからrequireを呼び出したときの、aliasの設定の違いによる挙動の変化

alias:require(“xyz”)require(“xyz/file.js”)
{}/abc/node_modules/xyz/index.js/abc/node_modules/xyz/file.js
{ xyz: “/absolute/path/to/file.js” }/absolute/path/to/file.jserror
{ xyz$: “/absolute/path/to/file.js” }/absolute/path/to/file.js/abc/node_modules/xyz/file.js
{ xyz: “./dir/file.js” }/abc/dir/file.jserror
{ xyz$: “./dir/file.js” }/abc/dir/file.js/abc/node_modules/xyz/file.js
{ xyz: “/some/dir” }/some/dir/index.js/some/dir/file.js
{ xyz$: “/some/dir” }/some/dir/index.js/abc/node_modules/xyz/file.js
{ xyz: “./dir” }/abc/dir/index.js/abc/dir/file.js
{ xyz: “modu” }/abc/node_modules/modu/index.js/abc/node_modules/modu/file.js
{ xyz$: “modu” }/abc/node_modules/modu/index.js/abc/node_modules/xyz/file.js
{ xyz: “modu/some/file.js” }/abc/node_modules/modu/some/file.jserror
{ xyz: “modu/dir” }/abc/node_modules/modu/dir/index.js/abc/node_modules/dir/file.js
{ xyz: “xyz/dir” }/abc/node_modules/xyz/dir/index.js/abc/node_modules/xyz/dir/file.js
{ xyz$: “xyz/dir” }/abc/node_modules/xyz/dir/index.js/abc/node_modules/xyz/file.js

index.jsはpackage.jsonに定義していれば、他のファイルを解決するでしょう。
/abc/node_modules/も/node_moduleを解決するでしょう。

resolve.root

モジュールを含むディレクトリ(絶対パス)かディレクトリの配列。
この設定は検索対象となるディレクトリへのパスを追加する必要があります。

必ず絶対パスで指定してください。./app/modulesみたいなパスはダメです。

resolve.modulesDirectories

現在のディレクトリとその先祖を解決したり、モジュールを検索したりするためのディレクトリ名の配列。
※ モジュール群を含む親のディレクトリ名を指定しろってことかと
この機能はnode.jsがnode_modulesを検索する機能に似ています。例えば、値が[“mydir”]であれば
webpackは”./mydir”、”../mydir”、”../../mydir” etc. を見に行きます。 

デフォルト:[“web_modules”,”node_moduels”] 

!メモ!
ここには絶対パスや”../someDir”、”app”、”.”等は必要有りません。必要なのはディレクトリ名だけで、ここで指定したディレクトリ以下に階層構造を持たせたい場合にのみ使用します。そうでなければresolve.rootオプションを使ってください。

resolve.fallback

resolve.rootやresolve.modulesDirectoriesで見つけることが出来ないモジュールをwebpackが参照できるようにするためのディレクトリかディレクトリの配列(絶対パス)

resolve.extensions

モジュールを解決するために利用する必要がある拡張子の配列。
例えば、CoffeeScriptファイルを利用しているのであれば、配列に文字列”.coffee”を入れて下さい。

デフォルト:[“”,”.webpack.js”,”web.js”,”.js”]

!重要!
この設定はデフォルト内容を上書きします。
これはwebpackがデフォルトの設定を基にモジュールを解決しなくなることを意味しています。
例えばrequire(‘./somefile.ext’)のように拡張子付きでrequireしたければ、空の文字列を配列に追加する必要があります。
逆に、require(‘underscore’)のように拡張子無しでrequireしたければ”.js”を配列に追加します。

resolve.packageMains

各パッケージのpackage.jsonに記載されているエントリポイントのフィールドを変更する
※ 優先順位は配列の先頭から
デフォルト:[“webpack”, “browser”, “web”, “browserify”, [“jam”, “main”], “main”]

// あるパッケージのpackage.jsonのエントリポイントのフィールドが"main"ではなく下記のようになっていた場合、
// package.json
{
...
"test-main" : "test-run.js"
...
}
// 設定ファイルに以下のように設定する
// webpack.config.js
{
resolve : {
packageMains : ["test-main","main"]
}
}

resolve.packageAlias

Check this field in the package.json for an object.
this specによるとキーと値のペアはエイリアスとして通ります。
例:”browser”はbrowerフィールドをチェックします。
デフォルト値はありません。

resolve.unsafeCache

ファイルの一部を解決するのに安全ではないキャッシュを積極的に行います。
キャッシュされたパスを変更すると稀に故障することがあります。
正規表現の配列か正規表現もしくはtrue(全てのファイルという意味)を期待します。
解決されるパスがマッチすれば、変更されます。

デフォルト:[]

resolveLoader

resolveに似ていますが、loader向けです。

デフォルト

{
modulesDirectories: ["web_loaders", "web_modules", "node_loaders", "node_modules"],
extensions: ["", ".webpack-loader.js", ".web-loader.js", ".loader.js", ".js"],
packageMains: ["webpackLoader", "webLoader", "loader", "main"]
}

resolveLoader.moduleTemplates

resolveLoader専用のプションです。

It describes alternatives for the module name that are tried.

解決を試みるモジュールの名前のための代替手段のための説明です?

デフォルト:[“*-webpack-loader”, “*-web-loader”, “*-loader”, “*”]

externals

webpackによって解決されるべきではない依存関係を指定しますが、生成されたバンドルの依存関係になります。
依存性の種類はoutput.libraryTargetに依存します。
値としてのオブジェクト、文字列、関数、正規表現と配列が利用できます。

string正確に一致した依存性が外部化します。
同じ文字列が外部の依存性として利用されます。
objectもし依存性がオブジェクトのプロパティに正確に一致した場合、プロパティの値が依存性として利用されます。
プロパティの値には依存性のタイプのプレフィックスをスペース区切りで含めることができます。
もしプロパティの値がtrueであれば、値の代わりにプロパティの名前(キー)が使われます。
プロパティの値がfalseであれば、外部化は中止され依存性は外部化しません。
functionfunction(context, request, callback(err, result))
関数はそれぞれの依存性に呼ばれます。もし結果がコールバック関数に渡されれば、この値はオブジェクトのプロパティのように処理されます。(above bullet point (key:valってことか?))
RegExp一致する全ての依存性が外部化します。リクエストも外部の依存性のリクエストとして使用されます。
array複数指定する場合に利用(再帰的)

 例

{
output: { libraryTarget: "commonjs" },
externals: [
{
a: false, // a is not external
b: true, // b is external (require("b"))
"./c": "c", // "./c" is external (require("c"))
"./d": "var d" // "./d" is external (d)
},
// Every non-relative module is external
// abc -> require("abc")
/^[a-z\-0-9]+$/,
function(context, request, callback) {
// Every module prefixed with "global-" becomes external
// "global-abc" -> abc
if(/^global-/.test(request))
return callback(null, "var " + request.substr(7));
callback();
},
"./e" // "./e" is external (require("./e"))
]
}
タイプ読み込まれたコードの結果
“var”“abc”module.exports = abc;
“var”“abc.def”module.exports = abc.def;
“this”“abc”(function() { module.exports = this[“abc”]; } ());
“this”[“abc”,”def”](function() { module.exports = this[“abc”][“def”]; }());
“commonjs”“abc”module.exports = require(“abc”);
“commonjs”[“abc”,”def”]module.exports = require(“abc”).def;
“amd”“abc”define([“abc”], function(X) { module.exports = X; })
“amd”“abc”everything above

amd/umd ターゲットとしてコンパイルしていなければ”amd”と”umd”は壊れます。

If using umd you can specify an object as external value with property commonjs, commonjs2, amd and root to set different values for each import kind.

メモ:
Umd を使用する場合は、プロパティ commonjs、commonjs2、amd とインポートの種類ごとに異なる値を設定するルートを持つ外部値としてオブジェクトを指定できます。

target

  • “web” ブラウザのような環境で使用するためのコンパイル(デフォルト)
  • “webworker” WebWorker向けのコンパイル
  • “node” node.jsのような環境で使用するためのコンパイル(チャンクをロードするためにrequireを使う)
  • “async-node”  node.jsのような環境で使用するためのコンパイル(非同期チャンクをロードするためにfsとvmを使う)
  • “node-webkit” webkitで使用するためのコンパイル。読み込まれたjsonpチャンクを利用するがnode.jsにビルドインモジュールとrequire(“nw.gui”)もサポートする(実験的)
  • “atom” atom-shellで使用するためのコンパイル。Atomを走らすために必要なモジュールのrequireをサポート

bail

最初のエラーを容認するのではなくハードエラーとしてレポートする
※ エラーあったら処理を止めるよ。ってことかと

profile

各モジュールのタイミング情報をキャプチャします。
※timing informationってなんぞ

ヒント:視覚化するためには分析ツール(analyze tool)を利用します。
–jsonまたはstats.toJson()はJSONとして統計データを与えます。

cache

複数の増えたビルドのパフォーマンスを向上させるためにモジュールとチャンクのキャッシュを生成します。
watch modeでデフォルトで利用しており、falseを指定することで不使用にします。

You can pass an object to enable it and let webpack use the passed object as cache. This way you can share the cache object between multiple compiler calls. Note: Don’t share the cache between calls with different options.

watch

監視モード。ファイルが変更されたら再構築を行う。
公式にはOnly use it with the Node.js JavaScript api webpack(options, fn).と書いてあるが、設定ファイルに{watch:true}と書くと動く・・・

watchDelay

最初の変更から再構築までの遅延時間。値はミリ秒

Default: 200

debug

未確認

devtool

開発ツールを選択。ソースマップの出力など

devtoop : '#source-map'

という具合に@か#か#@のプレフィックスが付いた文字列で指定する。デフォルトは#で推薦も# ( プラグマみたいな感じ

#evalevalソースに#sourceURLを付ける
参照:eval ソースをデバッグする
#source-mapソースマップを生成。output.sourceMapFilenameも参照
#hidden-source-map参照コメント無し版ソースマップ
#inline-source-mapJSファイルにdataURLとして記載
#eval-source-mapDataUrlスキームを利用しevalソースに埋め込む
#cheap-source-map列のマッピングを含まないソースマップを生成する
#cheap-module-source-map 列のマッピングを含まないソースマップ。
1 行につき 1 つのマッピング ローダーから SourceMaps として単純化される。
devtoolbuild speedrebuild speedproduction supportedquality
eval++++++nogenerated code
cheap-eval-source-map+++notransformed code (lines only)
cheap-source-map+oyestransformed code (lines only)
cheap-module-eval-source-mapo++nooriginal source (lines only)
cheap-module-source-mapoyesoriginal source (lines only)
eval-source-map+nooriginal source
source-mapyesoriginal source

引用(15/04/15):CONFIGURATION

devServer

webpack-dev-serverの設定を行う
webpack-dev-serverのドキュメントはここ

contentBaseコンテンツのベースパス
quietコンソールに出力しない
colors出力に色を付ける
noInfo退屈な情報(ファイル生成等重要ではない出力?)を出力しない
hostホスト名かIP
portポート(数値で指定)
inlinewebpack-dev-serverをランタイムのバンドルに埋め込む?
hotHotModuleReplacementPluginを追加し(自動)
サーバーをホットモード(ファイルを変更したらすぐブラウザに反映される)状態にする
※ HotModuleReplacementPluginを手動で読み込ませる必要はない
※ hot modeを利用するときはscriptタグ等でwebpack-dev-server.jsを読み込ませる
httpshttpsプロトコルを利用する
// 例
// ----------------------------------
$ npm i webpack-dev-server --S

// ----------------------------------
// package.json
// ----------------------------------
{
...
"scripts" : {
"dev" : "webpack-dev-server"
}
...
}
// ----------------------------------
// webpack.config.js
// ----------------------------------
module.exports = {
...
output : {
filename : '[name].bundle.js',
publicPath : '/dist/'
},
devServer : {
host : 'localhost',
port : '8090',
hot : true
}
...
}
// ----------------------------------
$ npm run dev

node

node.jsのポリフィルやモックなど

  • console:boolean
  • global:boolean
  • process:true、”mock”かfalse
  • Buffer:boolean
  • __filename:true(実際のファイル名)、”mock”(“/index.js”)かfalse
  • __dirname:true(実際のディレクトリ名)、”mock”(“/”)かfalse
  • <node buildin>:true、”mock”、”empty”かfalse

デフォルト値

{
console : false,
process : true,
global : true,
Buffer : true,
__filename : "mock",
__dirname : "mock"
}

amd

require.amd、define.amdの値を設定する ( 未確認

loader

loaderコンテキストで使用できるカスタム値

recordsPath, recordsInputPath, recordsOutputPath

末確認

plugins

プラグインを追加する。
※ プラグインには最初から提供されているものと外部からダウンロードする必要があるものがある。
※ プラグインリスト:LIST OF PLUGINS

// 例
var webpack = require('webpack');
module.exports = {
...
plugin : [
new webpack.HotModuleReplacementPlugin()
]
...
}