こんにちは。Eight でフロントエンドエンジニアをしている鳥山(@pvcresin)です。
最近は、Beat Saber という VR リズムゲームにハマっています。
音楽に合わせて、手に持ったライトセーバー的なものでブロックを切っていくゲームで、いい運動になっています。
さて、今回は Eight の Web フロントエンドにコードの整形ツールである Prettier を導入した話をしたいと思います。
Prettier とは
Prettierは Node.js 上で動く、コードのフォーマッター、整形ツールです。
ルールを設定することで、リポジトリ内のコードのスタイルを統一することができます。
Prettier にはデフォルトの設定があるので、細かな設定をしなくてもいい感じに整形してくれるのが良いところです。
HTML や CSS、JavaScript、Markdown などの形式に対応しています。
また、プラグインを入れることで Java や PHP、Ruby なども整形することが可能です。
今回は JavaScript のファイルに Prettier を適用してみました。
導入の背景
Eight のフロントエンドは 2012 年から存在し、これまで多くのエンジニアが開発に携わってきました。
JavaScript に関していえば、ESLint というリントツールが導入されており、コードの品質やスタイルの問題をチェックする仕組みが以前からありました。
しかし、それでも拾えないような細かなコードスタイルのバラつきが存在していました。
私は普段、個人で何かコードを書くときは、ファイルを保存するたびに自動で整形がかかるようにエディタを設定しており、コードのスタイルを気にする開発とは無縁の生活をしていました。
そのため、新卒として配属された初日にリポジトリを見たとき、Prettier をいれることを心に固く誓いました。
自動整形がもたらすメリット
ここまでの話では自己満足感が強いですが、チームでの開発においてもメリットがあります。
まず、既存のコードのスタイルが一貫していることで可読性が高くなります。
また、新規のコードを整形することで、レビューでのコードスタイルに関する指摘や作業途中で発生してしまう不要なコード差分を削減することができます。
これにより、エンジニアはコードのより本質的な部分に集中することができます。
加えて、整形ツールを導入することで、整形ツールはコードのスタイルを、リントツールはコードの品質を、とそれぞれの役割をより明確に分けることができます。
バラつきの例
いくつかバラつきの例を載せてみます。
実際はもう少し複雑でしたが、大まかなイメージは掴めると思います。
変数宣言
1 行で変数を宣言
const { param1, param2, ..., param9 } = obj;
改行して変数を宣言
const { param1, param2, ..., param9, } = obj;
if 文
{}
を 1 行で書く
if () { return null; }
{}
内部で改行する
if () { return null; }
if
と ()
と {
がくっついている
if(){ return null; }
アロー関数の引数
引数に()
をつける
const double = (num) => num * 2;
引数に()
をつけない
const double = num => num * 2;
一見、一つひとつは大したことないように思えますが、これらが積もり積もって大きなバラつきとなっていきます。
導入手順
上記のようなバラつきを取り除くため、Prettier を導入していきます。
ここからは実際の作業について説明します。
前提として、もし Prettier にバグがあった場合に、整形によってコードの挙動が変わってしまう可能性があるため1、慎重に段階的に進めていきました。
1. ESLint との連携の設定
ESLint にはコードのスタイルに関するルールがあり、Prettier のルールとぶつかることがあります。
Prettier はルールのカスタマイズ性が乏しいため、eslint-config-prettier を使って Prettier のルールとぶつかる ESLint 側のルールを無効にすることにしました。
2. 既存のコードの整形
まず、あらかじめコードを整形する範囲を決めました。
はじめは数ファイルしかないフォルダだったと思います。
その一定の範囲内のファイルをprettier --write
コマンドによって整形し、コードの挙動に影響がないことを目視で確認しました。
実際にはテストが完璧であれば、その必要はないのかもしれませんが、一部足りない部分もあったので、そのようなフローにしました。
また、場所によっては整形をかけたくない場合もあったので、.prettierignore
ファイルや// prettier-ignore
コメントを活用して整形させないようにしました。
3. 新規のコードの整形
Git のフックを利用し、一定の範囲内のファイルのコミット時に整形をかけるようにしました。 これには Husky と lint-staged を使いました。
4. CI の整備
一定の範囲内のファイルがちゃんと整形されているかを CI 上でチェックするようにしました2。
実際の作業としては 、Eight フロントエンドでは Circle CI を使っているので、job にprettier --check
コマンドを実行する step を追加しただけです。
これにより新しいコードはほぼ確実に整形された状態でマージされることになります。
5. 「一定の範囲」を広げる
手順の 2~4 で、一定の範囲内では既存のコードも新規のコードも整形されていることが保証されるので、あとは範囲を広げていくのみです。
少しずつ範囲を広げながら PR(プルリクエスト)を出していきました。
作業を終えて
個人のサイドタスクとしてコツコツ進めていたのですが、フロントエンドのコード全体に Prettier を広げるのに2~3ヶ月ほどかかりました。
段階的に広げていったため、無事に障害もなく終えることができました。
一時期、毎日のようにPRを見てくれたチームのメンバーには本当に感謝しています。
まとめ
今回は、Eight の Web フロントエンド に Prettier を導入した話について書きました。
Prettier を入れてから、PR も見やすくなりましたし、コードのスタイルについての悩みがほとんどなくなりました。
大きな変更を加えるときは、小さなところから段階的に広げていくことが重要だなと改めて感じました。
これからも常に DX(開発者体験、Developer Experience)向上を意識していきたいです💪