webpackではウェブコンテンツを制作に役立つさまざまな機能があります。例えば、webpackで出力したJavaScriptファイルは大きなファイル容量となるので、圧縮しておきたいと考える人も多いでしょう。そういった要望に応える機能が備わっています。

webpackでコードの圧縮とソースマップを有効にする

JavaScriptの開発では、元のソースファイルとの関連性を示すソースマップが欠かせません。また、ウェブサイトへの公開時にはウェブページの読み込みを早くするために、ファイル容量を圧縮することも重要でしょう。webpackでは設定ファイルの記述によって、それらをカスタマイズできます。

webpackの設定ファイル

webpackの設定ファイルには次のように記述します。modedevelopmentを記述することでソースマップを有効にします。逆に、modeの部分でproductionを指定することで、JavaSciptのコードを圧縮できます。開発時にはdevelopmentを指定し、ウェブサイト公開時にはproductionに設定するのがいいでしょう。

▼webpack.config.jsファイル

module.exports = {
  // モード値を production に設定すると最適化された状態で、
  // development に設定するとソースマップ有効でJSファイルが出力される
  mode: 'development',
};

以上で設定は完了です。webpack.config.jsファイルにdevelopmentを指定を指定した場合は、npm run buildコマンドを入力すると、srcフォルダに配置したJSファイルがコンパイルされ、distフォルダにmain.jsファイルが出力されます。

webpack.config.jsファイルにproductionを指定を指定した場合は、dist/main.jsファイルの中身は無駄なコメントが省略され、ファイル容量が最小化されていることが確認できるでしょう。

ここの手順をサンプルファイルとしてGitHubで公開していますので、参考ください。

webpackでローカルサーバーを起動し、変更時にブラウザをリロードする

毎回ビルドコマンドをコマンドラインで打ち込むのは効率的ではありません。ファイルの変更を検知し(watchともいいます)、自動的にビルドコマンドを実行し、ブラウザをリロードする・・・といった手順を自動化できます。類似の技術として「lite-server」や「BrowserSync」といったものがありますが、それに近いものだと考えていいでしょう。

▲webpack-dev-serverの実行例。JavaScriptを編集すると、即座にブラウザが結果を反映する。ローカルのウェブサーバーとしても利用できる。

「webpack-dev-server」はとても便利な機能です。わずかな設定でできるので構築してみましょう。

ビルド時間の短縮に効果的でもある

webpackは初回ビルドと二度目以降のビルドでは、かかる時間が変わります。二度目以降のビルドは、差分ビルドとして時間が大幅に短縮されます。そのため毎回、webpackのビルドコマンドを使うのは、ビルド時間が余計にかかり時間の無駄です。ビルド短縮のため、webpack-dev-serverもしくは後述のwatch機能は必ず利用しましょう

npmモジュールのインストール

webpack関連モジュールとwebpack-dev-serverモジュールをインストールしましょう。

npm i -D webpack webpack-cli webpack-dev-server

これをインストールすると、package.jsonファイルは次の内容になります。scriptsは自前のビルドコマンドとして"start": "webpack-dev-server"を記述しておくのがポイントです。

▼package.jsonファイル

{
  "scripts": {
    "build": "webpack",
    "start": "webpack-dev-server"
  },
  "devDependencies": {
    "webpack": "^4.5.0",
    "webpack-cli": "^2.0.14",
    "webpack-dev-server": "^3.1.1"
  }
}

webpackの設定ファイル

webpackの設定ファイルには次のように記述します。devServerにルートフォルダーを設定します。open: trueを指定しておくと、自動的にブラウザが立ち上がります。

▼webpack.config.jsファイル

module.exports = {
  // モード値を production に設定すると最適化された状態で、
  // development に設定するとソースマップ有効でJSファイルが出力される
  mode: 'development',

  // ローカル開発用環境を立ち上げる
  // 実行時にブラウザが自動的に localhost を開く
  devServer: {
    contentBase: 'dist',
    open: true
  }
};

以上で設定は完了です。npm run startコマンドを入力しましょう。もしくは、npx webpack-dev-serverコマンドでも起動できます。自動的にブラウザが起動しローカルホストが表示されます。ファイル保存時にブラウザが自動的にリロードするので、コーディングと確認の作業が楽になるでしょう

ここの手順をサンプルファイルとしてGitHubで公開していますので、参考ください。

なお、webpack-dev-serverに似た、webpack-serveというツールがありますが、webpack-serveは非推奨です(リポジトリにもDEPRECATEDと記載されてます)。そのため、webpack-serveは使わずにwebpack-dev-serverを使うべきでしょう。一応、webpack-serveの使い方を知りたい方のために、サンプルを用意しているので興味ある方は参照ください。

ファイル変更時に差分ビルドを。ウォッチを利用する

webpack-dev-serverはとても便利ですが、ブラウザで確認する必要がないときは機能が多すぎて余分に思うかもしれません。JavaScriptをビルドしたいだけであれば、watch機能を利用するがいいでしょう。watch機能を利用するにはコマンドラインの引数に「–watch」を追加するだけです。

npx webpack --watch

