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
Help us understand the problem. What is going on with this article?

eslintの設定からprettierとの併用までの流れ

More than 1 year has passed since last update.

はじめに

今までeslintやprettierの恩恵を受けながら具体的な設定や使い分けを理解していなかったので、改めて調べてみました。

対象

  • 設定がよくわからないままeslint/prettierの恩恵を受けている
  • eslintだけでなくprettierも導入したい

実際のコードはこちらで確認できます。

前提

$ yarn eslint -v
v5.6.1

$ yarn prettier -v
1.14.3

eslintとprettierをなぜ使うのか?

詳しくこの記事に載っている。
まとめると、eslintは構文チェックとコードフォーマットの機能はあるが、コードフォーマットに関してはprettierの方が優れている。そのためeslintは構文チェッカーとして、prettierはコードフォーマッターとして役割分担して使うことで両者のいいとこ取りができる。

問題は上記のようにeslintにもコードフォーマットの機能があるため、prettierとフォーマットルールが競合する可能性があることで、それぞれただ設定するのではなく、競合しないような設定にすることを注意する必要がある。

eslintの設定

eslintのインストール

$ yarn add -D eslint

eslintの初期設定。質問に答えていくことで設定ファイルができる。
もちろん自分で直接、設定ファイルを作ってもいい。

$ yarn eslint --init
? How would you like to configure ESLint? Answer questions about your style
? Which version of ECMAScript do you use? ES2018
? Are you using ES6 modules? Yes
? Where will your code run? Browser
? Do you use CommonJS? Yes
? Do you use JSX? Yes
? Do you use React? No
? What style of indentation do you use? Spaces
? What quotes do you use for strings? Single
? What line endings do you use? Unix
? Do you require semicolons? Yes
? What format do you want your config file to be in? JavaScript
'The config that you've selected requires the following dependencies:

eslint-plugin-react@latest
Successfully created .eslintrc.js file
   Done in 41.01s.
// .eslintrc.js
module.exports = {
    "env": {
        "browser": true,
        "commonjs": true,
        "es6": true
    },
    "extends": "eslint:recommended",
    "parserOptions": {
        "ecmaFeatures": {
            "jsx": true
        },
        "ecmaVersion": 2018,
        "sourceType": "module"
    },
    "rules": {
        "indent": [
            "error",
            4
        ],
        "linebreak-style": [
            "error",
            "unix"
        ],
        "quotes": [
            "error",
            "single"
        ],
        "semi": [
            "error",
            "always"
        ]
    }
};

eslintの設定プロパティ

parserOptions
https://eslint.org/docs/user-guide/configuring#specifying-parser-options
JavaScriptのパーサーに対するプロパティ。パーサー自体は、parserプロパティで指定できる。
ECMAScriptのバージョンやJSXの利用有無などを指定することができる。
ちなみにReactの使うJSXはJSXオプションをtrueにするだけでなく、eslint-plugin-reactも利用する必要がある。

Please note that supporting JSX syntax is not the same as supporting React.
React applies specific semantics to JSX syntax that ESLint doesn’t recognize.
We recommend using eslint-plugin-react if you are using React and want React semantics.

module.exports = {
    ...
    "parserOptions": {
        "ecmaFeatures": {
            "jsx": true
        },
        "ecmaVersion": 2018,
        "sourceType": "module"
    },
    ...
};

plugins
https://eslint.org/docs/user-guide/configuring#configuring-plugins
外部が提供するプラグインをインストールした上で、指定することで利用可能になる。あとで設定する。

globals
https://eslint.org/docs/user-guide/configuring#specifying-globals
no-undefルールが有効化されていると、そのファイルでは使われているが、定義されていない変数は警告が出る。
そのためグローバル変数もそのエラー対象になってしまうので、globalsプロパティに指定してあげると警告が出なくなる。
また上書き可能の場合はtrue、読み取り専用の場合はfalseをつけてあげることで指定できる。

module.exports = {
    ...
    "globals": {
        "require": false,
        "module": false
    }
};

extends
https://eslint.org/docs/user-guide/configuring#extending-configuration-files
extendsに追加することでrulesを拡張することができる。
具体的には、以下の振る舞いで拡張される。

  • ルールの追加
  • 同じルールの重複するオプションだけ上書き
  • 同じルールのオプション全てを上書き

eslint:recommendedはeslintの推奨するルールが追加される。また、各種プラグインもextend用のルールを用意しているので、それも指定することで使うことができる。
これもあとで設定を追加する。

rules
https://eslint.org/docs/user-guide/configuring#configuring-rules
eslintがlintとして適用するルールを追加したり、上書きしたりできる。必ずしも記述されているものが全てというわけではない。
それぞれのルールに対して、以下のオプションを指定して有効化どうかを設定できる。

  • off or 0 : ルールの無効化
  • warn or 1 : 警告を出すだけ
  • error or 2 : エラーをだし、Exit Code 1を返す
module.exports = {
    ...
    "rules": {
        "indent": [
            "error",
            4
        ],
        "linebreak-style": [
            "error",
            "unix"
        ],
        "quotes": [
            "error",
            "single"
        ],
        "semi": [
            "error",
            "always"
        ]
    }
};

Reactとflowに対する設定

