「従われている」傾向があるPrettier

sosukesuzuki氏(以下、suzuki):「Prettierに従わなくてもいい場合」を話します。

suzukiといいます。筑波大学の情報科学類で学生をしていたり、サイボウズ株式会社というところで働いていたり、OSSだとPrettier Core Teamでメンテナンス全般をやっていたり、Babel TeamというところでBabelのパーサー周りを見ていたりします。

Prettier、Node.jsをよく使う人ならたぶん使ったことがあると思うのですが、Prettierは、Opinionatedのコードフォーマッターと呼ばれるもので、オプションが非常に少ないのが特徴です。

JavaScriptとかTypeScriptとか、CSSとか、HTMLとか、Web開発に使うプログラミング言語には、だいたい対応しているコードフォーマッターです。

どんなものに使われてるのかを、ちょっと調べたのですが、Weekly Downloadsの2020年のState of JavaScriptのアンケートの結果を見てみると、npmとESLintに次いで広く認知されているようです。

もう1個の観点として「従われている」という傾向があると思っています。これはTwitterから適当に引っ張ってきたものですが、このようにPrettierに従うタイプのユーザーがけっこう多いです。

かくいう自分も、「Prettierさまに従って生きていれば楽。」と2年以上前にツイートしています。

今日は「従わなければいけない」ということはなくて、従わなくてもいいケースがあるという話を、みなさんに伝えたいと思っています。

Prettierに従わなくてもいい3つのケース

当然といえば当然の話ですが、今日紹介するのはこの3つのケースです。1個目が「Prettierがプログラマーの意図を解釈できない場合」。2個目が「Prettierが明らかにバグっている場合」。3つ目が「Prettierがバグっているかもしれない場合」というのがあります。

Prettierがプログラマーの意図を解釈できないケース

はじめに「Prettierがプログラマーの意図を解釈できない場合」について話していきます。

このPrettierは構文だけを見るので、プログラマーの意図を解釈できません。例えば、行列を作る関数を考えた時ですが、3かけ3行の列を作る関数があった時に、9個渡したらそれが行列になりますよという関数呼び出しがあっても、Prettierからすると、これはただの9個の引数を持つ関数呼び出しでしかありません。なので、「それは行列を作るものだから、3つずつで改行してほしいよね」というのは、Prettierからしたらわかりません。

なので、そういう時は対処法として、「prettier-ignore」コメントを容赦なく使って大丈夫です。

prettier-ignoreコメントを使うと、そのコメントの次のノードをPrettierのフォーマットの対象外にすることができるので、これを使いましょう。

Prettierが明らかにバグっているケース

もう1個「Prettierが明らかにバグっている場合」というのが、あります。Prettierは、けっこうバグがあって(笑)、メンテナンスたちも認知はしているのですが、未解決のバグが残念ながらけっこう多く存在しています。

どういうバグがあるかというと、例えば言語機能への対応が足りてないケースが、たまにあります。TypeScriptの新しい構文がリリースされた時に、リリースノートにその言及がないケースがあるんですね。

そうすると、それにPrettier Teamは気づかずに、追及できていない場合っがあります。

例えば、TypeScript 4.3でoverrideというのが追加されました。Parameter Property、コンストラクタの引数にpublicやreadonlyを付けると、それが同名のプロパティになる機能です。Prettier 2.3は、TypeScript 4.3に対応していたつもりだったのですが、2.3をリリースしてから「Parameter Property上のoverrideに対応してないよ」とユーザーから報告でそれに気づいて、パッチリリースで対応する、みたいなことがあるので、まれに言語機能への対応そのものが足りてないことがあります。

もう1個、よくあるのが「バグっていることには気がついているんだけど、技術的に難易度が高いかつリソースがあまりない」というところで、Prettierがバグを修正できていないケースがあります。

これの対処法が、「従わない」ということなのかと言われるとアレなのですが、そのまま使い続けるのではなくて、issueを作ったりコメントをしたり、issueやコメントにいいねをしてくれると、メンテナーは、すごく優先度がつけやすくて、現実に起きている問題なんだなと認識ができるので、その分早く修正される可能性があります。

もちろん、そのバグを修正するためのプルリクエストを作ってもらっても、ぜんぜん問題ないです。

Prettierがバグっているかもしれないケース

もう1個「Prettierがバグっているかもしれない場合」というのがあります。バグなのかよくわからない挙動がたまにあるんですね。みなさんも、もしかしたらPrettierに自動整形をかけた時に「これはマジか」と思うことがあるかもしれません。「一見しただけでは問題なさそうだが、よく考えたら読みにくい」とか、またその逆の「やや読みにくいんだけど、これがPrettierの流儀なんじゃないだろうか」みたいな挙動をすることが、たまに(笑)あるんじゃないかなと思っています。

実際に、後になってからバグと判断されて修正された例を、1個あげます。左がPrettier 2.2で正しいとされていたフォーマットで、右がPrettier 2.3で正しいとされていたフォーマットです。何が違うかというと、このclassに長めのextendsとimplementsがくっついてて、classの本体が始まる波括弧が、implementesの直後に改行なしでくっついているか、改行を入れて続いているかが違います。

2.2まではそのまま改行なしで続いてて、2.3からはimplementsの後に改行を入れるようになりました。これはなんでかというと、見たらなんとなくはわかるとおり、implementsとpropertyの間に何もないので、パッと見た時に、どこまでがextendsやimplementsで、どこからがclassのpropertyなのかが、わかりません。そこで議論が行われて、これは例外的に波括弧の直前に改行を入れてもいいケースだよねとなったので、2.3からはこういう修正がされました。

こういうことは、けっこうたまに起こるので、これに対して「Prettierの流儀なんじゃなかろうか」みたいに(笑)思ったとしても、issueをあげてくれたりコメントをしてくれたり、コメントにリアクションをしてくれると、ユーザーの声が知れるので、すごくうれしいし、実装に着手しやすくなります。

バグがあったら気軽にGitHub上でリアクションしてほしい

ドキュメントには一応、いわゆるPrettierの流儀というか、どうしてPrettierがそういう選択をしたのかと、その根拠が書いてあるページがあるので、そこを読むと納得できたり、issueが作りやすかったり、もしくはプルリクエストが作りやすかったりするんじゃないかなと思っているので、やってくれるとうれしいです。

重要な話として、たぶんPrettierを使う目的は「チーム内でのコーディングスタイルに関する議論をなくす」こと、つまりそのプロジェクトの本質ではない部分の議論を減らすことだと思うのですが、Prettier内ではそういう議論はしてよいとなっています。Prettierにとってコーディングスタイルはけっこう本質の部分なので、Prettierの中では実際にそういう議論が行われます。

なので、コードフォーマットにクセがあるなと思ったら「これ、どうしてこうなっているの?」と聞いてもらって大丈夫だし、バグってると思ったらissueをくれてもぜんぜん問題ありません。

まとめとしては、prettier-ignoreコメントを遠慮せずに使いましょう、というのと、バグってたら、アップボートだけでもいいので(笑)、GitHub上にリアクションをくれると早く着手できることがあります。

もう1個重要なのが、合理性があれば、Prettier内でコーディングスタイルの改善や修正について議論をするのは、ぜんぜん問題ないということです。

この話を聞いている人の中で、1人でも(笑)、GitHub上でなにかアクションを起こしてくれたらいいなと思って、話をしました。というところで、以上で終わりにしたいと思います。ありがとうございました。