Prettier 3.0 と DOCTYPE と HTML の XML 配信(いわゆる XHTML 5)
7月5日に Prettier 3.0(prettier.io
)がリリースされました。メジャーバージョンアップということでいくつかの Breaking Changes があります。
当ブログでも HTML, CSS, JavaScript のフォーマッターとして Prettier を使っていますが、とくに影響があったのは以下の3点です。
- API
- Change public APIs to asynchronous(
prettier.io
) - JavaScript
-
Change the default value for
trailingComma
toall
(prettier.io
) - HTML
-
Print HTML5
doctype
in lowercase(prettier.io
)
API: Change public APIs to asynchronous
API の非同期化は単に await
を付けて対応完了。特筆するようなことはありません。
JavaScript: Change the default value for trailingComma
to all
JavaScript の trailingComma
の変更は、リリースノートにあるように IE への考慮が必要なくなったことによるものです。これまで当ブログでは ESLint の comma-dangle
(eslint.org
)を Prettier 側に合わせて functions
構文のみ never
にしていたのですが、すべて always-multiline
に変更しました。
'comma-dangle': [
'error',
{
arrays: 'always-multiline',
objects: 'always-multiline',
imports: 'always-multiline',
exports: 'always-multiline',
functions: 'never',
},
],
↓
'comma-dangle': ['error', 'always-multiline'],
HTML: Print HTML5 doctype
in lowercase
本記事でもっとも触れたいのは HTML の DOCTYPE についてです。Prettier 2 以前は <!DOCTYPE html>
のように DOCTYPE
部分が大文字になっていたものが、今回のバージョン 3 では <!doctype html>
と小文字に変換するよう変更されました。
DOCTYPE は HTML 仕様にあるように、DOCTYPE
と html
部分の大文字・小文字が区別されませんから、これは完全にプロジェクトルールや個人の好みで決めて良い話となります。極端な話、<DoCtYpE hTmL>
と書いても(見た目の気持ち悪さを除けば)問題はありません。
一方で歴史的経緯や XML との互換性も踏まえて、私は <!DOCTYPE html>
形式を好んで書いていました。いまや DOCTYPE はその文字列自身には意味のない、単なるレンダリングモード指定のための存在となっていますが、HTML4 以前は文書型宣言としての意味があり、とくに XHTML 文書においては大文字・小文字の区別が重要でした。
文書型宣言の html
は HTML 文書におけるルート要素すなわち <html>
要素の要素名を指します。なので要素名を大文字で書く習慣のあった時代は
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<HTML lang="ja">
のように、文書型宣言内の HTML
も大文字で書くのが自然なことでした。
XHTML 文書においては要素名は小文字で書かなければなりませんし、HTML と異なり文書型宣言の html
部分もルート要素と大文字・小文字を含めて一致していなければなりませんでしたから、結果として文書型宣言の html
も小文字にする必要がありました(must)。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja">
また、XHTML では DOCTYPE
を大文字で記述しなければならず、HTML を XML としても提供するための Polyglot Markupでもやはり DOCTYPE
を大文字で書くように推奨されていました。
- Polyglot Markup の W3C Note は2015年9月を最後に更新されておらず、現在はメンテナンスされていない文書となります。あくまで歴史的経緯の説明としてリンクを張っている次第です。
そういった経緯もあり、DOCTYPE
は大文字、html
は小文字とするのが個人的な肌感覚に合っていたのですが、一方で近年になり複数のプロジェクトで doctype
の小文字化が行われたという報告もあります。
Prettier 3.0 でも強制的に小文字に変換されることとなり、この挙動は無効にすることはできません。Pull Request のコメントでオプションを用意する要望があったものの明確に否定されているので、今後のアップデートで追加される望みも薄いでしょう。Prettier を使い続けるならば DOCTYPE
の小文字化を受け入れ、もしプロジェクトルールで言及があるならそこもアップデートする必要があるということになります。
ところで、現代の HTML Living Standard でも XML 構文を使用し、application/xhtml+xml
などの XML MIME タイプで配信することは可能です。
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja">
- 一時期は「XHTML 5」とも呼ばれていましたが、現在は「XHTML」の用語は使用されなくなりました。
XML MIME タイプで配信すればユーザーは XML として処理ができるため、例えば <table>
要素を多用したデーターベース的なコンテンツにおいては text/html
と比べてメリットになり得るケースもあるでしょう。レアケースだとは思いますが、こういう場合に Prettier 3.0 を導入すると doctype
が小文字に変換され、これは XML としての整形式になりませんから、コンテンツがまったく閲覧できなくなってしまうことになります。
ただし、XHTML 1.0 や XHTML 1.1 時代に作られた (X)HTML を壊さないようにするためか、Prettier 3.0 による doctype
の強制変換は <!DOCTYPE html>
のような短い DOCTYPE の場合にのみ行われるようです。
HTML LS (HTML5) では通常はその短い DOCTYPE を使用するべきとされているものの、DOCTYPEレガシー文字列として <!DOCTYPE html SYSTEM "about:legacy-compat">
のような長い DOCTYPE も認められているので、Prettier による強制変換の回避方法の一つとして検討に値するでしょう。