かんがるーさんの日記

最近自分が興味をもったものを調べた時の手順等を書いています。今は Spring Boot をいじっています。

Spring Boot + npm + Geb で入力フォームを作ってテストする ( その14 )( browser-sync --> Tomcat 連携してファイル変更時に自動リロードで反映される環境を構築してみる )

概要

記事一覧はこちらです。

Spring Boot + npm + Geb で入力フォームを作ってテストする ( その13 )( HTML を Thymeleaf テンプレートファイルにする + Controller クラスを作成する2 ) の続きです。

  • 今回の手順で確認できるのは以下の内容です。
    • browser-sync –> Tomcat 連携して、ファイルを変更したらブラウザ側で自動リロードして反映される環境を構築できるか試してみます。
    • 尚、Tomcat の起動は JRebel で行っています。JRebel は personal, non-commercial use only なら free な myJRebel があります。
    • devltools + bootRun タスクで Tomcat を起動したらどうなるかも まとめ に書きました。
    • 結論を言うと完全自動リロードする環境は構築可能でしたが、その場合無駄な動作をして開発効率が上がる気がしなかったので、Thymeleaf テンプレートファイルや java ファイルは手動 build することにしました。

参照したサイト・書籍

  1. Spring Boot + Gradle on Intellij IDEA でアプリケーション実行中にコードの変更反映と Thymeleaf テンプレートの変更反映
    http://bufferings.hatenablog.com/entry/2017/07/24/010551

  2. Gulp browser-sync - redirect API request via proxy
    https://stackoverflow.com/questions/25410284/gulp-browser-sync-redirect-api-request-via-proxy

  3. http-proxy-middleware
    https://www.npmjs.com/package/http-proxy-middleware

  4. chimurai/http-proxy-middleware - Impossible to ignore proxy path prefix
    https://github.com/chimurai/http-proxy-middleware/issues/31

  5. Browsersync options
    https://browsersync.io/docs/options

  6. Chokidar
    https://github.com/paulmillr/chokidar

目次

  1. browser-sync の proxy 機能で Tomcat と連携してみる
    1. bs-springboot-config.js を新規作成する
    2. package.json に起動用の npm-scripts を追加する
    3. 自動リロードされるか確認する(js ファイル編)
    4. 自動リロードされるか確認する(Thymeleaf テンプレートファイル編)
    5. 自動リロードされるか確認する(class ファイル編)
    6. ここまでの結果をまとめる
  2. Tomcat 起動中でも自動 build されるよう IntelliJ IDEA の設定を変更して、自動リロードされるか確認する
    1. Tomcat 起動中でも自動 build されるよう IntelliJ IDEA の設定を変更する
    2. 自動リロードされるか確認する(Thymeleaf テンプレートファイル編)
    3. 自動リロードされるか確認する(class ファイル編)
    4. 結果をまとめる
  3. js ファイルは Tomcat からではなく browser-sync から直接返すようにしてみる
    1. 特定の URL だけ Tomcat へ転送せずに browser-sync から直接返すことができるのか?
    2. http-proxy-middleware をインストールする
    3. bs-springboot-config.js を変更する
    4. 自動リロードされるか確認する(js ファイル編)
  4. build 時に browser-sync が落ちないように watchOptions を設定する
  5. まとめ

手順

browser-sync の proxy 機能で Tomcat と連携してみる

browser-sync には proxy 機能がありますので、リクエストを全て Tomcat へ転送して自動リロードされる環境を構築できるか試してみます。

bs-springboot-config.js を新規作成する

bs-config.js をコピーして bs-springboot-config.js を作成した後、以下の点を変更します。

/*
 |--------------------------------------------------------------------------
 | Browser-sync config file
 |--------------------------------------------------------------------------
 |
 | For up-to-date information about the options:
 |   http://www.browsersync.io/docs/options/
 |
 | There are more options than you see here, these are just the ones that are
 | set internally. See the website for more info.
 |
 |
 */
