🍀

gulpでphpをhtmlに変換してValidateする。 [gulp-htmlhint]と[gulp-w3cjs]

2020/09/27に公開

きっかけ

  • WebサイトのHTMLを.phpでコーディングしている。
  • gulpでHTMLのValidateをどうしてもしたい。
  • gulpでHTMLをValidateするプラグインはいくつかある。
  • .phpファイルをそのままValidateプラグインに通すと、php部分も判定対象になるので「構文エラーです」となってしまい使えない。
  • gulpでphp→htmlに変換して、そのhtmlをValidateすればいいのでは?

できました!

このプラグインを使います

gulp-htmlhint
https://www.npmjs.com/package/gulp-htmlhint
gulp-w3cjs
https://www.npmjs.com/package/gulp-w3cjs

使うのはひとつでいいのですが重ね掛けしています。
理由は後述してあります。

php → htmlに変換するには・・

こちらをご覧ください

gulpでphpをhtmlに変換する [gulp-php2html]
https://zenn.dev/bonsai3/articles/e0eee5a62ccc5839d4a7

事前準備

ディレクトリ構成

/
├ html(php→html変換先、そしてValidate対象)
├ root(変換されるphp置き場)
  └ index.php
├ .htmlhintrc
├ package.json
└ gulpfile.js

package.json

{
    "name": "dev",
    "version": "1.0.0",
    "author": "",
    "main": "gulpfile.js",
    "license": "ISC",
    "devDependencies": {
        "gulp": "^3.9.1",
        "gulp-htmlhint": "^2.2.1",
        "gulp-php2html": "^0.3.2",
        "gulp-plumber": "^1.2.1",
        "gulp-w3cjs": "^1.3.1"
    }
}

gulpfile.js

// 環境変数
const setting = {
	html: {
		src: "./root/*.php",
		dest: "./html"
	}
};

const gulp = require("gulp");

// プラグインの読み込み
const php2html = require("gulp-php2html");
const htmlhint = require("gulp-htmlhint");
const plumber = require("gulp-plumber");
const w3cjs = require("gulp-w3cjs");

// phpからhtmlに変換するタスクを作成
gulp.task("html", () => {
	return (
		gulp
			// 変換対象のファイル
			.src(setting.html.src)
			// php→html変換
			.pipe(php2html())
			// htmlを保存
			.pipe(gulp.dest(setting.html.dest))
	);
});

// htmlをValidateするタスクを作成
// 「html」を実行してから、この「Validate」タスクを実行する
gulp.task("validate", ["html"], () => {
	return (
		gulp
			// Validate対象のファイル
			.src(setting.html.dest + "/**/*.html")
			// エラー発生時にgulpが強制停止するのを防止
			.pipe(plumber())
			// Validateする
			.pipe(htmlhint(".htmlhintrc"))
			// 追加でValidateする
			.pipe(w3cjs())
			// Validate結果をコマンドラインに表示
			.pipe(htmlhint.failReporter())
	);
});

// ファイルの変更を監視してタスク実行
gulp.task("watch", () => {
	gulp.watch(setting.html.src, ["validate"]);
});

// gulp起動時に実行するタスク
gulp.task("default", ["watch"]);

.htmlhintrc

htmlhintの公式のオプション設定情報です
https://github.com/htmlhint/HTMLHint/wiki/Rules

こちらを参考にして外部ファイル「.htmlhintrc」を作成しました。
今回の設定はこちら↓

{
	"tagname-lowercase": true,
	"attr-lowercase": false,
	"attr-value-double-quotes": true,
	"attr-value-not-empty": false,
	"attr-no-duplication": true,
	"doctype-first": false,
	"tag-pair": true,
	"tag-self-close": false,
	"spec-char-escape": true,
	"id-unique": false,
	"src-not-empty": false,
	"title-require": true,
	"head-script-disabled": false,
	"doctype-html5": true,
	"id-class-value": false,
	"style": true,
	"inline-style-disabled": true,
	"inline-script-disabled": false,
	"space-tab-mixed-disabled": "tab",
	"id-class-ad-disabled": false,
	"href-abs-or-rel": false,
	"attr-unsafe-chars": false,
	"alt-require": true
}

これをValidate時に読み込ませています。

 // Validateする
.pipe(htmlhint(".htmlhintrc"))

ポイント

タスク「html」を実行してから「validate」を実行しています。

この部分です

gulp.task("validate", ["html"], () => {

インストール

# package.jsonの内容をもとに、gulpとプラグインをインストール
$ npm install

gulpを実行(起動)します

$ gulp
[12:19:45] Using gulpfile (ディレクトリパス)/gulpfile.js
[12:19:45] Starting 'watch'...
[12:19:45] Finished 'watch' after 9.34 ms
[12:19:45] Starting 'default'...
[12:19:45] Finished 'default' after 69

結果

Validateしてみました

その1

HTMLタグを間違ってみます

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>test</title>
</head>
<body>

<h1>タイトル</h2>

</body>
</html>

<h1>の閉じタグを</h2>にしました

[11:16:07] Starting 'html'...
[11:16:07] Finished 'html' after 191 ms
[11:16:07] Starting 'validate'...
[11:16:07] HTML Error: index.html Line 9, Column 13: End tag “h2” seen, but there were open elements.
[11:16:07] <h1>タイトル</h2>
[11:16:07] 'validate' errored after 598 ms
[11:16:07] Error in plugin "gulp-htmlhint"
Message:
    2 errors found in C:(ディレクトリパス)\html\index.html
[L9:C9] Tag must be paired, no start tag: [ </h2> ] (tag-pair)
[L11:C1] Tag must be paired, missing: [ </h1> ], start tag match failed [ <h1> ] on line 9. (tag-pair)

無事にエラーがでました。ちゃんと怒ってくれました。
Validateされているようです。

プラグイン「gulp-htmlhint」と「gulp-w3cjs」の両方の結果が表示されます。
どれがどちらのプラグインのエラー表示かよくわからなくなりますが、
利用時にはどうでもよくなります。

「あぁ、なんかエラー出ているな。どこか間違ったな」に気が付ければOKです。

その2

次はこちらです。

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>test</title>
</head>
<body>

<ul>
	<li></li>
	<div></div>
</ul>

</body>
</html>

<ul>の中に<div>が入っています。

[11:20:27] HTML Error: index.html Line 11, Column 6: Element “div” not allowed as child of element “ul” in this context. (Suppressing further errors from this subtree.)
[11:20:27]      <div></div>
[11:20:27] Finished 'validate' after 652 ms

エラーが出ます。
gulp-htmlhintはこの記述を許容したようですが
gulp-w3cjsは怒りました。

「.htmlhintrc」のValidateルール設定が悪いのかもしれませんが・・

逆に
gulp-htmlhintは怒ったけど
gulp-w3cjsは許容した
というパターンもあった(ような思い出がある)ので

ダブルチェックということでValidateプラグインを2つ重ねています。

以上です。
ありがとうございました。

Discussion