babel-eslintパーサーを使う
eslintの標準パーサーだと、babelがトランスパイルするes6以上のJavaScriptやflowによる型宣言に対応できないことがある。
それに対応したパーサーを使う。
https://eslint.org/docs/user-guide/configuring#specifying-parser

$ yarn add -D babel-eslint
// .eslintrc.js
module.exports = {
    "parser": "babel-eslint",
    ...
};

React, flowのrulesを追加する

reactとflowを使っている場合。
以下のプラグインがないとparseに失敗する。

$ yarn add -D  eslint-plugin-react eslint-plugin-flowtype

また上記プラグインはReact, flow用のruleも利用できるようになっているので、extendsで追加する。

// .eslintrc.js
module.exports = {
    "parser": "babel-eslint",
    "env": {
        "browser": true,
        "commonjs": true,
        "es6": true
    },
    "extends": [
      "eslint:recommended",
      "plugin:react/recommended", // 追加
      "plugin:flowtype/recommended" // 追加
    ],
    ...
    "plugins": [
        "react", // 追加
        "flowtype" // 追加
    ],
    ...
};

webpackでビルド時にeslintをかける

webpackでeslintのチェックをできるようにする。そうすることで毎回eslintのチェックコマンドを実行しなくてもビルドする際に、チェックされるので手間が省ける。

$ yarn add -D eslint-loader
const path = require('path');

module.exports = {
  ...
  module: {
    rules: [
      {
        test: /\.js$/,
        use: [
          {
            loader: 'babel-loader',
            options: {
              "presets": [
                '@babel/preset-env',
                '@babel/preset-react',
                '@babel/preset-flow'
              ]
            }
          },
          {
            loader: 'eslint-loader' // 追加
          }
        ],
        exclude: [/node_module/]
      }
    ]
  },
  ...
};

prettierの設定

prettierの導入

$ yarn add -D prettier

eslintとのルールの競合の解消

競合するルールを調査し、競合するeslintのルールを無効化する
eslint-config-prettierで競合するeslintのルールを無効化することができる。

$ yarn add -D eslint-config-prettier

READMEにあるように、他のextendsされたルールを上書いて無効化するために、extendsの配列の最後に追加する。
exntendsは配列の左から順番に適用されるので、最後にprettier関連のルールを追加しないと他のルールを上書きできないため。

module.exports = {
    ...
    "extends": [
      "eslint:recommended",
      "plugin:react/recommended",
      "plugin:flowtype/recommended",
      "prettier", // 追加(prettier関連のルールは最後に追加する, eslintの競合ルールを無効化)
      "prettier/flowtype", // 追加(eslint-plugin-flowtypeを無効化)
      "prettier/react" // 追加(eslint-plugin-reactを無効化)
    ],
    ...
};

また、eslint-config-prettier-checkにeslintrcの内容を渡すことで、競合しているルールをチェックできる。

$ ./node_modules/.bin/eslint --print-config . | ./node_modules/.bin/eslint-config-prettier-check
The following rules are unnecessary or might conflict with Prettier:

- flowtype/boolean-style
- flowtype/generic-spacing
- flowtype/space-after-type-colon
- flowtype/space-before-generic-bracket
- flowtype/space-before-type-colon
- flowtype/union-intersection-spacing
- indent
- no-extra-semi
- no-mixed-spaces-and-tabs
- semi

The following rules are enabled but cannot be automatically checked. See:
https://github.com/prettier/eslint-config-prettier#special-rules

- no-unexpected-multiline
- quotes

prettierのルールをeslintrcで指定できるようにする
次に、eslint-plugin-prettierで、prettierのルールをeslintのルールとして追加することが可能になる。

$ yarn add -D eslint-plugin-prettier

同様にextendsにはprettier関連のルールが最後になるようにする。

https://github.com/prettier/eslint-plugin-prettier#installation
Then you need to add plugin:prettier/recommended as the last extension in your .eslintrc.json:

module.exports = {
    ...
    "extends": [
      "eslint:recommended",
      "plugin:react/recommended",
      "plugin:flowtype/recommended",
      "plugin:prettier/recommended", // 追加
      "prettier",
      "prettier/flowtype",
      "prettier/react"
    ],
    ...
    "plugins": [
        "react",
        "flowtype",
        "prettier" // 追加
    ],
    "rules": {
        "prettier/prettier", // 追加
        ...
    }
};

改めて競合するルールを調べてみる。

$ ./node_modules/.bin/eslint --print-config . | ./node_modules/.bin/eslint-config-prettier-check
The following rules are unnecessary or might conflict with Prettier:

- indent
- semi

The following rules are enabled but cannot be automatically checked. See:
https://github.com/prettier/eslint-config-prettier#special-rules

- quotes

だいぶ減ったが、それでも残った不要なルールの削除と自動でチェックされないルールの設定をする。

module.exports = {
    ...
    "rules": {
        "prettier/prettier": ['error', { "singleQuote": true }],
        "linebreak-style": [
            "error",
            "unix"
        ]
    }
};

これで競合も解消された!

$ ./node_modules/.bin/eslint --print-config . | ./node_modules/.bin/eslint-config-prettier-check
No rules that are unnecessary or conflict with Prettier were found.

参考

freee
スモールビジネスのバックオフィス業務をテクノロジーで自動化し、日本のスモールビジネスを元気にする
http://www.freee.co.jp/
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