webpackは何をするものなのか
今までJSフレームワークを扱うときは特に深く考えずにwebpackを見よう見まねで使っていたが、業務で開発プロセスの改善について考えることになり、webpackの役割についてちゃんと理解しなければいけないことになった。
webpackの細かい機能は都度覚えていくしかないが、「何をするものなのか」はいろいろ調べて理解が深まったのでまとめておく。
webpackとはなにか
静的なasset(CSS, JS, 画像, フォントなど)をビルドしてバンドルするためのもの。バンドルとは平たく言うとひとつにまとめること。
静的なassetというのは、リクエストによって内容が変わったりしないファイルのこと。HTMLは、JSからDOMを操作されて内容が書き換えられたうえで返されることもあるが、CSSやJSの内容が書き換えられることはない。
webpack公式のトップページにあるこの図が全てを表している。
大規模な開発をするときは、require()
などを使って、モジュールごとにファイルを分離して書くとわかりやすい。
しかし、ブラウザ上で動くJSはモジュール分割に対応しておらず、このままでは動かない。
そこで、webpack等のビルドツールを使うことで、モジュール同士の依存関係をふまえたうえでファイルをまとめてくれる。ファイルサイズが小さくなるようにminifyもしてくれる。
HTMLWebpackPluginを使うと、バンドルしたJSを読み込むHTMLも生成される。テンプレートがあればそれをもとにすることも可能。
あとはビルドで吐き出されたファイルとHTMLをサーバにアップロードすれば、開発中に想定していたとおりの動きをする。
また、webpackではJS以外の静的assetも管理できる。そのため、JSだけでなくCSSや画像などを読み込むときもrequire()
を使って簡単に書くことができる。
例えば画像なら<img src={ require('../../assets/logo.png') } />
などのように書ける。
静的assetを管理できると何がよいか?
まず、静的assetの過不足がなくなる。ビルドに使われるのは、コード内でrequire()
されているもののみであるため、使わないassetが排除される。
逆に、JSは変えたがCSSが古いままだった・画像がリンク切れだったというようなことも起こらない。もしそのようなものがあれば、ビルドが通らないので本番公開前に気づくことができる。
また、静的assetをどう読み込むかもコントロールできるようになる。例えばbase64エンコードをかけて読み込んだり、サイズが大きければビルドに含めずwebpack外のURLから読み込む形にするなどの設定もでき、静的assetを柔軟に扱いやすくなる。
開発用サーバも立てられる
フロントエンド開発でネックになるのは、ビルドしないとブラウザ上で動かないこと。
動作確認をするのに、毎回npm run build
してサーバにアップロードしなければいけないのでは面倒すぎる。
そこでwebpackでは、ローカルに簡単なサーバを立てる機能も提供されている。よく使われているのはwebpack-dev-server。
ローカルでの開発のための、小さなexpress製アプリである。localhost:8080/assets/bundle.jsのように指定すれば、すぐにそのファイルを擬似的にデプロイして確認できる。
watch
の設定をすれば、ローカルサーバが立っている状態でファイルを更新すると、自動でコンパイルし直して画面に反映してくれる。
また、webpack-dev-serverサーバサイドとAPIで通信させたいときは、proxy
の設定でリクエストを送るURLとサーバサイドのURLを対応させることができる。
webpackは今後も必要か?
ECMA2015では標準仕様としてモジュールが使えるようになったため、今後はブラウザ上でもモジュール分割を使えるようになっていき、webpackなどを使わなくてもよくなる場面が増えるかもしれない。
とはいえ、TypeScriptを使って開発する場合など、webpackがあった方が開発な楽なケースはまだまだあるだろう。
この辺りの話は以下のページがわかりやすい。