module.exports = {
    "ui": {
        "port": 3001,
        "weinre": {
            "port": 9081
        }
    },
    "files": [
        "./build/classes/**/*"
    ],
    "watchEvents": [
        "change"
    ],
    "watchOptions": {
        "ignoreInitial": true
    },
    "server": false,
    "proxy": "localhost:8080",
    "port": 9080,
    ..........
  • Tomcat は build/classes の下のファイルを見ているようなので、このディレクトリの下のファイルの変更を監視します。files の設定を "files": [ "./build/classes/**/*" ] に変更します。
  • browser-sync からは直接ファイルを返信しなくなるので、server の設定を "server": false に変更します。
  • "proxy": false"proxy": "localhost:8080" に変更します。

package.json に起動用の npm-scripts を追加する

package.json に bs-springboot-config.js を使用して browser-sync を起動するための npm-scripts を追加します。

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "postinstall": "run-s clean:static-dir copy:all",
    "clean:static-dir": "rimraf src/main/resources/static/*",
    "copy:all": "run-p copy:bootstrap copy:admin-lte copy:font-awesome copy:ionicons",
    "copy:bootstrap": "cpx node_modules/bootstrap/dist/**/* src/main/resources/static/vendor/bootstrap",
    "copy:admin-lte": "cpx node_modules/admin-lte/dist/**/* src/main/resources/static/vendor/admin-lte",
    "copy:font-awesome": "cpx node_modules/font-awesome/{css,fonts}/**/* src/main/resources/static/vendor/font-awesome",
    "copy:ionicons": "cpx node_modules/ionicons/dist/{css,fonts}/**/* src/main/resources/static/vendor/ionicons",
    "postcss:watch": "postcss src/main/assets/css/**/* -d src/main/resources/static/css -x .min.css -w --poll",
    "webpack": "webpack",
    "webpack:watch": "webpack --watch",
    "browser-sync": "browser-sync",
    "browser-sync:start": "browser-sync start --config bs-config.js",
    "browser-sync:springboot": "browser-sync start --config bs-springboot-config.js",
    "server": "run-p postcss:watch webpack:watch browser-sync:start",
    "springboot": "run-p postcss:watch webpack:watch browser-sync:springboot"
  },
  • 以下の2行を追加します。
    • "browser-sync:springboot": "browser-sync start --config bs-springboot-config.js"
    • "springboot": "run-p postcss:watch webpack:watch browser-sync:springboot"

これで npm run springboot コマンドを実行すれば browser-sync –> Tomcat 連携するようになります。

自動リロードされるか確認する(js ファイル編)

Tomcat を起動してから npm run springboot コマンドを実行します。

ブラウザから http://localhost:9080/inquiry/input/01/ にアクセスして入力画面1を表示した後(Tomcat ではなく browser-sync にアクセスするのでポート番号は 8080 ではなく bs-springboot-config.js に設定している 9080 になります)、js ファイル、Thymeleaf テンプレート、class ファイルを更新してみます。

まずは js ファイルから。src/main/assets/js/inquiry/input01.js を以下のように変更します。

var $ = require("admin-lte/plugins/jQuery/jquery-2.2.3.min.js");

$(document).ready(function () {
    $("h1").text("テストです");

    // 動作確認のために初期表示時に「次へ」ボタンをクリック可能にする
    $(".js-btn-next").prop("disabled", false);

    $(".js-btn-next").on("click", function (event) {
        $("#input01Form").attr("action", "/inquiry/input/01/?move=next");
        $("#input01Form").submit();

        // return false は
        // event.preventDefault() + event.stopPropagation() らしい
        return false;
    })
});
  • $("h1").text("テストです"); を追加します。

webpack が変更を検知して src/main/resources/static/js/inquiry/input01.js を出力しますが、

f:id:ksby:20170811205629p:plain

ブラウザに表示している入力画面1のタイトルは変更されませんでした。自動で build/classes/main/static/js/inquiry/input01.js の方に変更が反映されないので当然でした。

