【gulp】「gulp-htmlhint」でHTMLの文法をチェックする方法をメモメモ
みなさま、こんにちは。hulu で「めぞん一刻」を見て、最終回でボロ泣きした kouraku です。記憶に残る思い出深い作品だったということと、大人になり結婚した今だからこそ分かる想いなんかが色々と重なって(単純に涙もろくなってきた、というのもありますが(苦笑))、最後の最後でどっと感情が溢れ出てしまった、といった感じでしょうか。いや~、名作はいつ見ても感動を与えてくれるものですよね。
さて今回は、前回までにご紹介したHTMLテンプレート「gulp-html-extend」で出力したコードに誤りがないか、例えば閉じタグが無い・・・とか、imgタグにalt属性が無い・・・とか、そんなものをチェックサイトにコピペして確認とか面倒なので、gulpにある程度任せてみたいと思います。そこで、白羽の矢が立ったのが「gulp-htmlhint」ですね。では、このプラグインの使い方についてメモメモ。
※前回までの記事を元に進めていきます。
前回のやり残しを先に・・・
では早速、「gulp-htmlhint」をインストール・・・と行きたいところですが、前回までの「gulp-html-extend」について1点やり残していたことがありましたので、先に対応したいと思います。
毎回毎回コンパイルするのに「gulp html-extend」とコマンドを叩くのも面倒なので、サクッと watch に追加しましょう。src の中の extend 配下にある htmlファイルに更新が入ったら、'html-extend' を実行させます。
[gulptasks/watch.coffee]
:
# ファイル監視
gulp.task 'watch', ->
gulp.watch [
config.paths.pub+'**/*.js'
config.paths.pub+'**/*.html'
config.paths.pub+'**/*.css'
],['reload']
gulp.watch [ ← 追加
config.paths.src+'extend/**/*.html'
],['html-extend']
return ← 位置移動
監視するのは1つですが、コピペが楽なので体裁そのままにしてます(笑)。
あと、gulpコマンド実行時に 'html-extend' が動くように設定しておきます。
[gulpfile.coffee]
:
gulp.task 'default', [
'browser-sync'
'html-extend' ← 追加
'watch'
]
はい、これで前回のやり残し対応は終わりです。
「gulp-htmlhint」の導入
さて、それでは前回までの件で思い残したことも無くなったので、文法をチェックするための仕組みをgulpへ導入したいと思います。動きとしては、
- htmlファイルに更新が入ったら文法チェック開始。
- エラーを起こしても止まらない様に設定。
- 同じエラーは、そのファイルに更新が入らない、もしくは gulp を再起動しない限り、1度だけの表示とする。
- ターミナル等がウィンドウの裏に隠れているとエラーが見えなくなるので、デスクトップに通知する。
といった内容を実現させたいと思います。
では、次のコマンドを叩いて html の文法チェックプラグイン「gulp-htmlhint」をインストールします。
$ npm install gulp-htmlhint --save-dev
プラグインのインストールが完了したら、次はタスクを作成します。gulptasks配下に以下のコードを入力したファイルを作成します。
[gulptasks/htmlhint.coffee]
gulp = require 'gulp'
plugins = prop.plugins
config = prop.config
# htmlhint
module.exports = do ->
gulp.task 'htmlhint', ->
gulp
.src [
config.paths.pub+'**/*.html'
]
.pipe plugins.plumber()
.pipe plugins.htmlhint()
.pipe plugins.htmlhint.failReporter()
はい、これで基本的な htmlhint のタスクは出来上がりました。
では次に、このタスクをhtmlファイルが更新されたら実行されるように、watch に追加しましょう。
[gulptasks/watch.coffee]
:
gulp.watch [
config.paths.src+'extend/**/*.html'
],['html-extend']
gulp.watch [ ← 追加
config.paths.pub+'**/*.html'
],['htmlhint']
return ← 位置移動
これで htmlhint を使う準備が整いました。それでは早速 gulp を起動しましょう。
$ gulp
すると・・・
う・・・おっと、いきなりエラー文がドドドっと出てきましたね。でも、よく見ると・・・index.html、index2.html、index3.html の3ファイルについて同じことを3回ずつ(計9回)言っているようです。
それにしても、何故9回もエラー文が出てくるのでしょうか?先ほどの watch に追加した内容を確認しますと・・・
config.paths.pub+'**/*.html'
と、htdocs配下の htmlファイルに変更が入る度に 'htmlhint' が動くようになっています。つまり、index.html、index2.html、index3.htmlの3ファイルが出力され、それぞれ毎に htdocs内の全HTMLファイルをチェックしているわけですね。3ファイルにエラーが存在 × 3ファイル出力 = 9回エラーが呼ばれている、というわけです。
仕組み上仕方ないとは言え、毎回こんな感じで同じエラーが何度も呼ばれるのは、ログも見辛いし嫌ですよね。ということで、実現したい動き3つ目「同じエラーは、そのファイルに更新が入らない、もしくは gulp を再起動しない限り、1度だけの表示とする。」をタスクに組み込みます。
「gulp-cached」を導入する
一度基点を流れたものは一時的にメモリに保存され、次からの処理は変更がない限り基点より下に回さない、そんな働きをするプラグインが「gulp-cached」です。使い方次第ではとても便利ですよね。
では、次のコマンドを叩いてインストールします。
$ npm install gulp-cached --save-dev
プラグインのインストールが完了したら、早速 htmlhint タスクに組み込みます。
[gulptasks/htmlhint.coffee]
:
gulp.task 'htmlhint', ->
gulp
.src [
config.paths.pub+'**/*.html'
]
.pipe plugins.plumber()
.pipe plugins.cached('htmlhint_log') ← 追加
.pipe plugins.htmlhint()
.pipe plugins.htmlhint.failReporter()
これで更新時に1回だけ表示されるようになると思います。試しに gulp を起動してみます。
はい、ちゃんと index.html、index2.html、index3.htlm それぞれ1回ずつエラーが表示されるようになりました。(出ない場合は、適当に htmlファイルを保存してください)
続いて、適当にどこかの htmlファイルを保存をすると・・・
はい、1度表示されたエラーは流れなくなりましたね(「gulp-cached」を入れる前は9回表示されます)。
「gulp-notify」を導入する
最後に実現したい動きとして、4点目「ターミナル等がウィンドウの裏に隠れているとエラーが見えなくなるので、デスクトップに通知する。 」です。これは「gulp-notify」というプラグインを使用することで実現できます。
では、早速プラグインをインストールします。
$ npm install gulp-notify --save-dev
プラグインのインストールが完了したら、htmlhint タスクに組み込みます。
[gulptasks/htmlhint.coffee]
:
gulp.task 'htmlhint', ->
gulp
.src [
config.paths.pub+'**/*.html'
]
.pipe plugins.plumber ←変更
errorHandler: plugins.notify.onError 'Error: <%= error.message %>' ← 追加
.pipe plugins.cached('htmlhint_log')
.pipe plugins.htmlhint()
.pipe plugins.htmlhint.failReporter()
追加が終わったら、gulpを再起動します。エラーが表示された後、デスクトップにバルーンで通知されることが確認できます。
はい、これで HTMLの文法チェックタスクが完成しました。
文法チェックルールをカスタマイズ
しかし、これだけでは一体どんなチェックが行われているのか分かりません。むしろ案件に合わせたチェックを行いたい、と思うのが常です。
となると、HTMLHintの公式に書かれているルールを自分の手で設定できるようにすれば、とても便利になりますよね。
はい、ちゃんとこのルールを設定することができるんです。json形式で設定ファイルを作成して、それを読み込ませるように指定してあげればOKです。
では例として、基本はデフォルトを使用して、imgタグの中に alt 属性が無い場合にエラーを出すようにしてみましょう。ここでは htmlhint の jsonファイルだということが分かりやすい様に、拡張子も付けておきます。
※オプションの設定内容についてはhtmlhintの公式をご確認ください。
[htmlhintrc.json]
{
"alt-require": true
}
次に、htmlhint タスクで外部に用意したオプションファイルを読み込ませる変更をします。
[gulptasks/htmlhint.coffee]
:
gulp.task 'htmlhint', ->
gulp
.src [
config.paths.pub+'**/*.html'
]
.pipe plugins.plumber
errorHandler: plugins.notify.onError 'Error: <%= error.message %>'
.pipe plugins.cached('htmlhint_log')
.pipe plugins.htmlhint('htmlhintrc.json') ← 変更
.pipe plugins.htmlhint.failReporter()
はい、これで新たなルールを追加することができました。では、gulpを再起動して htmlファイルにわざとエラーが出るようにコードを追加してみます。
[src/extend/modules/index.html]
:
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Placeat, vel eveniet nemo repudiandae dolore consequatur similique dicta voluptates accusamus laboriosam earum sed itaque ex aliquam unde minima illo et obcaecati?</p>
<img src="test.jpg"> ← altを指定しないまま保存
<!-- @@close -->
上記の状態で保存すると・・・
alt属性は必須ですよ!というエラーメッセージが表示されました。成功ですね。
今回のサンプルデータまとめ
タグの閉じ忘れとかは、どんなにベテランになっても起こしてしまうものです。そんなエラーを裏で機械的に管理して、分かりやすく報告してもらえると安心ですよね。また、id や class のネーミングルール(一定のパターンになりますが)とかも監視させることができるので、自社のルールに合わせて設定ファイルを作成・・・なんて使い方もできると思います。HTMLテンプレートを使わない場合でも活躍するプラグインなので、ぜひ皆さん活用しましょう!
さてと、この後は嫁が見ていない序盤の話をもう一度見ることにします(嫁は20話くらいからの途中参戦だったので)。面白い話は何度見ても楽しめるし、何度見ても笑えますね。今週もまた「めぞん一刻」に染まります!