Spring Boot + npm + Geb で入力フォームを作ってテストする ( その7 )( webpack + browser-sync をインストールする )
概要
記事一覧はこちらです。
Spring Boot + npm + Geb で入力フォームを作ってテストする ( その6 )( URL の決定 ) の続きです。
- 今回の手順で確認できるのは以下の内容です。
- 各画面の HTML を作成する前に、今回は HTML の確認を Tomcat ではなく webpack + browser-sync を使用して行ってみようと思います。
- まずはインストールして試してみます。
- 「Spring Boot + npm + Geb で入力フォームを作ってテストする」では webpack は js ファイルの開発にしか使わないので HTML の確認だけなら browser-sync だけでいいのですが、両方インストールして変更したファイル(html ファイルだけでなく js ファイルも)を watch する仕組みを構築します。
参照したサイト・書籍
最新版で学ぶwebpack 3入門 – JavaScript開発で人気のバンドルツール
https://ics.media/entry/12140Building Static Sites with Webpack
https://blog.binoy.io/building-static-sites-with-webpack-4fc489ceabcaWebPack-Dev-ServerからBrowsersyncに乗り換えた
https://saku.io/move-from-webpack-dev-server-to-browser-sync/webpackで複数のディレクトリへ出力する
http://webdesign-dackel.com/2015/09/10/webpack-multiple-output/window.onloadとjQueryの$(document).ready等の比較
https://rcmdnk.com/blog/2015/07/11/computer-javascript-jquery/
目次
手順
webpack をインストールする
npm install --save-dev webpack
コマンドを実行して webpack をインストールします。
プロジェクトのルートディレクトリ直下に webpack.config.js というファイルを新規作成し、以下の内容を記述します。
module.exports = { entry: { "js/app": ["./src/main/assets/js/app.js"] }, output: { path: __dirname + "/src/main/resources/static", publicPath: "/", filename: "[name].js" } };
- js ファイルは src/main の下に assets/js ディレクトリを作成し、その下に作成します。
- 今回は動作確認のために app.js を作成します。
- webpack により処理・生成された js ファイルは src/main/resources/static/js の下に配置します。
src/main の下に assets/js ディレクトリを作成し、src/main/assets/js の下に app.js を作成します。
app.js には以下の内容を記述します。
var $ = require("admin-lte/plugins/jQuery/jquery-2.2.3.min.js");
webpack を起動しやすくするために package.json の scripts に以下の記述を追加します。
"scripts": { .........., "webpack": "webpack" },
動作確認します。まずは npm run webpack -- --version
コマンドを実行してバージョン番号が表示されることを確認します。
3.3.0
と表示されました。
次に npm run webpack
コマンドを実行し、src/main/assets/js/app.js から src/main/resources/static/js/app.js が生成されることを確認します。
コマンドが正常に終了し、src/main/resources/static/js の下に app.js が生成されています。
app.js を開くと以下の内容で始まるファイルでした。
問題なく動作しているようですので、次へ進みます。
browser-sync をインストールする
npm install --save-dev browser-sync
コマンドを実行して browser-sync をインストールします。
package.json の scripts に以下の記述を追加します。
"scripts": { .........., "browser-sync": "browser-sync" },
npm run browser-sync -- init
コマンドを実行して bs-config.js を生成します。
bs-config.js の以下の点を変更します。
"weinre": { "port": 8080 }
→"weinre": { "port": 9081 }
に変更します。"files": false
→"files": [ "./static/**/*", "./src/main/resources/static/**/*" ]
に変更します。"server": false
→"server": { "baseDir": [ "./static", "./src/main/resources/static" ] }
に変更します。"port": 3000
→"port": 9080
に変更します。"notify": true
→"notify": false
に変更します。
/* |-------------------------------------------------------------------------- | 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": [ "./static/**/*", "./src/main/resources/static/**/*" ], "watchEvents": [ "change" ], "watchOptions": { "ignoreInitial": true }, "server": { "baseDir": [ "./static", "./src/main/resources/static" ] }, "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": 5000 } }, "tagNames": { "less": "link", "scss": "link", "css": "link", "jpg": "img", "jpeg": "img", "png": "img", "svg": "img", "gif": "img", "js": "script" } };
package.json の scripts に以下の記述を追加します。
"scripts": { .........., "browser-sync:start": "browser-sync start --config bs-config.js" },
プロジェクトのルートディレクトリ直下に static ディレクトリを作成します。今回は Thymeleaf テンプレート前の html ファイルは jar ファイルに入れないようにするために、src/main/resources/static ではなく static の下に作成することにします。
npm run browser-sync:start
コマンドを実行してみます。
特にエラーは出ずに起動しているようです。http://localhost:3001 にアクセスすると browser-sync の ui が表示されました。
npm run browser-sync:start
コマンドを実行したコマンドプロンプトで Ctrl+C を押して終了すると、ブラウザに以下の画面が表示されました。サーバと同期して動いているようです。
問題なさそうですので、次へ進みます。
webpack + browser-sync 起動用の npm-scripts を作成する
package.json の scripts に以下の記述を追加します。
"scripts": { .........., "webpack": "webpack", "webpack:watch": "webpack --watch", "browser-sync": "browser-sync", "browser-sync:start": "browser-sync start --config bs-config.js", "server": "run-p webpack:watch browser-sync:start" },
"webpack:watch": "webpack --watch"
を追加します。"server": "run-p webpack:watch browser-sync:start"
を追加します。
npm run server
コマンドで webpack と browser-sync が起動して、ファイルが変更されるとブラウザに自動反映されるようにします。
動作確認する
static の下に以下の内容の sample.html を作成します。
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> テスト用ページです。<br/> <span id="sample">xxx</span> <script src="/js/app.js"></script> </body> </html>
src/main/assets/js/app.js を以下の内容に変更します。
var $ = require("admin-lte/plugins/jQuery/jquery-2.2.3.min.js"); $(document).ready(function() { $("#sample").text("サンプル"); });
npm run server
コマンドを実行します。
ブラウザが起動しますので、http://localhost:9080/sample.html にアクセスしてみます。
sample.html に記述した文字列が表示されており、また app.js に記述した処理も反映されていました。
sample.html を以下の内容に変更してみます。
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> サンプルですよ?<br/> <span id="sample">xxx</span> <script src="/js/app.js"></script> </body> </html>
ブラウザを見るとリロードすることなく反映されています。
今度は app.js を以下の内容に修正してみます。
var $ = require("admin-lte/plugins/jQuery/jquery-2.2.3.min.js"); $(document).ready(function() { $("#sample").text("app.js を修正してみました"); });
webpack の処理が実行されて src/main/resources/static/js/app.js が作り直されて、
ブラウザの方に手動でリロードすることなく反映されました。
他にも browser-sync はこんなことができるようです。
複数のブラウザ(下の画像では IE と Chrome)で同じページを見ている時に、ファイルが変更されると全てのブラウザに手動リロードすることなく反映されます。
複数のブラウザで同じフォームを見ている時に、片方のブラウザ(IE)に入力すると、自動で別のブラウザ(Chrome)にも入力されます。
sample2.html を作成します。その後で sample.html には sample.html → sample2.html へ遷移するリンクを、sample2.html には sample2.html → sample.html へ遷移するリンクを記述してから IE と Chrome で sample.html を表示した後
IE の方のリンクをクリックして sample2.html へ遷移すると、Chrome の方でも sample2.html へ遷移します。
browser-sync ってすごい面白い! まさか、こんな便利なソフトがあるとは。
他にも browser-sync には proxy の機能もあるようで、Spring Boot の Tomcat と連携して自動リロードもできるのでしょうか。。。? 入力フォームができたら試してみたいと思います。
Ctrl+C を押して webpack と browser-sync を停止します。今回作成した sample.html, sample2.html は commit せずに削除します。
最後に package.json, webpack.config.js, bs-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", "webpack": "webpack", "webpack:watch": "webpack --watch", "browser-sync": "browser-sync", "browser-sync:start": "browser-sync start --config bs-config.js", "server": "run-p webpack:watch browser-sync:start" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "admin-lte": "^2.3.11", "bootstrap": "^3.3.7", "font-awesome": "^4.7.0", "ionicons": "^3.0.0" }, "devDependencies": { "browser-sync": "^2.18.13", "cpx": "^1.5.0", "npm-run-all": "^4.0.2", "rimraf": "^2.6.1", "webpack": "^3.3.0" } }
webpack.config.js
module.exports = { entry: { "js/app": ["./src/main/assets/js/app.js"] }, output: { path: __dirname + "/src/main/resources/static", publicPath: "/", filename: "[name].js" } };
bs-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": [ "./static/**/*", "./src/main/resources/static/**/*" ], "watchEvents": [ "change" ], "watchOptions": { "ignoreInitial": true }, "server": { "baseDir": [ "./static", "./src/main/resources/static" ] }, "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": 5000 } }, "tagNames": { "less": "link", "scss": "link", "css": "link", "jpg": "img", "jpeg": "img", "png": "img", "svg": "img", "gif": "img", "js": "script" } };
履歴
2017/07/24
初版発行。