f:id:ksby:20170811205811p:plain

反映するために Ctrl+F9 を押して build したら npm run springboot コマンドが落ちました。。。 IntelliJ IDEA の方で Parsing java ... が表示されて数秒経過しているうちに npm run springboot コマンドがエラーで落ちるようです。何度試してみても Parsing java ... が表示されるとダメでした。js ファイルは webpack が出力するので Ctrl+Shift+F9 でそのファイルだけ build するという訳にもいきませんし、どうしたものでしょうか。。。

自動リロードされるか確認する(Thymeleaf テンプレートファイル編)

次は Thymeleaf テンプレートファイルで試してみます。npm run springboot コマンドを実行し直して、ブラウザでは入力画面1を表示しておきます。

src/main/resources/templates/web/inquiry/input01.html を以下のように変更します。

    <section class="content-header">
      <h1>
        テストです2
      </h1>
    </section>
  • h1 タグ内のテキストを 入力画面1テストです2 に変更します。

この時点でブラウザに切り替えても入力画面1の画面名の部分は何も変わりませんでした。何もしなければ Thymeleaf テンプレートファイルの変更は build/classes/main/templates/web/inquiry/input01.html に反映されないので当然でした。

Ctrl+F9 を押して build します。Reloading Browsers... のメッセージがいくつも出力されますが、

f:id:ksby:20170812074954p:plain

自動リロードされて画面名が テスト2 に変わりました。

f:id:ksby:20170812075104p:plain

この後何度か画面名を変更して Ctrl+F9 を押してみましたが、常に反映されました。Ctrl+F9 を押す手間はありますが、変更検知してブラウザに反映されます。

自動リロードされるか確認する(class ファイル編)

最後に class ファイルで試してみます。npm run springboot コマンドを実行し直して、ブラウザでは入力画面1を表示しておきます。

src/main/java/ksbysample/webapp/bootnpmgeb/web/inquiry/InquiryInputController.java を以下のように変更します。

    /**
     * 入力画面1 初期表示処理
     *
     * @return 入力画面1の Thymeleaf テンプレートファイルのパス
     */
    @GetMapping("/01")
    public String input01() {
        return TEMPLATE_INPUT02;
    }
  • TEMPLATE_INPUT01TEMPLATE_INPUT02 に変更します。

IntelliJ IDEA では通常自動コンパイルされないので、この時点では画面は何も変わりません。

Ctrl+F9 を押して build します。大量の Reloading Browsers... が出力されますが、

f:id:ksby:20170812080832p:plain f:id:ksby:20170812080947p:plain f:id:ksby:20170812081056p:plain f:id:ksby:20170812081220p:plain f:id:ksby:20170812081321p:plain

自動リロードされて入力画面2の画面が表示されました。

f:id:ksby:20170812081429p:plain

Controller クラスが返す画面を 入力画面1→入力画面2→入力画面1→… と何度か変更して Ctrl+F9 を押してみましたが、browser-sync は落ちることなくブラウザの画面に反映されました。Ctrl+F9 を押す手間がありますが、こちらも変更検知してブラウザに反映されるようです。

ここまでの結果をまとめる

現時点の状況としては、

  • js ファイルは、変更した後で js ファイルからカーソルを外せば webpack が変更検知して出力し直してくれますが、その後に自動で Tomcat が見ている build/classes ディレクトリに反映されないので自動リロードされません。また Ctrl+F9 を押して build/classes の下に反映しても browser-sync が落ちてしまいます。
  • Thymeleaf テンプレートファイルと class ファイルは Ctrl+F9 を押す手間は必要ですが、build するとブラウザには自動リロードされて反映されます。Tomcat 起動中も自動 build されるよう設定すればよさそう?

Tomcat 起動中でも自動 build されるよう IntelliJ IDEA の設定を変更して、自動リロードされるか確認する

Tomcat 起動中でも自動 build されるよう IntelliJ IDEA の設定を変更する

