お知らせ(2021/05/26 追記)
以前はeslint --fix
などで ESLint を実行時に Prettier でコードを整形し、整形したコードに対して構文チェックが実行されるようにすることが推奨されていました。
ESLint で Prettier を実行するためには、ESLint の Plugin が必要でしたが、これを利用することが公式で推奨されなくなりました(詳細はこちら)。
そのため、記事を更新して Prettier と ESLint をそれぞれ実行させるような内容に変更しました(ついでに husky のバージョンも上げており、それに関する内容も更新しています)。
更新前のコードや記事は以下にありますので、必要に応じてご確認ください。
はじめに
Prettier(v.2.3.0) に関しての備忘録です。
- 「Prettier の何が便利なのかよくわからない」
- 「ESLint と何が違うのかよくわからない」
- 「
eslint --fix
でコード整形ができるから Prettier の必要性が感じられない」
といった人達向けに書いた記事であり
- Prettier の基本情報、利用目的、利用方法を理解する
- 何故 ESLint だけではなく Prettier も利用するのかを理解する
- Prettier と ESLint の併用方法を理解する
ことを目的としています。
ESLint 自体の説明は記載しておりませんので、ご注意ください。
解説に利用しているコードの最終形態は GitHub 上にあります。
Prettier とは?
コードフォーマッター(ソースコードを整形してくれるツール)のこと。読み方はプリティア。
以下のような様々な形式にサポートしている。
- JavaScript
- JSX
- Flow
- TypeScript
- JSON
- HTML
- Vue
- Angular
- Ember / Handlebars
- CSS
- Less
- SCSS
- styled-components 💅
- styled-jsx
- GraphQL
- Markdown
- YAML
何故コードフォーマッタを利用するのか(コードを整形するのか)
- ソースコードの品質を保つため(コードのスタイルの一貫性を保つため)
- コードレビュー時に、設計や命名などの重要な箇所に集中するため(コードのスタイルの指摘に時間を割くのを防ぐため)
- 複数のメンバーが各自の整形ルールを適用し、更新する度に余計な差分が発生することを防ぐため
- ソースコードを綺麗にするための労力(スタイル定義の議論や時間)を費やさなくて済むため
- ツールに任せられることはツールに任せてしまった方が今後楽になるため
Prettier を利用してみる
Prettier を利用してソースコードが整形されたファイルを出力してみる。
ディレクトリ構成
今回 Prettier を利用するディレクトリ構成は以下を前提とする。
integrate-prettier-with-eslint
├── .prettierrc
├── package.json
└── app.js
.prettierrc
Prettier の設定ファイル。
設定を記述することで、Prettier のデフォルトの設定を上書きできる。
{
"singleQuote": true
}
指定できるオプションは以下を参照。
package.json
パッケージをローカルインストールするため、package.json
は以下のコマンドで生成する。
npm init -y
app.js
ソースコードを整形するファイル。
スペースの数が統一されておらず、無駄な改行が存在したりとコードが汚い状態。
class Person{
constructor(name) {
this.name = name;
}
}
const profile = {
name: 'soarflat', sex: 'male', location: 'Tokyo'
};
const hoge = (message)=>{
console.log(message);
}
// hoge(new Person('Person').name);
const fooBar = (a, b, c) =>{
console.log(a);
console.log(b)
console.log(c);
};
fooBar(111,
{
hoge: 'hoge!'
},profile
)
Prettier のインストール
npm install prettier@2.3.0 --save-dev
ローカルインストールした Prettier を実行するために PATH を通す
prettier
コマンドを実行できるようにするため、以下のように PATH を通す。
export PATH=$PATH:./node_modules/.bin
※「PATH を通す」が不明な方は以下をご覧ください。
Prettier の実行
app.js
に対してprettier
コマンドを実行する。ファイルを上書きするために--write
オプションをつける。
prettier app.js --write
コマンドを実行すれば、整形されたファイルが出力される。
class Person {
constructor(name) {
this.name = name;
}
}
const profile = {
name: 'soarflat',
sex: 'male',
location: 'Tokyo',
};
const hoge = (message) => {
console.log(message);
};
// hoge(new Person('Person').name);
const fooBar = (a, b, c) => {
console.log(a);
console.log(b);
console.log(c);
};
fooBar(
111,
{
hoge: 'hoge!',
},
profile
);
整形されたファイルを出力できたが
ESLint でもコード整形はできるし、結局 Prettier の何が良いのかわからないため、Prettier は ESLint より何が優れており、何故利用(併用)すべきかを説明していく。
何故 Prettier を利用(ESLint と併用)するのか
ESLint でもeslint --fix
でコード整形ができるが、Prettier の方がコード整形が優れているから。
具体的には以下の点が優れている。
- ESLint では整形できないコードを整形できる
- ESLint と比べて手軽で確実に整形できる
ESLint では整形できないコードを整形できる
以下のような一行の文字数が長いコードは ESLint でエラーが出力されるが、整形はされない。
foo(reallyLongArg(), omgSoManyParameters(), IShouldRefactorThis(), isThereSeriouslyAnotherOne());
一方、Prettier では以下のように整形される。
foo(
reallyLongArg(),
omgSoManyParameters(),
IShouldRefactorThis(),
isThereSeriouslyAnotherOne()
);
上記のような整形をしてくれれば、複数のメンバーがエラーに対する独自の修正を適用し、更新するたびに差分が出てしまうような事態を防ぐことができる。
そのため、Prettier を利用した方がコードのスタイルの一貫性は保たれる。
ESLint と比べて手軽で確実に整形できる
eslint --fix
は設定に該当したエラーのみを整形する。そのため、設定次第ではコードを整形しきれない。
整形を厳密に行うためには、多くの設定を指定する必要があり、設定自体が複雑になる(設定ファイルがすごい行数になる)可能性がある。
一方、Prettier はデフォルトのスタイル(整形ルール)が存在するため、prettier
コマンドを実行するだけでコードが整形される。
スタイルの変更も可能だが、こだわりがなければデフォルトのままで問題ないし、確実に整形してくれる。
また、Prettier は良くも悪くも設定できる項目が少ないため、設定が複雑になる可能性が低い。
そのため、Prettier を利用した方が手軽で確実に整形できる。
Prettier は ESLint よりもコード整形が優れているが
上記の理由で Prettier を利用すべきだが、Prettier はコードフォーマッタのため、ESLint のような構文チェック機能はない。
そのため、コードの整形は Prettier が行い、コードの構文チェックは ESLint が行うように併用する。
ESLint との併用
ESLint にもフォーマットのルールが存在するため、ESLint の整形と Prettier の整形が競合する可能性がある。
そのため、ESLint のフォーマットのルールを無効化にして、Prettier と ESLint を実行できるようにする。
併用に必要なパッケージのインストール
以下のパッケージをインストールする。
npm install eslint@7.26.0 eslint-config-prettier@8.3.0 --save-dev
それぞれのパッケージの詳細は以下の通り。
-
eslint
(ESLint 本体) -
eslint-config-prettier
(ESLint のフォーマット関連のルールを全て無効にする、要は Prettier が整形した箇所に関してエラーを出さなくなる)
.eslintrc
の設定
先ほど Prettier を実行したディレクトリに.eslintrc
(ESLint の設定ファイル)を作成する。
そのため、ディレクトリ構成は以下のようになる。
integrate-prettier-with-eslint
├── .eslintrc
├── .prettierrc
├── package.json
└── app.js
.eslintrc
の内容は以下の通り。
{
"root": true,
"env": {
"browser": true,
"es6": true
},
"extends": ["eslint:recommended", "prettier"]
}
Prettier に関連する記述は
"extends": ["eslint:recommended", "prettier"]
の"prettier"
の箇所のみ。
この記述で、ESLint のフォーマット関連のルールが全て無効になる。
また、この記述は必ずextends
配列内の最後に記述する。
以下のような記述だとうまく動作しないことがあるため注意。
{
"extends": ["prettier", "eslint:recommended"]
}
npm scripts で Prettier と ESLint を実行できるようにする
以下のように、package.json
のscripts
フィールドに Prettier と ESLint を実行する記述を追加する。
{
"name": "integrate-prettier-with-eslint",
"scripts": {
"format": "prettier --write app.js",
"lint": "eslint --fix app.js",
"fix": "npm run format && npm run lint"
},
"devDependencies": {
"eslint": "^7.26.0",
"eslint-config-prettier": "^8.3.0",
"prettier": "^2.3.0"
}
}
npm run fix
を実行すれば、npm run format
とnpm run lint
が順番に実行されるので、Prettier と ESLint が実行される。
npm run fix
を実行してみる
コードの整形、構文チェックができた。
git commit
時に Prettier と ESLint が実行されるようにする
上記の方法でコード整形と構文チェックが可能になったが、Prettier と ESLint を実行しない限りコードは整形されないため、整形されていないコードがコミットされてしまう可能性がある。
これを防ぐために、エディタと連携してファイル保存時に Prettier と ESLint を実行する手段がある。
個人での開発ではそれで問題ないが、複数人開発の場合、全員がそれぞれのエディタプラグインを導入するコストがかかる。
そのため、整形したコードのみを確実にコミットしたいのであればgit commit
時に Prettier と ESLint が実行されるようにする。
Git にはコミット前に指定のスクリプトを実行できる pre-commit フックと言う仕組みがあるため、それを利用する。
pre-commit フックに必要なパッケージをインストール
npm install husky@6.0.0 lint-staged@11.0.0 --save-dev
それぞれのパッケージの詳細は以下の通り。
-
husky
(Git のコミット時やプッシュ時に指定したコマンドを実行できる) -
lint-staged
(Git のステージングに追加されたファイルにのみに ESLint などのリントを実行できる)
husky を利用するためのセットアップ
husky のインストール後は以下のコマンドで、Git フックを有効にする(.husky
ディレクトリとhusky.sh
などが生成される)。
npx husky@6.0.0 install
そして以下のコマンドを実行する。
npm set-script prepare "husky install"
このコマンドを実行することで、以下のようにscripts
フィールドにprepare
が追加される。
{
"name": "integrate-prettier-with-eslint",
"scripts": {
"format": "prettier --write app.js",
"lint": "eslint --fix app.js",
"fix": "npm run format && npm run lint",
"prepare": "husky install"
},
"devDependencies": {
"eslint": "^7.26.0",
"eslint-config-prettier": "^8.3.0",
"prettier": "^2.3.0"
}
}
prepare
はnpm install
などを実行時に自動で実行される。
そのため、自分以外の開発環境などでもnpm install
を実行すればhusky install
が実行され、Git フックが有効になる。
pre-commit フックを追加する
npx husky@6.0.0 add .husky/pre-commit "lint-staged"
これで、コミット時にlint-staged
が実行されるようになった。
package.json
に lint-staged の設定を追加する
以下のように、package.json
のlint-staged
フィールドに lint-staged の設定を追加する。
{
"name": "integrate-prettier-with-eslint",
"scripts": {
"format": "prettier --write app.js",
"lint": "eslint --fix app.js",
"fix": "npm run format && npm run lint",
"prepare": "husky install"
},
"lint-staged": {
"*.js": [
"prettier --write",
"eslint --fix"
]
},
"devDependencies": {
"eslint": "^7.26.0",
"eslint-config-prettier": "^8.3.0",
"husky": "^6.0.0",
"lint-staged": "^11.0.0",
"prettier": "^2.3.0"
}
}
上記のようにすることで、ステージングに追加された JavaScript ファイルに対して、prettier --write
とeslint --fix
が実行される。
これでgit commit
時にlint-staged
が実行され、Prettier と ESLint が実行されるようになった。
git commit
時に Prettier と ESLint が実行されるか確認する
git commit
時に Prettier と ESLint が実行され、エラーを解消しなければコミットできなくなった。
終わり
コードは綺麗に越したことはないし、手軽に導入できるので少しでも魅力に感じたら利用してみましょう。
pre-commit フックまで利用するのは堅苦しく感じる方もいると思いますので、とりあえずはコマンドで整形するかエディタと連携させれば良いと思います。
お知らせ
Udemy で webpack の講座を公開したり、Kindle で技術書を出版しています。
Udemy:
webpack 最速入門(10,800 円 -> 2,000 円)
Kindle(Kindle Unlimited だったら無料):
React Hooks 入門(500 円)
興味を持ってくださった方はご購入いただけると大変嬉しいです。よろしくお願いいたします。