Vue.js で非SPAのサイトもホットリロードで開発したい

最終更新日
2018.03.27

一度だけなら…とホットリロードを体験してしまうと依存スパイラルに陥り数秒のビルドにもイライラしはじめそれなしではいられない体になります。

Vue のホットリロードいいよね♥

単純にブラウザをリロードするわけじゃなくて、シームレスに更新される開発モードがあるじゃないですか。 他の言語やフレームワークでもホットデプロイみたいな名前で同じような機能はあると思うんですけど、はじめて使った時私は感動しました。

多ページサイトで所々 Vue を使いたいとか API が無い自分の好きな CMS を使ってるなど理由があって SPA にはしないけど開発モードのホットリロードだけ使いたい人向けです。

Vue CLI でセットアップする

対象のプロジェクトフォルダに Vue CLI の「webpack」テンプレートでもろもろインストールします。 ちなみに「webpack-simple」テンプレートでもできます。

既存プロジェクトにマージ

いろいろ理由があって「新規でインストールしたくない」という場合は、別のフォルダで Vue プロジェクトを作成して必要なフォルダだけをコピーします。 「build」「config」フォルダと、package.jsonに書いてある不足している依存モジュールを追加してください。

プロキシを設定

config/index.js に空のプロキシテーブルがあるので XAMPP や別サーバーで動作させてる URL を追加します。

config/index.js

proxyTable: {
  '*': {
    target: 'http://localhost:8081', // php やバックエンド用のサーバー
    changeOrigin: true,
    filter: function (pathname) {
      if (pathname.match('hot-update.(js|json)$') ||
          pathname.match('^/app.js$') ||
          pathname.match('^/__webpack_hmr$') ||
          /* Devモードで動的に読み込みたいものを追加する */
          pathname.match('^/dist/static/img')) {
        return false
      }
      return true
    }
  }
},

ルートからすべて http://localhost:8081 が吊り下がる感じになります。

開発するときは npm run dev を実行して http://localhost:8080 の URL を使用します。

ビルド時にハッシュを付けないようにする

webpackテンプレートでは、キャッシュを無効にするためビルドしたファイルには自動的にハッシュが付きます。 HTML ドキュメントが動的に作成されないため、ビルドするたびにハッシュ付きのパスに書き換えるのは大変です。 生成ファイルにハッシュを付けないように設定します。

build/webpack.prod.conf.js にある [chunkhash][contenthash] を削除。

スクリプトパスを同じにする

今の状態だと、デフォルトだと開発中は /app.js を使うようになりますが、開発と運用でパスが異なる場合があります。 Devモードの output.filenamedev.proxyTable.filter 部分で /app.js のパスを修正して開発と本番で同じパスにしておくと、変更しなくていいので楽になります。

config/index.js

dev:{
  assetsPublicPath: '/dist/'
}

build/webpack.dev.config.js

output: {
  filename: 'static/js/[name].js'
}

これでビルドするたびにパスを修正しなくてもOKです!

<script src="/dist/static/js/manifest.js"></script>
<script src="/dist/static/js/vendor.js"></script>
<script src="/dist/static/js/app.js"></script>

わたしの環境が、プロジェクトルートとドキュメントルートが同じなのでこの設定(標準のまま)になっています。 パスが変わる場合は調整してください。

ルートの HTML ドキュメントは、たとえば「index.php」などが使用されるため、標準で入っている「index.html」は不要になります。 このファイルが不要なら HtmlWebpackPlugin 部分を削除してしまっても問題ないんじゃないかと思います。

たとえば「HTML には書いているけどビルドされた CSS を読み込まないようにする」とか、「Dev モードでは特定のファイルの読み込み先を別にしたい」とかあれば pathRewritefilter でパスを設定して、動的ファイルや空のファイルに誘導してしまえばよさそう。

proxyTable: {
  '*': {
    // 省略
    pathRewrite: {
      '^/dist/static/css/.*?\.css': '/dist/dummy/dummy.css',
      '^/dist/static/js/.*?\.js': '/dist/dummy/dummy.js'
    }
  }
},

デモ

ディレイ付きのアニメーションなのでちょっと分かりにくいですが、SVGアニメを作っているコンポーネント部分だけがリロードされてサクッと確認できます。

特にこういう部品のアニメーションとかはいちいちビルドするのが面倒なので別のフォルダで作り込んで上手く行ったらコピペとかしてたけどこの速度だったら直接編集してもストレスにならなさそうですね。

まとめ

すごいストレスフリーになりました(๑'ᴗ'๑) 最初は webpac-dev-derver + vue-hot-reload-api を試してみましたが、ブラウザ自体がリロードされてしまいました。 Vue CLI のようにスルっとさせるためにゼロから設定するのは、すごい面倒くさそうなのでやめました。 今のところ Webpack を勉強する時間がないので…。 さて次回は Vue-router を使ったページの構成&遷移エフェクトについてやりたいと思います!