Tomcat を起動していない場合に自動 build する方法は知っているのですが Tomcat 起動中でも自動 build する方法がないか調べたところ、Spring Boot + Gradle on Intellij IDEA でアプリケーション実行中にコードの変更反映と Thymeleaf テンプレートの変更反映 という記事を見つけました。ちょうどやりたいことと一致していたので、この記事の通り設定してみます。

IntelliJ IDEA のメインメニューから「File」-「Settings…」を選択します。

「Settings」ダイアログが表示されたら、画面左側の一覧から「Build, Execution, Deployment」-「Compiler」を選択した後、画面右側の「Build project automatically」をチェックします。チェック後「OK」ボタンをクリックしてダイアログを閉じます。

f:id:ksby:20170812093132p:plain

次に IntelliJ IDEA のメインメニューから「Help」-「Find Action…」を選択します。

「Enter action or option name」ダイアログが表示されますので、registry と入力して、表示された一覧から Registry... を選択します。

f:id:ksby:20170812093421p:plain

「Registry」ダイアログが表示されますので「compiler.automake.allow.when.app.running」をチェックします。チェック後「Close」ボタンをクリックしてダイアログを閉じます。

f:id:ksby:20170812094401p:plain

自動リロードされるか確認する(Thymeleaf テンプレートファイル編)

設定は以上で終了です。今度は Ctrl+F9 を押すことなしに自動リロードされるか試してみます。

Tomcat を起動してから npm run springboot コマンドを実行し、ブラウザで入力画面1を表示します。

先程と同様に src/main/resources/templates/web/inquiry/input01.html の h1 のテキストを テストです2 に変更します。が、ブラウザに反映されません。また Thymeleaf を編集しようとした時に、先程 java ファイルを変更して Ctrl+F9 を押して build した時と同様に大量の Reloading Browsers... のメッセージが出力されました。

Ctrl+F9 を押さなくても自動 build されて build/classes/main/templates/web/inquiry/input01.html に変更は反映されていたのですが、browser-sync が変更を検知できないようです。ブラウザで F5 を押して手動リロードすると画面上に変更が反映されました。

自動リロードされるか確認する(class ファイル編)

今度は src/main/java/ksbysample/webapp/bootnpmgeb/web/inquiry/InquiryInputController.java の input01 メソッドの戻り値を TEMPLATE_INPUT01TEMPLATE_INPUT02 に変更してみます。

こちらは自動でブラウザまで反映されました。ただしリロードが2回発生します。ブラウザのタブに表示される文字列を見ていると、1回目は入力画面1で、2回目は入力画面2でした。何度か試しても同じです。またリロードが発生するのは IntelliJ IDEA 内で別のファイルにタブを切り替えるか、別のプロセスに切り替える必要がありました。自動 build は編集しているファイルにカーソルがある間は実行されないようです。

f:id:ksby:20170812102639p:plain

結果をまとめる

IntelliJ IDEA で自動 build の設定をすると class ファイルの方は自動リロードされますが、Thymeleaf テンプレートファイルの方は手動リロードが必須でした。また少し多めにリロードが発生するのが気になりました。一旦自動 build の設定は元に戻します。

js ファイルは Tomcat からではなく browser-sync から直接返すようにしてみる

特定の URL だけ Tomcat へ転送せずに browser-sync から直接返すことができるのか?

js ファイルを変更すれば webpack の watch 機能で変更検知されて自動で src/main/resources/static/js の下に出力されることは既に分かっており、build/classes/main/static の下のファイルは src/main/resources/static の下のファイルをコピーしているだけであること、src/main/resources/static の下のファイルが変更されたら browser-sync が変更検知して自動リロードしてくれることは既に確認していることから、js ファイルは Tomcat へ転送せずに browser-sync から直接返すようにすれば Ctrl+F9 を押す手間がなくなるのではないか?、と思いました。

