ESLint で有効化するルールのカスタマイズ
はじめに
こんにちは。Belong で Frontend Engineer をやっている hatakoya です。
この記事ではフロントエンドの開発でよく使われる Linter である ESLint について、ルールのカスタマイズ方法といくつかのルールについて紹介したいと思います。
ESLint 構成ファイルの書き方
簡単に構成ファイルでルールをカスタマイズする方法について説明します。
ESLint の構成ファイルは .eslintrc.js
です。 .js
以外でも書けますがそこはお好みです。
ルールをカスタマイズするときは主に以下のプロパティを設定することになります。
plugins
extends
rules
overrides
const config = {
plugins: [],
extends: [],
rules: {},
overrides: [],
}
module.exports = config
plugins
plugins
には ESLint のプラグイン(npm パッケージ)を指定します。
ESLint がデフォルトで備えているルールだけでも結構な量がありますが、プラグインを追加することでそのプラグインが提供する独自のルールをさらに追加することができます。
例えばeslint-plugin-reactを入れる場合は以下のように書きます。このとき "eslint-plugin" は省略できます。
const config = {
plugins: ['react'],
}
module.exports = config
extends
extends
には Shareable Configs(npm パッケージ)を指定します。
これにより外部の ESLint 構成ファイルをベースに変えたいところだけ自分たちでカスタマイズするといったことができます。
基本的にはプラグイン自体が Shareable Configs も提供していて、そのプラグイン用の推奨構成などが用意されていたりします。
プラグインを入れることにより競合する ESLint ルールを無効にしたり、プラグインを動かすために必要な構成ファイルの settings
や parserOption
プロパティの設定値などもいい感じに設定してくれるので、それらを自分で書くよりは提供される構成を利用してしまうのが手っ取り早いです。
プラグインの Shareable Configs にはその構成自体に自身のプラグインを追加する構成も含まれていたりするので、その場合は plugins
は設定しなくても良いです。
const config = {
extends: ['plugin:react/recommended'],
}
module.exports = config
rules
rules
では各ルールについて有効 or 無効の設定をします。
Shareable Configs の設定をベースに、変えたいものを設定していきます。
基本的には 'off'
や 'error'
などを設定しますが、ルールによってはオプションがあり、オプションをデフォルトから変えたい場合は配列で設定します。
const config = {
rules: {
// 無効にする
'no-undef': 'off',
// 有効にする(警告)
'no-undef': 'warn',
// 有効にする(エラー)
'no-undef': 'error',
// 有効にする(オプションつき)
'array-callback-return': [
'error',
{ allowImplicit: false, checkForEach: true },
],
},
}
module.exports = config
overrides
特定のディレクトリ内のファイルだけルールを別にしたい場合は overrides
を設定します。
これは例えば eslint-plugin-import で基本的に default export
を禁止したいが、Next.js の pages
ディレクトリのように default export
しなければならないファイルについてはルールを変えたいといったときに使えます。
const config = {
rules: {
// Default export を禁止する
'import/no-default-export': 'error',
'import/prefer-default-export': 'off',
},
overrides: [
{
files: ['pages/**/*.{ts,tsx}'],
rules: {
// Default export を強制する
'import/no-default-export': 'off',
'import/prefer-default-export': 'error',
},
},
],
}
module.exports = config
ESLint のルールについて
JavaScript や TypeScript のリンターとして ESLint を利用するにあたり、有効化するルールは eslint:recommended
などの推奨ルールを設定したり、
eslint-config-airbnb のようなものを使うと楽です。
ただし、ルールを厳しくしたり緩くしたり、チームに合った適切な設定にするためには各ルールのドキュメントを読み、内容をある程度理解する必要がでてきます。
ESLint にはたくさんのルールがありますが、この中から eslint:recommended
に含まれないものをいくつか抜粋して紹介したいと思います。
array-callback-return
配列の map
や find
などのメソッドで return
することを強制するルールです。
コーディングスタイルを揃えたい場合は有効にすると良いです。
オプション:
allowImplicit
(default:false
) - 値なしのreturn
でundefined
を返すことを許可するかcheckForEach
(default:false
) -forEach
で値つきのreturn
を許可するか
checkForEach
は true
にするのが良いと思います。
'array-callback-return': [
'error',
{ allowImplicit: false, checkForEach: true },
],
no-constant-binary-expression
常に true
or false
になる比較式や、常に通らない ||
, &&
, ??
を禁止します。
no-implicit-coercion
!!foo
の代わりに Boolean(foo)
を使うようにするなど、わかりにくそうな型変換を禁止します。
no-else-return
不要な else を禁止する。
allowElseIf: false
にすると、if の中で return する場合は else-if を禁止します。
'no-else-return': ['error', { allowElseIf: false }],
no-unneeded-ternary
条件が常に true
または false
になる三項演算子を禁止します。
no-useless-return
不要な return
を禁止します。
object-shorthand
オブジェクトのプロパティの値が変数と同じ名前の場合は省略記法を強制します。
// NG
const foo = {
a: a,
}
// OK
const foo = {
a,
}
prefer-const
const
で宣言できる変数は const
で宣言するようにします。
arrow-body-style
アロー関数の中括弧を強制または禁止します。
1つ目のオプション
“always”
- 常に中括弧を強制する“as-needed”
- 中括弧を省略できる場合は中括弧なしを強制する。“never”
- 中括弧なしを強制する(値を返さないアロー関数は書けなくなる)
2つ目のオプション
requireReturnForObjectLiteral
(default: false) -“as-needed”
の場合にのみ設定できる。true にするとオブジェクトリテラルを返す場合に return を強制する。- true にすると以下のようになります
// NG
const func = () => ({ a: 1 })
// OK
const func = () => {
return { a: 1 }
}
consistent-return
関数内の複数の return がある場合に値を指定する/しないが一貫することを強制します。
オプション:
treatUndefinedAsUnspecified
true
- 値なしはreturn undefined
でもreturn
でも OKfalse
(default) - 値なしはreturn undefined
ではなくreturn
を強制
'consistent-return': ['error', {
treatUndefinedAsUnspecified: false,
}],
curly
if 文などで中括弧{}
を強制します。
default-case
switch-case で default を強制します。
default-case-last
switch-case で default を最後に書くことを強制します。
eqeqeq
==
や !=
の代わりに ===
と !==
を使うようにします。
オプションで、 null
との比較をする場合は ==
と !=
しか使えないようにすることもできます。
eqeqeq: ["error", "always", { null: "never" }],
no-duplicate-imports
同じモジュールからの import
は 1 行にまとめることを強制します。
// NG
import { foo } from 'myModule'
import { bar } from 'myModule'
// OK
import { foo, bar } from 'myModule'
TypeScript の import type
を使う場合は代わりに import/no-duplicates を使います。
おわりに
ESLint のルールを整備することで、コーディングスタイルを統一したり、バグを防ぐことができます。
上記で紹介したルールは一例ですが、recommended
で有効にならないルールの中でも有用なものも多いので、必要に応じて追加していくのが良いと思います。
もしくは eslint:all
を有効にして、必要なルールだけ無効にするという方法もあります。その場合は無効または変更するルールが rules
内に明示的に書かれるので、どのルールをカスタマイズしているかがわかりやすいかもしれません。
Belong のフロントエンドは TypeScript/Next.js で開発しており、各種プラグインを入れて ESLint を活用しています。 機会があれば、他のプラグインなどについても紹介したいと思います。
また、弊社 Belong は一緒に働くエンジニアを募集しています。
興味がある方は エンジニアリングチーム紹介ページ をご覧いただけると幸いです。