KCF Labo Blog

KDDI Commerce Forwardの開発ブログ

webpack-dev-server後継のwebpack-serveを利用してみたお話

2018.09.20 追記: webpack-serveは DEPRECATED となりました。 これまで通り webpack-dev-server を利用することをおすすめします。

はじめまして。エンジニアの白本です。

皆さんはフロント開発における開発用ローカルサーバは何を利用されていますか?
browser-syncwebpack-dev-server
私は少し前からwebpack-dev-serverの後継であるwebpack-serveを利用しています。

github.com

webpack-serveってなに?

f:id:kcf_shiramoto:20180806163133p:plain
webpack-dev-serverのgithubには以下のように書かれています。

Please note that webpack-dev-server is presently in a maintenance-only mode and will not be accepting any additional features in the near term. Most new feature requests can be accomplished with Express middleware; please look into using the before and after hooks in the documentation.

Use webpack-serve for a fast alternative. Use webpack-dev-server if you need to test on old browsers.

要はwebpack-dev-serverはメンテナンスモードで運営されていて今後新しい機能などは追加しないからwebpack-serveを使ってね!
ただし古いブラウザ使うんだったらwebpack-dev-serverが必要だよ。

webpack-serveとwebpack-dev-serverの違い

webpack-serveとwebpack-dev-serverの違いを見てみましょう。

利用できるwebpackのバージョン

webpack-serveはwebpack v4以降でないと利用できません。*1
webpack-dev-serverも最新のv3.xではwebpack v4.xでしか利用できませんがバージョンを落とせばwebpack v3.xでも利用できます。

内部で利用されているフレームワーク

webpack-dev-serverは Express を利用しているのに対しwebpack-serveは Koa を利用しています。

KoaとExpress

本題から外れて少しだけKoaとExpressの話をしましょう。
どちらもnode.js用のWebフレームワークです。またKoaとExpressの作者は同じ方です。
Expressが2010年にリリースされ、後発のKoaは2013年にリリースされています。
Koa自体はExpressが持つルーティングやテンプレートの機能をそれ単体では持たない軽量なフレームワークです。
それらの機能が必要であればパッケージを追加する必要があります。
また大きな違いとしてKoaはジェネレータやasync/awaitという比較的新しい機能を利用でき、Expressで問題だったコールバック地獄から解消されます。
より詳しく違いを知りたい方は公式の Koa vs Express を読んでみてください。

WebSocketかSockJSか

LiveReloadやHMRの仕組みが違います。
webpack-serveは WebSocket (webpack-hot-client経由で)というモダンなウェブブラウザでは標準で利用できる通信規格を利用しています。
webpack-dev-serverは SockJS というライブラリを利用しています。
SockJSはWebSocketが利用できるブラウザ・環境ではWebSocketを利用しますが古いブラウザやその他の制限で利用できない場合はポーリングなどの代替手段を提供します。
古いブラウザではwebpack-dev-serverを利用する必要があるのはこのためです。

実際に使ってみる

Config

webpack-dev-serverはwebpackコンフィグにオブジェクトで設定しますがwebpack-serveにはいくつかの方法が用意されています。

1.CLIで指定

詳しくはgithubを見てもらえれば分かりますがCLIで指定する方法があります。
簡単な設定であればこちらで問題ないですが長くなる場合は別の方法がいいでしょう。

$ webpack-serve --port 3000 --reload --config ./webpack.config.js

2.package.jsonに書く

package.jsonJSON形式で書くこともできます。

...,
"serve": {
  "port": 3000,
  "reload": true,
  "config": "webpack.config.js",
  "content": "./public",
  "devMiddleware": {
    "publicPath": "/assets"
  }
}
...

3.JSONYAMLファイルに書く

2で書いた内容をJSONYAMLファイルとして書くこともできます。
package.jsonはパッケージの情報やnpm scripts等も記載されますので分けて書きたい場合はこちらの方がスッキリするでしょう。
.severc.serverc.json,.serverc.yml というファイル名で保存します。

4.webpack.config.jsファイルに書く

webpack.config.jsにも書くことができます。

// webpack config
module.exports = {
 ...
};

// serve config
module.exports.serve = {
  port: 3000,
  content: './public/,
  devMiddleWare: {
    publicPath: '/assets/',
    stats: {
      cached: true,
      modules: false,
      colors: true
    }
  }
};

5.serve.config.jsに書く

こちらもJSONYAMLと同じで4で書いた内容をwebpack.config.jsと切り離して設定ファイルを用意したい場合に利用します。
serve.config.js というファイル名で保存します。

Events

イベントをハンドリングしたい場合はJSを利用するしかありません。
全てのイベントの第一引数からStatsを参照できるので追加で情報を出したい場合はこちらを利用すると良いでしょう。

module.exports.serve = {
  ...,
  on: {
    'build-started': (stats) => {
      console.log('ビルドを開始しますよ');
    },
    'build-finished': (stats) => {
      console.log('ビルドが終わったよ');
    },
    'compiler-warning': (stats) => {
      console.log('Warningが発生したよ');
    },
    'compiler-error': (stats) => {
      console.log('Errorが発生したよ');
      /**
       * エラーは通常設定であれば敢えてこちらで出力する必要はありません
       * 敢えてこちらで出力したい場合は stats.errors を false にしないと2重でエラーが出てしまいます
       */
      const { errors } = stats.json;
      errors.forEach((error) => {
        console.log(error);
      });
    }
  }
};

Add-on

webpack-serveの目玉?機能のひとつにAdd-onがあります。
webpack-serve自体に機能を持たせるのではなく、必要があれば自由に追加することができます。
この辺はKoaに似ていますしKoaをフレームワークとして採用した理由のような気がします。
githubにいくつかのサンプルが用意されています。
また、Add-onを利用したいくつかのパッケージも既にあるようです。

github.com github.com

おわりに

webpack-serveは今年2月に最初のバージョンがリリースされました。
5月に1.0.0がリリースされ、7月に2.0.0がリリースされています。
1.0.0から2.0.0へのアップデートでは破壊的変更があり設定の互換性がありません。
短いスパンでのメジャーアップデート、破壊的変更からも分かるようにまだまだ試行錯誤段階のようです。

これらのことから今すぐwebpack-dev-serverからwebpack-serveに乗り換える必要はないでしょう。
ただし最初に書いたようにwebpack-dev-serverは既にメンテナンスモードです。
今後webpackがメジャーアップデートされるタイミングでwebpack-dev-serverは対応されない可能性もあるので今のうちからwebpack-serveに慣れておくといいですね。

*1:執筆時のバージョン2.0.2