browser-sync でそのような設定が可能なのか調べてみたところ、以下の記事を見つけました。browser-sync の proxy 機能は使用せずに、http-proxy-middleware パッケージを使用すれば実現できそうなので、試してみることにします。

http-proxy-middleware をインストールする

npm install --save-dev http-proxy-middleware コマンドを実行してインストールします。

f:id:ksby:20170812150752p:plain

bs-springboot-config.js を変更する

bs-springboot-config.js の以下の点を変更します。

var httpProxyMiddleware = require('http-proxy-middleware');
var proxy = httpProxyMiddleware(
    [
        // /css, /js, /vendor と *.html は Tomcat に転送しない
        "!/css/**/*",
        "!/js/**/*",
        "!/vendor/**/*",
        "!/**/*.html",
        "/**/*"
    ],
    {target: "http://localhost:8080"}
);

/*
 |--------------------------------------------------------------------------
 | Browser-sync config file
 |--------------------------------------------------------------------------
 |
 | For up-to-date information about the options:
 |   http://www.browsersync.io/docs/options/
 |
 | There are more options than you see here, these are just the ones that are
 | set internally. See the website for more info.
 |
 |
 */
module.exports = {
    "ui": {
        "port": 3001,
        "weinre": {
            "port": 9081
        }
    },
    "files": [
        "./build/classes/**/*.class",
        "./build/classes/**/*.html",
        "./static/**/*",
        "./src/main/resources/static/**/*"
    ],
    "watchEvents": [
        "change"
    ],
    "watchOptions": {
        "ignoreInitial": true
    },
    "server": {
        "baseDir": [
            "./static",
            "./src/main/resources/static"
        ],
        "middleware": [proxy]
    },
    "proxy": false,
    "port": 9080,
    ..........
  • ファイルの先頭に以下の2行を追加します。
    • var httpProxyMiddleware = require('http-proxy-middleware');
    • var proxy = httpProxyMiddleware(["!/css/**/*", "!/js/**/*", "!/vendor/**/*", "!/**/*.html", "/**/*"], {target: "http://localhost:8080"});
  • "files": ["./build/classes/**/*"]"files": ["./build/classes/**/*.class", "./build/classes/**/*.html", "./static/**/*", "./src/main/resources/static/**/*"] に変更します。
  • "server": false"server": {"baseDir": ["./static", "./src/main/resources/static"], "middleware": [proxy]} に変更します。
  • "proxy": "localhost:8080""proxy": false に変更します。

自動リロードされるか確認する(js ファイル編)

js ファイル変更時に自動リロードされるか試してみます。

Tomcat を起動してから npm run springboot コマンドを実行し、ブラウザで入力画面1を表示します。

src/main/assets/js/inquiry/input01.js に $("h1").text("テストです"); を追加します。ブラウザに切り替えると画面名が テストです にすぐに切り替わりました。

f:id:ksby:20170812155952p:plain

ただしこの後に Ctrl+F9 を押して build し、Parsing java ... のメッセージが数秒出る状態になると browser-sync が落ちました。。。 コマンドプロンプトに出力されているエラーメッセージを見ると Error: EPERM: operation not permitted, lstat 'c:\project-springboot\ksbysample-boot-miscellaneous\boot-npm-geb-sample\build\classes\main\static\js\inquiry' と出力されています。おそらく build 時に lstat できなくなる場合があって、それに引っかかるとエラーで落ちてしまうものと思われます。

build 時に browser-sync が落ちないように watchOptions を設定する

build 時に browser-sync が落ちてしまうのを回避できる設定がないか Browsersync options のページを見たのですが、「watchOptions」のところに File watching options that get passed along to Chokidar. Check their docs for available options という記述と Chokidar へのリンクがありました。

Chokidar のページを見てみると ignorePermissionErrors という設定がありました。この項目の説明文に EPERM の記述があったので、おそらくこの設定でエラーを無視できると思われます。デフォルトでは false なので true にしてみます。

Tomcat を起動してから npm run springboot コマンドを実行し、ブラウザで入力画面1を表示します。

src/main/assets/js/inquiry/input01.js に $("h1").text("テストです"); を追加してから Ctrl+F9 を押して build を実行し Parsing java ... のメッセージが数秒出る状態を何度か再現してみましたが、今度は browser-sync がエラーで落ちることはありませんでした。

また Chokidar のページには usePolling というオプションもあり、ファイルの変更をポーリングでチェックできるようでした。IntelliJ IDEA で Tomcat 起動時にも自動 build できるように設定を変更して、browser-sync の watchOptions に "usePolling": true を追加してみたところ、Thymeleaf テンプレートファイルを変更したときも class ファイルを変更したときもどちらも自動リロードさせることができたのですが、class ファイル変更時に自動リロードが2回動くことと、js ファイルの時と比較するとあまり動きが軽快でないことが自分好みではなかったので、このオプションは使用しないことにします。usePolling を使用しなくても Ctrl+F9 か Ctrl+Shift+F9(変更したファイルだけ build)で手動 build すれば自動リロードされるので、build は手動で行うことにします。

まとめ

  • browser-sync –> Tomcat 連携は可能。ただし Tomcat は JRebel で起動すること。使い勝手は申し分ない。
  • browser-sync –> Tomcat 連携は browser-sync の proxy 機能は使用せず http-proxy-middleware パッケージを使用する。
  • http-proxy-middleware パッケージを使用する理由は /css, /js 及び *.html にマッチする URL の場合には Tomcat に転送せず browser-proxy から直接返信するためである。その方が js ファイル変更 –> ブラウザの自動リロードまでのレスポンスが軽快で開発しやすい。
  • Thymeleaf テンプレートファイルと class ファイルは Tomcat から返信する。
  • IntelliJ IDEA の自動 build の設定は有効にしない。Thymeleaf テンプレートファイルや java ファイルを変更した時には Ctrl+F9 あるいは Ctrl+Shift+F9 で手動 build する。手動 build すると browser-sync がファイルの変更を検知してブラウザを自動リロードする。
  • browser-sync, Tomcat はどちらから起動してもよい。また途中でどちらかを再起動しても問題ない。
  • Tomcat を devtools + bootRun タスクで起動した場合、class ファイル変更時には自動リロードで反映されない。devtools がクラスローダーを再起動する時間が長く、class ファイルの変更を検知して自動リロードしようとしても Tomcat からの応答がタイムアウトして Error occured while trying to proxy to: localhost:9080/inquiry/input/01/ のようなエラーメッセージがブラウザ上に表示される。

最後に最終版の package.json と bs-springboot-config.js を載せておきます。

ソースコード

package.json

{
  "name": "boot-npm-geb-sample",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "postinstall": "run-s clean:static-dir copy:all",
    "clean:static-dir": "rimraf src/main/resources/static/*",
    "copy:all": "run-p copy:bootstrap copy:admin-lte copy:font-awesome copy:ionicons",
    "copy:bootstrap": "cpx node_modules/bootstrap/dist/**/* src/main/resources/static/vendor/bootstrap",
    "copy:admin-lte": "cpx node_modules/admin-lte/dist/**/* src/main/resources/static/vendor/admin-lte",
    "copy:font-awesome": "cpx node_modules/font-awesome/{css,fonts}/**/* src/main/resources/static/vendor/font-awesome",
    "copy:ionicons": "cpx node_modules/ionicons/dist/{css,fonts}/**/* src/main/resources/static/vendor/ionicons",
    "postcss:watch": "postcss src/main/assets/css/**/* -d src/main/resources/static/css -x .min.css -w --poll",
    "webpack": "webpack",
    "webpack:watch": "webpack --watch",
    "browser-sync": "browser-sync",
    "browser-sync:start": "browser-sync start --config bs-config.js",
    "browser-sync:springboot": "browser-sync start --config bs-springboot-config.js",
    "server": "run-p postcss:watch webpack:watch browser-sync:start",
    "springboot": "run-p postcss:watch webpack:watch browser-sync:springboot"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "admin-lte": "^2.3.11",
    "bootstrap": "^3.3.7",
    "font-awesome": "^4.7.0",
    "ionicons": "^3.0.0"
  },
  "devDependencies": {
    "autoprefixer": "^7.1.2",
    "browser-sync": "^2.18.13",
    "cpx": "^1.5.0",
    "cssnano": "^3.10.0",
    "http-proxy-middleware": "^0.17.4",
    "npm-run-all": "^4.0.2",
    "postcss-cli": "^4.1.0",
    "rimraf": "^2.6.1",
    "stylelint": "^8.0.0",
    "stylelint-config-standard": "^17.0.0",
    "webpack": "^3.3.0"
  }
}

