gulp-htmlhintを使ってHTMLのバリデーションを行ってみます。
設定方法
プロジェクトディレクトリに移動して、package.jsonを作成します。
npm init
使用するパッケージをインストールします。
npm install gulp gulp-htmlhint --save-dev
プロジェクトルートにgulpfile.jsを作成して、以下のように記述します。
gulpfile.js
var gulp = require('gulp'), htmlhint = require('gulp-htmlhint'); gulp.task('html', function() { return gulp.src('htdocs/**/*.html') .pipe(htmlhint()) .pipe(htmlhint.reporter()); });
htdocsディレクトリを作成して、その中にindex.htmlを作成します。
htdocs/index.html
<!DOCTYPE html> <html lang="ja"> <head> </head> <body> <DIV class="sample-box"> <img class="sample-box_img" src="image.png"> <p class="sample-box_text">テストです。</p> </DIV> </body> </html>
タスクを実行します。
gulp html
一部変更していますが、以下のようにエラーが表示されました。
[HH:MM:SS] 6 errors found in /XXXXXX/htdocs/index.html [HH:MM:SS] [L4:C1] <title> must be present in <head> tag. (title-require) [HH:MM:SS] </head> [HH:MM:SS] [L6:C1] The html element name of [ DIV ] must be in lowercase. (tagname-lowercase) [HH:MM:SS] <DIV class="sample-box"> [HH:MM:SS] [L7:C7] An alt attribute must be present on <img> elements. (alt-require) [HH:MM:SS] <img class="sample-box_img" src="image.png"> [HH:MM:SS] [L7:C7] The id and class attribute values must be in lowercase and split by a dash. (id-class-value) [HH:MM:SS] <img class="sample-box_img" src="image.png"> [HH:MM:SS] [L8:C5] The id and class attribute values must be in lowercase and split by a dash. (id-class-value) [HH:MM:SS] <p class="sample-box_text">テストです。</p> [HH:MM:SS] [L9:C1] The html element name of [ DIV ] must be in lowercase. (tagname-lowercase) [HH:MM:SS] </DIV>
今回の例では以下の部分でエラーが出ています。
- titleタグがない(2行目)
- タグ名が大文字(4,12行目)
- imgタグにaltがない(6行目)
- class名の単語の区切りに「-」以外が使われている(8,10行目)
エラーの出ている部分を一部修正してみます。
htdocs/index.html
<!DOCTYPE html> <html lang="ja"> <head> <title>タイトル</title> </head> <body> <div class="sample-box"> <img class="sample-box_img" src="image.png" alt=""> <p class="sample-box_text">テストです。</p> </div> </body> </html>
再度タスクを実行します。
gulp html
対応を行った部分はエラーが表示されなくなりました。
[HH:MM:SS] 2 errors found in /XXXXXX/htdocs/index.html [HH:MM:SS] [L8:C7] The id and class attribute values must be in lowercase and split by a dash. (id-class-value) [HH:MM:SS] <img class="sample-box_img" src="image.png" alt=""> [HH:MM:SS] [L9:C5] The id and class attribute values must be in lowercase and split by a dash. (id-class-value) [HH:MM:SS] <p class="sample-box_text">テストです。</p>
ルールの変更
先ほどの例ではclass名の単語の区切りに「-」以外が使われているとエラーになっていましたが、こういったルールを変更することもできます。
以下コードの7〜29行目が設定できる項目とその初期値になります。
gulpfile.js
var gulp = require('gulp'), htmlhint = require('gulp-htmlhint'); gulp.task('html', function() { return gulp.src('htdocs/**/*.html') .pipe(htmlhint({ "tagname-lowercase": true, "attr-lowercase": true, "attr-value-double-quotes": true, "attr-value-not-empty": false, "attr-no-duplication": true "doctype-first": true, "tag-pair": true, "empty-tag-not-self-closed": true, "spec-char-escape": true, "id-unique": true, "src-not-empty": true, "title-require": true, "alt-require": true, "doctype-html5": true, "id-class-value": "dash", "style-disabled": false, "inline-style-disabled": false, "inline-script-disabled": false, "space-tab-mixed-disabled": "space", "id-class-ad-disabled": false, "href-abs-or-rel": false, "attr-unsafe-chars": true, "head-script-disabled": true })) .pipe(htmlhint.reporter()); });
それぞれのエラー内容は以下の通りです。
tagname-lowercase | タグ名が小文字かどうか。 初期値はtrue。 |
---|---|
attr-lowercase | 属性名が小文字かどうか。 初期値はtrue。 |
attr-value-double-quotes | 属性値がダブルクォーテーションで囲われているかどうか。 初期値はtrue。 |
attr-value-not-empty | 属性値が空でないかどうか。 初期値はfalse。 |
attr-no-duplication | 属性が重複していないかどうか。 初期値はtrue。 |
doctype-first | DOCTYPEが先頭にあるかどうか。 初期値はtrue。 |
tag-pair | タグのペアが揃っているかどうか。 初期値はtrue。 |
empty-tag-not-self-closed | 空要素の終端のスラッシュを省略しているかどうか。 初期値はtrue。 |
spec-char-escape | 特殊文字がエスケープされているかどうか。 初期値はtrue。 |
id-unique | IDがユニークかどうか。 初期値はtrue。 |
src-not-empty | srcが空でないかどうか。 初期値はtrue。 |
title-require | titleタグがあるかどうか。 初期値はtrue。 |
alt-require | altがあるかどうか。 初期値はtrue。 |
doctype-html5 | DOCTYPEがHTML5かどうか。 初期値はtrue。 |
id-class-value | IDやclass名の単語の区切りを指定。 初期値はdashで、dash(-) / underline(_) / hump(キャメルケース) / falseから選択。 |
style-disabled | styleタグを使っていないかどうか。 初期値はfalse。 |
inline-style-disabled | インラインスタイルを使っていないかどうか。 初期値はfalse。 |
inline-script-disabled | インラインスクリプトを使っていないかどうか。 初期値はfalse。 |
space-tab-mixed-disabled | インデントがタブかスペースか。 初期値はspaceで、space / tabから選択。。 |
id-class-ad-disabled | IDやclassに広告キーワードを使っていないかどうか。 初期値はfalse。 |
href-abs-or-rel | リンク先が絶対パスか相対パスかを指定。 初期値はfalseで、false / abs(絶対パス) / rel(相対パス)から選択。 |
attr-unsafe-chars | 属性値に安全でない文字を使用していないかどうか。 初期値はtrue。 |
head-script-disabled | head内にscriptタグを埋め込んでいないかどうか。 初期値はtrue。 |
先ほどの例の場合、21行目の”id-class-value”で”dash”が設定されているためエラーになります。
class名の単語の区切りでは特にエラーを出したくないので、falseを設定してみます。
var gulp = require('gulp'), htmlhint = require('gulp-htmlhint'); gulp.task('html', function() { return gulp.src('htdocs/**/*.html') .pipe(htmlhint({ "id-class-value": false })) .pipe(htmlhint.reporter()); });
タスクを再度実行してみます。
gulp html
これで先ほどの例でエラーが表示されなくなりました。
どのルールを使用するかは案件によって多少変わりますが、個人的には以下の設定をベースにしようと思います。
var gulp = require('gulp'), htmlhint = require('gulp-htmlhint'); gulp.task('html', function() { return gulp.src('htdocs/**/*.html') .pipe(htmlhint({ "tagname-lowercase": true, "attr-lowercase": true, "attr-value-double-quotes": false, "attr-value-not-empty": false, "attr-no-duplication": true, "doctype-first": true, "tag-pair": true, "empty-tag-not-self-closed": true, "spec-char-escape": true, "id-unique": true, "src-not-empty": true, "title-require": true, "alt-require": true, "doctype-html5": true, "id-class-value": false, "style-disabled": false, "inline-style-disabled": false, "inline-script-disabled": false, "space-tab-mixed-disabled": "space", "id-class-ad-disabled": false, "href-abs-or-rel": false, "attr-unsafe-chars": true, "head-script-disabled": false })) .pipe(htmlhint.reporter()); });
data属性でシングルクォーテーションを使うことがあるので”attr-value-double-quotes”をfalseに、class名の単語の区切りでエラーを出したくないので”id-class-value”をfalseに、head内にscriptタグを埋め込むことがあるので”head-script-disabled”をfalseにしています。
【参考サイト】
コメントが承認されるまで時間がかかります。