(2017/08/28追記)
この記事は webpack v1 系での config について書かれています。
v2 系以降は一部の項目名などに変更があります。
Migrating from v1 to v2
を読んで v2 系への移行を行うか、または私のリポジトリを参考にしてください。
https://github.com/zaki-yama/react-redux-template
https://github.com/zaki-yama/redux-express-template
(追記ここまで)
はじめに
webpack を使った JS/CSS のビルドを行う場合、webpack.config.js
という設定ファイルを用意してコマンド自体は webpack
で済ませることがほとんどだと思いますが
公式チュートリアルでも webpack.config.js
については少ししか触れられていなかったので、よく使う項目についてメモしておきます。
(項目の一覧は https://webpack.github.io/docs/configuration.html に記載されています)
また、ちょうどこの記事を書こうと思ったときに、英語ですが非常にわかりやすい記事が投稿されてました。
今回は取り上げなかった webpack-dev-server の設定についても言及されているし、とにかく説明が丁寧でわかりやすいです。オススメ。
(2016/05/07追記)
webpack-dev-server についても書きました。
(追記ここまで)
目次
webpack.config.js の例
React と ES2015 を使ったアプリ開発なんかでよく見る webpack.config.js
は、たとえばこのような形です。
module.exports = { entry: __dirname + "/index.js", output: { path: __dirname + '/dist', filename: 'bundle.js' }, module: { loaders: [ { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader', query:{ presets: ['react', 'es2015'] } } ] }, devtool: 'source-map', resolve: { extensions: ['', '.js', '.jsx'] } };
各項目について、順番に見ていきます。
entry
ビルドの起点となるファイルのパスを指定します。
起点とは、要するにここからさまざまなファイルを require しているファイルのことです。
entry
は文字列で単一のファイルを指定することも、Array または Object で複数のファイルを指定することもできます。
複数指定する場合、Object だと出力ファイルも複数になります(output
の項で触れます)が、Array だと出力されるファイルは1つです。
ので、どういった目的で使うのかあんまりわかってません。
output
output.path
に出力先のパスを、output.filename
に出力ファイル名を指定するのが一般的です。
なお、entry
に Object を渡して複数のエントリーポイントを指定した場合、出力も複数のファイルになりますが
その場合には output.path
に [id]
や [name]
などの特殊な変数を使用します。
module.exports = { entry: { module1: './entry.js', module2: './entry2.js' }, output: { path: __dirname + '/dist', filename: '[name].bundle.js' // entry の key (module1, module2) が渡される } };
結果
$ ls dist module1.bundle.js module2.bundle.js
module.loaders
メインとなる部分です。
対象のファイルを変換するための loader を指定します。
modules.loaders
は Array になっており、Array の要素は以下の項目を持った Object です。
test
include
、exclude
loader
またはloaders
query
test
ビルド対象(Loader を適用するファイル)を指定します。正規表現が使えます。
include, exclude
ビルド対象に含める/除外するファイルを指定します。正規表現が使えます。
loader または loaders
適用する loader の名前を指定します。xxx-loader
の -loader
部分は省略可能です。
loader
を使った場合、複数の loader の指定は!
区切りで記述します
module: { loaders: [ { test: /\.css$/, loader: 'style!css' } ] }
loaders
を使った場合、配列で loader を指定します
module: { loaders: [ { test: /\.css$/, loaders: ['style', 'css'] } ] }
いずれの方法でも複数の loader が指定可能ですが、右から左に適用されることに注意しましょう。
また、loader は webpack とは別に npm でインストールする必要があります。
たとえば、例として紹介している babel-loader については、ドキュメントにもあるように
$ npm install babel-loader babel-core babel-preset-es2015 babel-preset-react --save-dev
とする必要があります。(この場合に関しては、presets
も個別インストールが必要のようですね)
query
loader に渡したいクエリパラメータを指定します。
まとめると
冒頭の
loaders: [ { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader', query:{ presets: ['react', 'es2015'] } } ]
は、node_modules
ディレクトリ配下を除き、拡張子が .js
のファイルすべてに対し、babel-loader という loader を適用します。
また、適用する際、loader に react
と es2015
という preset を指定します。
devtool
デバッグのための SourceMap の出力を設定することができます。
SourceMap とはビルド前後の JS ファイルの対応関係情報を持ったファイルで、これを出力するとブラウザの開発者ツールなどでビルド前のコードを参照することができます。
参考:
・SourceMap について調べてみました。 | イントフロート スタッフブログ
・Introduction to JavaScript Source Maps - HTML5 Rocks
webpack では、devtool
に指定する値によって出力される SourceMap の形式およびビルド速度に差があるようです。一覧表をドキュメントから引用します。
devtool | build speed | rebuild speed | production supported | quality |
---|---|---|---|---|
eval | +++ | +++ | no | generated code |
cheap-eval-source-map | + | ++ | no | transformed code (lines only) |
cheap-source-map | + | o | yes | transformed code (lines only) |
cheap-module-eval-source-map | o | ++ | no | original source (lines only) |
cheap-module-source-map | o | - | yes | original source (lines only) |
eval-source-map | – | + | no | original source |
source-map | – | – | yes | original source |
それぞれの細かな違いについてきちんと理解できてませんが、開発時は inline-source-map
や source-map
、本番ビルド時には eval
を指定しているものが多い気がします。
eval
だと元のコードを確認できるのかどうか、よくわからず。。。
resolve
こちらもいくつかパラメータがあるようなのですが、よく見るのは extensions
です。
ビルド対象に含めたい(require
している)ファイルの拡張子を Array で指定します。
デフォルトは
["", ".webpack.js", ".web.js", ".js"]
です。
たとえば React ファイルの拡張子を .jsx
で作っていた場合、こちらに記述する必要があります。
※ただし、指定すると デフォルト値を上書き(デフォルト値に追加ではなく)してしまうので注意
foo.js
を require('foo')
というように拡張子なしで読み込みたい場合は '.js'
を指定する必要があり、
逆にデフォルト値以外の拡張子のファイルを require('myfile.ext')
というように拡張子つきで読み込みたい場合、''
(空文字列)を指定する必要があるとのこと。
おわりに
webpack.config.js
でよく出てくる項目にいて整理しました。
これでたいていのアプリの設定ファイルは読めるんじゃないでしょうか。
今回紹介したもの以外だと webpack-dev-server がらみで plugins
とか devtool
とかありますが、それはまた別の記事で整理したいと思います。
(2017/03/07追記)
本番環境用のビルドについて書きました。
(追記ここまで)