bs-springboot-config.js

var httpProxyMiddleware = require('http-proxy-middleware');
var proxy = httpProxyMiddleware(
    [
        // /css, /js, /vendor と *.html は Tomcat に転送しない
        "!/css/**/*",
        "!/js/**/*",
        "!/vendor/**/*",
        "!/**/*.html",
        "/**/*"
    ],
    {target: "http://localhost:8080"}
);

/*
 |--------------------------------------------------------------------------
 | Browser-sync config file
 |--------------------------------------------------------------------------
 |
 | For up-to-date information about the options:
 |   http://www.browsersync.io/docs/options/
 |
 | There are more options than you see here, these are just the ones that are
 | set internally. See the website for more info.
 |
 |
 */
module.exports = {
    "ui": {
        "port": 3001,
        "weinre": {
            "port": 9081
        }
    },
    "files": [
        "./build/classes/**/*.class",
        "./build/classes/**/*.html",
        "./static/**/*",
        "./src/main/resources/static/**/*"
    ],
    "watchEvents": [
        "change"
    ],
    "watchOptions": {
        "ignoreInitial": true,
        "ignorePermissionErrors": true
    },
    "server": {
        "baseDir": [
            "./static",
            "./src/main/resources/static"
        ],
        "middleware": [proxy]
    },
    "proxy": false,
    "port": 9080,
    "middleware": false,
    "serveStatic": [],
    "ghostMode": {
        "clicks": true,
        "scroll": true,
        "location": true,
        "forms": {
            "submit": true,
            "inputs": true,
            "toggles": true
        }
    },
    "logLevel": "info",
    "logPrefix": "Browsersync",
    "logConnections": false,
    "logFileChanges": true,
    "logSnippet": true,
    "rewriteRules": [],
    "open": "local",
    "browser": "default",
    "cors": false,
    "xip": false,
    "hostnameSuffix": false,
    "reloadOnRestart": false,
    "notify": false,
    "scrollProportionally": true,
    "scrollThrottle": 0,
    "scrollRestoreTechnique": "window.name",
    "scrollElements": [],
    "scrollElementMapping": [],
    "reloadDelay": 0,
    "reloadDebounce": 0,
    "reloadThrottle": 0,
    "plugins": [],
    "injectChanges": true,
    "startPath": null,
    "minify": true,
    "host": null,
    "localOnly": false,
    "codeSync": true,
    "timestamps": true,
    "clientEvents": [
        "scroll",
        "scroll:element",
        "input:text",
        "input:toggles",
        "form:submit",
        "form:reset",
        "click"
    ],
    "socket": {
        "socketIoOptions": {
            "log": false
        },
        "socketIoClientConfig": {
            "reconnectionAttempts": 50
        },
        "path": "/browser-sync/socket.io",
        "clientPath": "/browser-sync",
        "namespace": "/browser-sync",
        "clients": {
            "heartbeatTimeout": 50000
        }
    },
    "tagNames": {
        "less": "link",
        "scss": "link",
        "css": "link",
        "jpg": "img",
        "jpeg": "img",
        "png": "img",
        "svg": "img",
        "gif": "img",
        "js": "script"
    }
};

履歴

2017/08/12
初版発行。