Webpack Dev ServerとFirebase serveを一緒に使う

Firebase Hostingを開発するために公式でstatic serverが用意されていますがconfigを元にrewriteやheaderを書き換えてくれるわずかなミドルウェアの入っただけなので`webpack-dev-server`と一緒に使う場合の方法です。

webpack-dev-serverはwebpack用の開発サーバーでビルドした結果を返してくれたりホットリロードをサポートしていたりと高機能な開発サーバーです。

# 環境

MacOS 10.12.2
Node 8.8.1
webpack 3.8.1

# セットアップ

雛形として[webpack-simple](https://github.com/vuejs-templates/webpack-simple)を使いました。

以下のコマンドでプロジェクトを作成できます。

```bash
$ npm install -g vue-cli
$ vue init webpack-simple my-project

  This will install Vue 2.x version of the template.

  For Vue 1.x use: vue init webpack-simple#1.0 my-project

? Project name my-project
? Project description A Vue.js project
? Author Kazuhiro Kubota <k2.wanko@gmail.com>

   vue-cli · Generated "my-project".

   To get started:

     cd my-project
     npm install
     npm run dev
```

次に[firebase-tools](https://www.npmjs.com/package/firebase-tools)を使ってセットアップします。

```bash
$ npm install -g firebase-tools
$ cd my-project
$ firebase init

     🔥🔥🔥🔥🔥🔥🔥🔥 🔥🔥🔥🔥 🔥🔥🔥🔥🔥🔥🔥🔥  🔥🔥🔥🔥🔥🔥🔥🔥 🔥🔥🔥🔥🔥🔥🔥🔥     🔥🔥🔥     🔥🔥🔥🔥🔥🔥  🔥🔥🔥🔥🔥🔥🔥🔥
     🔥🔥        🔥🔥  🔥🔥     🔥🔥 🔥🔥       🔥🔥     🔥🔥  🔥🔥   🔥🔥  🔥🔥       🔥🔥
     🔥🔥🔥🔥🔥🔥    🔥🔥  🔥🔥🔥🔥🔥🔥🔥🔥  🔥🔥🔥🔥🔥🔥   🔥🔥🔥🔥🔥🔥🔥🔥  🔥🔥🔥🔥🔥🔥🔥🔥🔥  🔥🔥🔥🔥🔥🔥  🔥🔥🔥🔥🔥🔥
     🔥🔥        🔥🔥  🔥🔥    🔥🔥  🔥🔥       🔥🔥     🔥🔥 🔥🔥     🔥🔥       🔥🔥 🔥🔥
     🔥🔥       🔥🔥🔥🔥 🔥🔥     🔥🔥 🔥🔥🔥🔥🔥🔥🔥🔥 🔥🔥🔥🔥🔥🔥🔥🔥  🔥🔥     🔥🔥  🔥🔥🔥🔥🔥🔥  🔥🔥🔥🔥🔥🔥🔥🔥

You're about to initialize a Firebase project in this directory:

  /private/tmp/my-project

Before we get started, keep in mind:

  * You are currently outside your home directory

? What Firebase CLI features do you want to setup for this folder? Database: Deploy Firebase Realtime Database Rules, Hosting: Configure and deploy Fireba
se Hosting sites

=== Project Setup

First, let's associate this project directory with a Firebase project.
You can create multiple project aliases by running firebase use --add,
but for now we'll just set up a default project.

? What Firebase project do you want to associate as default? [don't setup a default project]

=== Database Setup

Firebase Realtime Database Rules allow you to define how your data should be
structured and when your data can be read from and written to.

? What file should be used for Database Rules? database.rules.json
✔  Database Rules for undefined have been downloaded to database.rules.json.
Future modifications to database.rules.json will update Database Rules when you run
firebase deploy.

=== Hosting Setup

Your public directory is the folder (relative to your project directory) that
will contain Hosting assets to be uploaded with firebase deploy. If you
have a build process for your assets, use your build's output directory.

? What do you want to use as your public directory? public
? Configure as a single-page app (rewrite all urls to /index.html)? No
✔  Wrote public/404.html
✔  Wrote public/index.html

i  Writing configuration info to firebase.json...
i  Writing project information to .firebaserc...

✔  Firebase initialization complete!
```

次にpackage.jsonに依存パッケージを追加します。

```bash
$ npm install -D firebase-tools
$ npm install -D superstatic
$ npm install -D html-webpack-plugin
```

# 設定ファイルの修正

以下のように`devServer`と`plugin`を書き換えます。

```js:webpack.config.js
var path = require('path')
var webpack = require('webpack')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var firebaseConfig = require('firebase-tools/lib/config').load({ cwd: process.cwd() })

module.exports = {
  entry: './src/main.js',
  output: {...},
  ...
  devServer: {
    historyApiFallback: true,
    noInfo: true,
    before(app) {
      app.use(require('superstatic')({ config: firebaseConfig.data.hosting }))
    }
  },
  ...
  plugins: [
    new HtmlWebpackPlugin({
      template: 'index.html'
    })
  ]
}

...
```

そして`npm run dev`を実行すれば rewriteなどの設定が効きつつホットリロードのできる開発サーバーが実行できます。