Spring Boot + npm + Geb で入力フォームを作ってテストする ( その11 )( PostCSS で common.css を minify する + autoprefixer, stylelint を導入する )
概要
記事一覧はこちらです。
Spring Boot + npm + Geb で入力フォームを作ってテストする ( その10 )( 各画面の HTML を作成する3 ) の続きです。
- 今回の手順で確認できるのは以下の内容です。
参照したサイト・書籍
Autoprefixer
https://github.com/postcss/autoprefixerBrowserslist
https://github.com/ai/browsersliststylelint
https://github.com/stylelint/stylelintstylelint-config-standard
https://github.com/stylelint/stylelint-config-standard‘at-rule-empty-line-before’ do not accept
except
+ignore
https://github.com/stylelint/stylelint/issues/691PostCSS まとめ
http://qiita.com/morishitter/items/4a04eb144abf49f41d7dSassを捨ててPostCSSに移行したのでそのときの工程メモ
http://qiita.com/nabeliwo/items/0aeea21e95f3fbab3955ここがすごいぞ! stylelint!
http://qiita.com/inuscript/items/ff4f6972c988afbec3a8PostCSSとstylelintの環境構築
http://qiita.com/buchiya4th/items/01b4ad050b7c59b48539
目次
- はじめに
- PostCSS と cssnano プラグインをインストールして minify してみる
- Autoprefixer プラグインを追加する
- stylelint プラグインを追加する
- 次回は。。。
手順
はじめに
作成している common.css を単にコピーするだけでなく圧縮(minify)もしたいと思い調べたところ、PostCSS を使えば出来るようなので、試してみます。
PostCSS ではいろいろなプラグインを組み合わせて使用しますが、今回は以下のプラグインを入れてみます。
- Autoprefixer(必要なベンダープリフィックスを自動で付与する)
- cssnano(minify)
- stylelint(CSSリンター)
PostCSS と cssnano プラグインをインストールして minify してみる
PostCSS をインストールする
npm install --save-dev postcss-cli
コマンドを実行してインストールします。
cssnano プラグインをインストールする
npm install --save-dev cssnano
コマンドを実行してインストールします。
postcss.config.js を作成する
プロジェクトのルートディレクトリに postcss.config.js を新規作成し、以下の内容を記述します。
module.exports = { plugins: [ require('cssnano')({ preset: 'default' }) ] };
npm-scripts を追加する
package.json の scripts に以下の記述を追加します。
"scripts": { .......... "copy:css:watch": "cpx src/main/assets/css/**/* src/main/resources/static/css -w", "postcss:watch": "postcss src/main/assets/css/**/* -d src/main/resources/static/css -x .min.css -w --poll", "server": "run-p copy:css:watch webpack:watch browser-sync:start" },
"postcss:watch": "postcss src/main/assets/css/**/* -d src/main/resources/static/css -x .min.css -w --poll"
を追加します。-w
オプションだけだとなぜかうまく watch してくれない(数回変更を検知するとそれ以降検知しなくなる時がある)ので、--poll
オプションも追加しました。
※この後の動作確認の時はまだ--poll
オプションは付けていません。うまく動かない時があることに気付いて後から付けています。- postcss を実行した同じディレクトリに postcss.config.js があると自動で読み込んでくれるようなので
-c postcss.config.js
は付けません。
動作確認する
src/main/resources/static の下の css ディレクトリを削除します。
npm run postcss:watch
コマンドを実行します。
src/main/resources/static の下を見ると css/common.min.css が生成されており、
common.min.css を開くと minify されていました。
src/main/assets/css/common.css で background-color: ivory;
→ background-color: snow;
に変更すると、
再び Finished src\main\assets\css\common.css
のメッセージが出力されて、
src/main/resources/static/css/common.min.css に反映されます。
うまく動作しているようです。ただし、以下1点注意があります。
- IntelliJ IDEA で src/main/assets/css/common.css を変更して、IntelliJ IDEA を Active な Window にしたまま src/main/resources/static/css/common.min.css を表示しても反映はされませんでした。一度 IntelliJ IDEA から他のプロセスに Active な Window を切り替えないと(マウスか Alt+Tab 等のキーで別の Window を Active にしないと)反映されませんでした。
npm-scripts を変更して正式に取り込む
package.json の scripts を以下のように変更します。
"scripts": { .......... "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", "server": "run-p postcss:watch webpack:watch browser-sync:start" },
"copy:css:watch": "cpx src/main/assets/css/**/* src/main/resources/static/css -w"
を削除します。"server"
内のcopy:css:watch
→postcss:watch
に変更します。"postcss:watch"
を記述する位置を"webpack"
の上に変更します。
動作確認する(その2)
今度は npm run server
コマンドを実行した後、browser-sync でブラウザに反映されるか確認します。
static/input01.html を以下のように変更します。
<head> .......... <!-- 画面共通で使用する css --> <link rel="stylesheet" href="/css/common.min.css"> </head>
- head タグ内の
<link rel="stylesheet" href="/css/common.css">
→<link rel="stylesheet" href="/css/common.min.css">
に変更します。
npm run server
コマンドを実行します。
ブラウザで http://localhost:9080/inquiry/input01.html にアクセスすると以下の画面が表示されます。
src/main/assets/css/common.css で background-color: snow;
→ background-color: white;
に変更すると、
postcss と browser-sync のメッセージが出力されて、
ブラウザに表示している入力画面1の背景色が white に変更されました。
問題なさそうです。
src/main/assets/css/common.css で background-color: ivory;
に戻した後、Ctrl+C を押して npm run server
コマンドを停止します。また static の下の input01.html 以外の html ファイルも <link rel="stylesheet" href="/css/common.min.css">
に変更します。
Autoprefixer プラグインを追加する
Autoprefixer プラグインをインストールする
npm install --save-dev autoprefixer
コマンドを実行してインストールします。
postcss.config.js を変更する
postcss.config.js に autoprefixer の設定を追加します。
module.exports = { plugins: [ require('autoprefixer')({ browsers: [ "last 2 versions" ] }), require('cssnano')({ preset: 'default' }) ] };
require('autoprefixer')({ ... })
を追加します。
動作確認する
npm run server
コマンドを実行します。src/main/resources/static/css/common.min.css は作り直されましたが、今のファイルだと何の prefix も追加されませんでした。
src/main/resources/static/css/common.min.css に a { display: flex; }
を追加してみます。
a { display: flex; } /* body 内の背景色を白より少し色がついた色にする */ .content-wrapper { background-color: ivory; } ..........
変更が検知されて、
src/main/resources/static/css/common.min.css を見ると vendor prefixes が自動で追加されていました。
stylelint プラグインを追加する
stylelint プラグインと stylelint-config-standard をインストールする
stylelint で適用するルールは stylelint-config-standard をそのまま使うことにします。npm install --save-dev stylelint stylelint-config-standard
コマンドを実行してインストールします。
postcss.config.js を変更する
postcss.config.js の以下の点を変更します。
module.exports = { plugins: [ require('stylelint'), require('autoprefixer')({ browsers: [ "last 2 versions" ] }), require('cssnano')({ preset: 'default' }) ] };
require('stylelint')
を追加します。記述された順序でプラグインが適用されるので、一番最初に stylelint を記述します。最初はアルファベット順に一番最後に記述したら common.min.css に対して stylelint が適用されて大量にメッセージが出力されました。。。
stylelint.config.js を作成する
プロジェクトのルートディレクトリの直下に stylelint.config.js を新規作成し、以下の内容を記述します。
module.exports = { extends: "stylelint-config-standard" }
動作確認する
npm run server
コマンドを実行します。
common.min.css 生成時に stylelint が実行されて以下の画像のように大量のメッセージが出力されました。動作しましたが、大した行数の CSS でもないのに結構メッセージが出ますね。。。
stylelint で出力されたメッセージに対応する
出力されたメッセージは以下の8種類でした。出力されたメッセージの説明は https://github.com/stylelint/stylelint/tree/master/lib/rules にあります。
Expected indentation of 2 spaces (indentation)
- インデントがスペース2個でないというメッセージでした。IntelliJ IDEA だとデフォルトではスペース4個に設定されているので、stylelint.config.js に
"indentation": 4
を追加して設定を変更します。
- インデントがスペース2個でないというメッセージでした。IntelliJ IDEA だとデフォルトではスペース4個に設定されているので、stylelint.config.js に
Expected empty line before comment (comment-empty-line-before)
- コメントの前に1行空行がないというメッセージでした。コメントの前に1行空行を追加します。
Expected a leading zero (number-leading-zero)
Unexpected unit (length-zero-no-unit)
- 値が 0 の時に
0px
のように単位を記述していたので出力されているメッセージでした。単位を削除して0px
→0
に変更します。
- 値が 0 の時に
Expected single space after ":" with a single-line declaration (declaration-colon-space-after)
- ここまでの修正でメッセージが出なくなったので対応しません。
Expected empty line before rule (rule-empty-line-before)
- 定義と定義の間に空行を入れていないというメッセージでした。空行を入れずに連続して記述したい場合があるので、stylelint.config.js に
"rule-empty-line-before": "never-multi-line"
を追加して設定を変更します。
- 定義と定義の間に空行を入れていないというメッセージでした。空行を入れずに連続して記述したい場合があるので、stylelint.config.js に
Expected indentation of 4 spaces (indentation)
- ここまでの修正でメッセージが出なくなったので対応しません。
Expected empty line before at-rule (at-rule-empty-line-before)
.label-required
を定義しているところで@media (min-width: 768px) { ... }
と@media (max-width: 767px) { ... }
の間に空行を入れていないというメッセージでした。ここに空行は入れたくないので、stylelint.config.js に"at-rule-empty-line-before": [ "always", {"except": ["after-same-name"]} ]
を追加して設定を変更します。
ここまで対応すると、追加で以下の3種類のメッセージが表示されました。
Expected empty line before comment (comment-empty-line-before)
/* ... */
のコメント行を空行を入れずに2行続けて書いていたために出ているメッセージでした。コメント行は連続で書けるようにしたいので、stylelint.config.js に"comment-empty-line-before": [ "always", {"ignore": ["after-comment"]} ]
を追加して設定を変更します。
Expected empty line before at-rule (at-rule-empty-line-before)
- コメント行の後に
@media (min-width: 768px) {
を記述しているところでメッセージが出ていました。上で追加した"at-rule-empty-line-before": [ ... ]
の中に"ignore": ["after-comment"]
を追加して、チェックされないようにします。
- コメント行の後に
Unexpected empty line before rule (rule-empty-line-before)
.form-group .float-label
の定義の前に空行が入っていたのでエラーが出ていました。ここは空行を取り除きます。
以上の対応で stylelint からメッセージが出ないようになりました。最終版の stylelint.config.js は以下のようになります。
module.exports = { extends: "stylelint-config-standard", rules: { "at-rule-empty-line-before": [ "always", { "except": ["after-same-name"], "ignore": ["after-comment"] } ], "comment-empty-line-before": [ "always", { "ignore": ["after-comment"] } ], "indentation": 4, "number-leading-zero": "never", "rule-empty-line-before": "never-multi-line" } };
次回は。。。
Controller クラスと Thymeleaf テンプレートファイルを作成する予定です。
ソースコード
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", "server": "run-p postcss:watch 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": { "autoprefixer": "^7.1.2", "browser-sync": "^2.18.13", "cpx": "^1.5.0", "cssnano": "^3.10.0", "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" } }
postcss.config.js
module.exports = { plugins: [ require('stylelint'), require('autoprefixer')({ browsers: [ "last 2 versions" ] }), require('cssnano')({ preset: 'default' }) ] };
stylelint.config.js
module.exports = { extends: "stylelint-config-standard", rules: { "at-rule-empty-line-before": [ "always", { "except": ["after-same-name"], "ignore": ["after-comment"] } ], "comment-empty-line-before": [ "always", { "ignore": ["after-comment"] } ], "indentation": 4, "number-leading-zero": "never", "rule-empty-line-before": "never-multi-line" } };
common.css
/* body 内の背景色を白より少し色がついた色にする */ .content-wrapper { background-color: ivory; } /* フォーカス時の入力フィールドの色合いが adminLTE より Bootstrap のものが好みなので、そちらに定義し直す */ .form-control:focus { border-color: #66afe9; outline: 0; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6); box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6); } /* form-control-static の文字列を入力項目のすぐ下に隙間をほとんど空けずに表示されるようにする */ .form-control-static { padding-top: 0; padding-bottom: 0; margin-bottom: -15px; } /* 入力チェックエラーの入力項目の背景色を薄い赤色にする */ .has-error .form-control { background-color: #fff5ee; } /* form-horizontal 内で form-control, form-control-static-inline の入力フィールドを横並びで表示する */ .form-control-inline { float: left; margin-right: 10px; } .form-control-static-inline { float: left; padding-top: 7px; margin-right: 10px; } /* checkbox の文字列の右側に少し隙間を空ける */ .checkbox label { margin-right: 10px; } /* 必須ラベル */ /* 767px 以下の場合には必須ラベルを右側に移動する */ @media (min-width: 768px) { .label-required { background-color: red; margin-right: 5px; } .form-group .float-label { float: right; } } @media (max-width: 767px) { .label-required { background-color: red; margin-left: 5px; } } /* 画面下のボタンを大きく表示させる */ .btn { width: 150px; }
履歴
2017/08/05 初版発行。