Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
1016
Help us understand the problem. What is going on with this article?
@soarflat

Prettier 入門 ~ESLintとの違いを理解して併用する~

お知らせ(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
}

指定できるオプションは以下を参照。

Options · Prettier

package.json

パッケージをローカルインストールするため、package.jsonは以下のコマンドで生成する。

npm init -y

app.js

ソースコードを整形するファイル。

スペースの数が統一されておらず、無駄な改行が存在したりとコードが汚い状態。

整形前の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

コマンドを実行すれば、整形されたファイルが出力される。

整形後の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
);

整形されたファイルを出力できたが

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の内容は以下の通り。

.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.jsonscriptsフィールドに 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 formatnpm run lintが順番に実行されるので、Prettier と ESLint が実行される。

npm run fixを実行してみる

fix.gif

コードの整形、構文チェックができた。

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"
  }
}

preparenpm 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.jsonlint-stagedフィールドに lint-staged の設定を追加する。

package.json
{
  "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 --writeeslint --fixが実行される。

これでgit commit時にlint-stagedが実行され、Prettier と ESLint が実行されるようになった。

git commit時に Prettier と ESLint が実行されるか確認する

pre-commit.gif

git commit時に Prettier と ESLint が実行され、エラーを解消しなければコミットできなくなった。

終わり

コードは綺麗に越したことはないし、手軽に導入できるので少しでも魅力に感じたら利用してみましょう。

pre-commit フックまで利用するのは堅苦しく感じる方もいると思いますので、とりあえずはコマンドで整形するかエディタと連携させれば良いと思います。

お知らせ

Udemy で webpack の講座を公開したり、Kindle で技術書を出版しています。

Udemy:
webpack 最速入門10,800 円 -> 2,400 円

Kindle(Kindle Unlimited だったら無料):
React 実践入門(500 円)
React Hooks 入門(500 円)

興味を持ってくださった方はご購入いただけると大変嬉しいです。よろしくお願いいたします。

1016
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
soarflat
フロントエンドエンジニア。Udemy で webpack の講座を公開しています。https://www.udemy.com/course/practical-webpack/?couponCode=E09894A14502565499BA

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
1016
Help us understand the problem. What is going on with this article?