PugやEJSなどのHTMLプリプロセッサはとても便利だが、出力後のHTMLファイルはインデントや改行などが汚いので、そのまま客先に納品するのがはばかられる。そこで、js-beautifyというパッケージを使ってインデントや空白をバッチで除去できるスクリプトを作成した。
js-beautifyのインストール
npm install --save-dev js-beautify
js-beautifyのオプション
オプション一覧
CLIオプション
オプション | 説明 |
---|---|
-f, --file | 入力ファイルのパス。('-'を渡すと標準入力を使用) |
-r, --replace | 整形後の出力を直接入力ファイルに上書く |
-o, --outfile | 出力ファイルのパス (デフォルトは標準出力) |
--config | 設定ファイルのパス |
--type | 動作モードの指定 [js|css|html] |
-q, --quiet | 標準出力へのログ出力を抑制 |
-h, --help | ヘルプを表示 |
-v, --version | バージョンを表示 |
HTML用整形オプション
オプション | 説明 |
---|---|
-s, --indent-size | インデントサイズ [4] |
-c, --indent-char | インデントに使用する文字 [" "] |
-t, --indent-with-tabs | インデントにタブを使う。 -s と -c を上書く |
-e, --eol | 改行として使用する文字 (デフォルトは"\n") |
-n, --end-with-newline | 出力の最後に改行を出力する |
-l, --indent-level | インデントの初期サイズ [0] |
-p, --preserve-newlines | 改行を維持する (--no-preserve-newlines disables) |
-m, --max-preserve-newlines | 許容する連続改行数 [10] |
-I, --indent-inner-html |
<head>``<body> 要素をインデントする。デフォルトはfalse |
-b, --brace-style | [collapse|expand|end-expand|none] [,preserve-inline] [collapse,preserve-inline] |
-S, --indent-scripts | [keep|separate|normal] ["normal"] |
-w, --wrap-line-length | 行に含まれる文字数がこの数を越えたら改行を挿入する [250] |
-A, --wrap-attributes | 属性を改行するかどうか [auto|force|force-aligned|force-expand-multiline] ["auto"] |
-i, --wrap-attributes-indent-size | この属性値がこの文字数を越えたときに改行する [indent-size] (wrap-attributesが"force-aligned"のときは無視する) |
-U, --unformatted | リフォーマットを適用しない要素のリスト(デフォルトはinline) |
-T, --content_unformatted | コンテンツにリフォーマットを適用しない要素のリスト(デフォルトはpre) |
-E, --extra_liners | 終了タグの後に空白行を挿入する要素のリスト(デフォルトはbody,head,/html) |
--editorconfig | EditorConfigを設定として使用する |
js-beautifyの実行
デフォルト設定のままでもそこそこ綺麗になるが、以下の点が気に入らなかったので設定に反映。
- 改行が連続していてもそのまま保持される
- ⇒
preserve-new-lines
とmax_preserve_newlines
をそれぞれ無効に
- ⇒
-
<a>``<span>``<svg>
などのタグが整形されない- ⇒
unformatted
オプションを絞る
- ⇒
- 属性が長いと改行されてしまう
- ⇒
wrap-attributes
を無効に
- ⇒
JavaScript版
-
targetDirs
配列内のディレクトリ直下から、拡張子が.html
のファイルを走査して整形
beautify.js
const fs = require('fs');
const beautify = require('js-beautify');
// HTMLファイルを検索するディレクトリ
const targetDirs = ['./dist/', './dist/subdir/'];
// 整形オプション
// https://www.npmjs.com/package/js-beautify
const beautifyOptions = {
indent_size: 2,
end_with_newline: true,
preserve_newlines: false,
max_preserve_newlines: 0,
wrap_line_length: 0,
wrap_attributes_indent_size: 0,
unformatted: ['b', 'em']
};
targetDirs.forEach(targetDir => {
fs.readdir(targetDir, (err, files) => {
if (err) console.log(err);
if (err) return;
const htmls = files.filter(name => {
return name.match(/\.html$/);
});
htmls.forEach(file => {
fs.readFile(targetDir + file, 'utf8', (err, html) => {
if (err) console.log(err);
if (err) return;
const result = beautify.html(html, beautifyOptions);
fs.writeFile(targetDir + file, result, 'utf8', err => {
if (err) console.log(err);
});
});
});
});
});
シェルから実行
node ./beautify.js
シェルスクリプト版
- ローカルインストールの実行バイナリは
node_modules/.bin/
の中に作成されるので、それを使う -
$dirs
配列内のディレクトリ直下から、拡張子が.html
のファイルを走査して整形 -
*
を使うとファイルの一覧を取得できるので、それをfor
で回す
beautify.sh
#!/usr/bin/env bash
exe="node_modules/.bin/js-beautify"
# HTMLファイルを検索するディレクトリ
dirs=(\
"dist/" \
"dist/subdir/" \
)
function main() {
for dir in ${dirs[@]}
do
for entry in "$dir"*.html
do
$exe "$entry" -r --preserve-new-lines false --max-preserve-newlines 0 --wrap-line-length 0 --wrap-attributes-indent-size 0 --unformatted 'b em'
done
done
}
main
./beautify.sh