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


きっかけ

  • 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://qiita.com/bonsai3/items/c33dfc902aed41899708

事前準備

  • ディレクトリ構成
/
├ html(php→html変換先、そしてValidate対象)
├ root(変換されるphp置き場)
  └ index.php
├ .htmlhintrc
├ package.json
└ gulpfile.js
  • package.json
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
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つ重ねています。

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