📛

【Husky / lint-staged】Prettierまわりのライブラリをマスターする【eslint-config-prettier】

2024/08/24に公開

はじめに

共同プロジェクトでPrettierを導入する際に、Prettierとその周辺技術についての調査をしました。
本記事ではそのまとめとして、Prettier, GitHooks, Husky, lint-staged, eslint-config-prettierのセットアップの手順と、各ツールの簡単な解説をしていきます!

Prettierとは?

ソースコードのフォーマット(整形)を行うnpmライブラリです。

Prettierのセットアップ

早速ですが、Prettierの公式ドキュメントに沿ってPrettierをセッティングしていきます!
https://prettier.io/docs/en/install

Prettierをインストールします。

npm install --save-dev --save-exact prettier

package.jsonのscriptsに以下を記述します。

package.json
{
    "scripts": {
+       "format": "prettier --write ."
    },
}

これで、npm run formatを実行するとフォーマットが走るようになりました🌟
上記の設定では、カレントディレクトリ(.)とそのすべてのサブディレクトリ内の、Prettierがサポートするタイプのファイルがフォーマットの対象になっています。

Prettierは.jsや.tsに限らず、色んな形式のファイルをサポートしています。
https://prettier.io/docs/en/

フォーマットを走らせたくないファイルがある場合は、rootディレクトリに.prettierignoreファイルを作成し、以下のように任意のファイル名やディレクトリ名を記述します。

.prettierignore
**/*.html
build

https://prettier.io/docs/en/ignore.html#ignoring-files-prettierignore

上記の設定をしなくても、Prettierはデフォルトで以下の拡張子のファイルを無視します。

  • **/.git
  • **/.svn
  • **/.hg
  • **/node_modules

https://prettier.io/docs/en/ignore.html#ignoring-files-prettierignore

また、特定のフォーマットルールを設けたい場合は、rootディレクトリに.prettierrcファイルを作成し、フォーマットのルールを記述します。

.prettierrc
{
    "trailingComma": "es5",
    "tabWidth": 4,
    "semi": false,
    "singleQuote": true
}

.prettierrcファイルを作成しない場合、もしくは空の.prettierrcファイルを作成した場合は、Prettierのデフォルトのフォーマットルールが適用されます。

また、.prettierrcファイルは.json, .yaml, .jsなどでもOKです👌
以下にファイルタイプごとの記述方法が載っています。
https://prettier.io/docs/en/configuration.html

これで、Prettierの基本的な設定は完了しました!🏃‍♂️

とは言っても、毎回手動でnpm run formatを実行するのは面倒です。
個人開発であれば、コードエディタの設定で、保存時に自動でPrettierを走らせるよう設定すれば良いですが、チーム開発となると少々厄介です。

チームメンバー全員にエディタの設定をしてもらうのは大変ですし、設定忘れなども想定できます。
そのような場合に備えて、コミット時に自動でPrettierを走らせる設定をしましょう。

GitHooksとは?

GitHooksを使うと、gitコマンドの実行前後に、任意のコマンドを実行させることができます。これで、コミット時に自動的にprettierコマンドを実行させることができます!

https://git-scm.com/docs/githooks

せっかくなので、GitHooksの実態を調査します🕵️

プロジェクトのrootディレクトリの中に.git/hooksディレクトリがあります。

このhooksディレクトリの中にGitHookのサンプルファイルが置かれています。

確認になりますが、今回はコミット時にprettierを実行させたいのでした。なので今回は、hooksディレクトリにpre-commitファイルを作成し、そこにコマンドを記述することになります。
他にも、pre-mergeやpre-pushなどのサンプルファイルが見受けられますが、それぞれにコマンドを設定することで、任意のタイミングで任意のコマンドを実行するようにできます。

ちなみに、サンプルファイルの中身はこんな感じです。

なにも、わからない…………😸

このGitHooksを使いやすいようにしてくれるのが、Huskyというnpmライブラリです🐕

Huskyのセットアップ

GitHooksを使ってコミット時にprettierを走らせるよう、Huskyの設定をしていきます!
Huskyのドキュメントに沿って、セットアップを行います。

