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にしています。
【参考サイト】
コメントが承認されるまで時間がかかります。