もしくは、package.jsonファイルのscriptsは自前のビルドコマンドとして"start": "webpack --watch"を記述しておくのもいいでしょう。この場合は実行コマンドはnpm run watchとなります。

▼package.jsonファイル

{
  "scripts": {
    "build": "webpack",
    "watch": "webpack --watch"
  },
  "devDependencies": {
    "webpack": "^4.5.0",
    "webpack-cli": "^2.0.14"
  }
}

先述の通り、buildするよりもwatchを使ったほうが差分ビルドで高速になるので、積極的にwatchを利用するようにしましょう。

次はタスクランナーとしての使い分け方を紹介します。

タスクランナーとの使い分け

webpackはこうした性質上、タスクランナーであるGulpGruntの代わりとして紹介されることがしばしばあります。Googleトレンドで見ても、2017年4月現在ではタスクランナーGulpと肩を並べるほどwebpackは人気です。

2015年4月~2018年3月のGoogleトレンド調査(カテゴリー:コンピュータ)

タスクランナーでできることの多くはwebpackでも可能です。しかし、プロジェクトによってはタスクランナーGulp、Gruntの資産があり、webpackを部分的に採用したいケースもあるでしょう。また、webpackは「CSSや画像を含むあらゆるアセットファイルをJavaScriptとして出力する」ことが基本的な使い方となっているため、CSSや画像をそのまま扱いたい時はタスクランナーが必要になります。

webpackとタスクランナーは併用して使うことも選択肢の一つのです。Gulpとwebpackを連携するための方法は、筆者のQiitaの記事「Gulpで始めるwebpack 入門」を参照くださいませ。

他のモジュールバンドラーとの性能比較

性能面での比較

モジュールバンドラーとして知られているのはwebpackだけではありません。他にも類似のツールがあるので、性能面で違いはあるのかを検証しました。有名どころのnpm modulesを3つ利用しJavaScriptをバンドルする形での比較検証です。利用方法の制約から各ツールを完全に同一条件で比較できたわけではないので、「この技術を使った場合、こういう書き方をするのでこのぐらいの結果になる」という参考値としてとらえてください。

  • rollup : 0.56
  • webpack@4 : 4.1
  • webpack@3 : 3.11
  • fuse-box : 3.1
  • browserify : 16.1
  • parcel-bundler : 1.6

容量に関しては、webpackとrollupが最も小さくなりました。webpackはES ModulesをサポートしておりTree Shaking(未使用のモジュールを省いてバンドルする機能)や、モジュールの連結機能(可能な場合は複数のモジュールを一つに連結するconcatenateModulesオプション)を搭載していることが効果的だったようです。

ビルド時間に関してはwebpack 4(developモード)が最も高速でした。最新版webpack 4のリリースで「Build times decreased from 60 to 98%!!(意訳:ビルド時間は60%から98%に減少)」と紹介されているように、従来のwebpack 3よりも高速化したことが確認できました。

検証の条件・詳細とソースコードはGitHubで公開しています(「ベンチマークのソースコード」)。

ビルド時間の短さや成果物の容量から判断しても、webpack 4は他のツールよりも全般的に高性能であるといえそうです。もちろん、各々のツールには解決しようとしている課題が異なるので特性や使い方に違いがあります。さらに、性能は検証の条件で差がでるでしょうから、採用の前には皆さんのプロジェクトや環境で目的が合致しているか、性能に問題がないか試験されることをオススメします。

トレンドの比較

かつてはBrowserifyRequireJSといったツールもありました。npm trendsで調べたところ、webpackの利用が右肩上がりで他を圧倒していることがわかります。

各種バンドルツールのトレンド推移 | npm trends

BrowserifyはCommonJS仕様がベースで(module.exportsrequire()のような独自に定義された変数やメソッドを使う仕様)、Tree Shakingが使えないという点で旧世代のツールです。枯れた技術としてはRequireJSやBrowserifyの利点はありますが、標準仕様のES Modulesをネイティブで利用できるwebpackのほうが将来性があるといえそうです。

2017年12月に新しいバンドルツール「Parcel」が話題になりました。設定ファイルが不要であり手軽ですが、ほとんどカスタマイズできません。記事「設定ファイル不要のParcelでTypeScriptをコンパイル・バンドルしたら拍子抜けするほど簡単だった – Qiita」で試しましたが、webpackと比べるとParcelは案件で使うのはまだ早い印象を持ちました

webpackは次世代の標準となりうる技術

大規模なJavaScriptの開発にはモジュールシステムの導入は必須。webpackはJavaScriptのモジュールを扱いやすくするのはもちろん、他のアセットファイルの取り扱いにも長けているという便利な技術です。実際のJavaScript開発ではBabelやTypeScriptを利用することがほとんどでしょう。

続編記事「webpack + BabelでES2017ビルド環境の構築」と「webpack + TypeScriptの環境構築」で使い方を説明してますので、あわせてご覧ください。

筆者もここ最近webpackを使っていますが、多機能で使いやすく、現在人気になっているのも納得できました。トレンドから見てもタスクランナーと並んで今後標準のウェブ開発技術になることが予想されます。是非この機会に触れてみてください。

連載一覧

(編集部注*この記事は2016年5月23日に公開された記事を再編集したものです)