https://typicode.github.io/husky/get-started.html

Huskyをインストールし、初期化します。

npm install --save-dev husky
npx husky init

.huskyディレクトリが作成され、package.jsonには以下の内容が追加されます

package.json
{
    "scripts": {
        "format": "prettier --write .",
+       "prepare": "husky"
    },
}

.huskyディレクトリを覗くとpre-commitファイルが作成されているので、こちらに以下のように記述します。

.husky/pre-commit
- npm
+ npx prettier --write .

これで、コミット時に自動でprettierが走るようになりました!🚗

……しかし現時点での設定だと、Prettierはフォーマット時にすべてのファイルをスキャンすることになります。たとえファイルに変更がなくても、スキャンされてしまうようです。
このため、ソースコードが膨大な大規模プロジェクトなどでは、フォーマットに時間がかかってしまいます。また、自分が変更していないソースコードにフォーマットがかかってしまう、といったことも発生するかもしれません。

これを防ぐために、Gitのステージングエリアにあるファイル(自分が編集してgit addしたファイル)にのみフォーマットを走らせるよう、設定したいところです。

これを可能にするのが、lint-stagedというnpmライブラリです🦄

lint-stagedのセットアップ

lint-stagedのREADMEに沿って、セットアップを行います。
https://github.com/lint-staged/lint-staged

lint-stagedをインストールします。

npm install --save-dev lint-staged

コミット時にlint-stagedに書かれたコマンドが実行されるよう、pre-commitファイルを修正します。

.husky/pre-commit
- npx prettier --write .
+ npx lint-staged

package.jsonに、コミット時に実行したいコマンドを記述します。

package.json
{
    "scripts": {
        "format": "prettier --write .",
        "prepare": "husky"
    },
+   "lint-staged": {
+       "**/*": "prettier --write --ignore-unknown"
+   }
}

ちなみに、"**/*": "prettier --write --ignore-unknown""prettier --write ."と同義で、カレントディレクトリとそのすべてのサブディレクトリ内の、Prettierがサポートするタイプに対してprettierを実行するコマンドです。

また、記述量が多くなる場合は、.lintstagedrcファイルを作成し、こちらで設定することも可能です。

.lintstagedrc
{
    "**/*": "prettier --write --ignore-unknown"
}

https://github.com/lint-staged/lint-staged?tab=readme-ov-file#configuration

これで、lint-stagedの設定は完了です!
最強のPrettier環境を構築することができました!🚅

eslint-config-prettierのセットアップ

ESLintを使用している人は、こちらの設定もしましょう!

eslint-config-prettierは、Prettierと競合する可能性のあるESLintのルールを無効化し、ESLintとPrettierが衝突するのを防ぐライブラリです。
https://prettier.io/docs/en/integrating-with-linters

eslint-config-prettierのREADMEに沿って、セットアップを進めていきましょう!
https://github.com/prettier/eslint-config-prettier

eslint-config-prettierをインストールします。

npm install --save-dev eslint-config-prettier

.eslintrcファイルに、以下のように記述します。

.eslintrc
{
    "extends": [
        "some-other-config-you-use",
+       "prettier"
    ]
}

以上でセットアップは完了です🎊
お疲れ様でした!

おまけ

今回、調査の過程で気になることがあったので、AIに聞いてみました。

🐌
各configファイルの末尾にあるrcって何ですか?

👾
"rc" の使用は1965年の MIT の CTSS (Compatible Time-Sharing System) オペレーティングシステムにまで遡ります。
"run commands" の略として使用され始めました。
現代では、"runtime configuration" としても解釈されることが多くなっています。
プログラムやシステムの起動時に読み込まれる設定ファイルを指す一般的な用語となっています。
.bashrc, .vimrc, .npmrc など、多くのプログラムやツールの設定ファイルで使用されています。

参考

https://prettier.io/
https://git-scm.com/docs/githooks
https://github.com/lint-staged/lint-staged
https://typicode.github.io/husky/
https://github.com/prettier/eslint-config-prettier
https://zenn.dev/risu729/articles/latest-husky-lint-staged

Discussion