まくろぐ

TypeScript プロジェクトに ESLint を導入する

更新:
作成:

ESLint とは

ESLint は JavaScript/TypeScript 向けの Lint ツール(静的解析ツール)です。 プロジェクト内のソースコードに対して eslint コマンドを実行することで、コーディングルールに従っていない部分や、不具合の原因になりそうな部分を検出してくれます。

☝️ eslint vs tslint もともと TypeScript 用には tslint という Lint ツールが提供されていましたが、Microsoft の TypeScript チームが eslint への統合を 公式に発表 してから(2019年以降)は、TypeScript においても eslint が事実上の標準 Lint ツールとなっています。参考: TypeScript の ESLint 対応プロジェクト

ESLint のインストール

eslint コマンドは npm でインストールできます。 TypeScript プロジェクトのディレクトリ内で、次のように開発用にインストールすることが推奨されています(package.json は作成済みだと想定します)。

ESLint のインストール
$ npm install eslint --save-dev

ESLint の初期設定

eslint コマンドを実行するためには、設定ファイル .eslintrc.{js,yml,json} を作成しておく必要があります。

設定ファイルの生成
$ npx eslint --init

上記のように実行すると、ウィザード形式でどのような用途に使用するかを質問されるので、順番に答えていくだけで設定ファイルを生成できます。 最後にその構成に必要なモジュールをまとめてインストールできます。 ここでは、eslint v7.26.0 における表示例を示しています。

質問1
? How would you like to use ESLint? …
  To check syntax only
  To check syntax and find problems
❯ To check syntax, find problems, and enforce code style

ここでは「構文チェック」「問題の発見」「スタイル強制」をすべて行いたいので、カーソルキーで一番下の項目を選んで Enter キーを押します。

質問2
? What type of modules does your project use? …
❯ JavaScript modules (import/export)
  CommonJS (require/exports)
  None of these

モジュールのインポート形式には import/export を選択します。

質問3
? Which framework does your project use? …
❯ React
  Vue.js
  None of these

React.js や Vue.js を使うのであれば、ここで選択します。

質問4
? Does your project use TypeScript?  No / Yes

TypeScript を使うかどうかを聞かれるので、Yes を選択します。

質問5
? Where does your code run? …
✔ Browser
  Node

実行環境を選択します(スペースキーで選択をトグルします)。 コードの中で、どのようなグローバルオブジェクトを参照するかに応じて選択します。 Web ブラウザ上で動作させる JavaScript コードであれば Browser を選択し、Node.js 環境で動作させるコードであれば Node を選択します。

質問6
? How would you like to define a style for your project? …
❯ Use a popular style guide
  Answer questions about your style
  Inspect your JavaScript file(s)

最初の質問で一番下の enforce code style を選んでいると、ここでどのようなコーディングスタイルを使うかを質問されます。 ここでは、ポピュラーなスタイルをそのまま使うことにします。

質問7
? Which style guide do you want to follow? …
  Airbnb: https://github.com/airbnb/javascript
❯ Standard: https://github.com/standard/standard
  Google: https://github.com/google/eslint-config-google
  XO: https://github.com/xojs/eslint-config-xo

実際にどのスタイルを提供するかを指定します。 有名どころの Airbnb スタイルや JavaScript Standard スタイルなどを選択できます。 ここでは、行末のセミコロンを省略するスタイルである Standard を選択することにします。 参考: TypeScript のコーディング規約(ルール/ガイドライン)

質問8
? What format do you want your config file to be in? …
  JavaScript
❯ YAML
  JSON

コンフィグファイルの形式を選択します。 基本的には一番簡潔に記述できる YAML 形式を選び、何らかの動的処理が必要な場合のみ JavaScript 形式を選べばよいと思います。 JSON 形式は記述が冗長になるし、コメントも記述できないので、選択しないようにしましょう。

質問9
The config that you've selected requires the following dependencies:

eslint-plugin-react@latest @typescript-eslint/eslint-plugin@latest eslint-config-standard@latest eslint@^7.12.1 eslint-plugin-import@^2.22.1 eslint-plugin-node@^11.1.0 eslint-plugin-promise@^4.2.1 @typescript-eslint/parser@latest
? Would you like to install them now with npm?  No / Yes

必要なパッケージの一覧が表示されるので、Yes を選択してインストールします。 これらの依存情報は、package.jsondevDependencies に自動的に追加されます。

これで、ESLint の初期設定は完了です。 作成された .eslintrc.yml の内容は次のような感じになっています。

.eslintrc.yml
env:
  browser: true
  es2021: true
extends:
  - 'plugin:react/recommended'
  - standard
parser: '@typescript-eslint/parser'
parserOptions:
  ecmaFeatures:
    jsx: true
  ecmaVersion: 12
  sourceType: module
plugins:
  - react
  - '@typescript-eslint'
rules: {}

ESLint の実行

カレントディレクトリ以下の .ts および .tsx ファイルに対して、ESLint をかけるには次のように実行します。

$ npx eslint . --ext ts,tsx

標準出力に警告がずらずらと表示されるはずです。 上記コマンドは、NPM スクリプトとして package.json に登録しておくと楽です。

package.json(抜粋)
{
  //...
  "scripts": {
    "lint:eslint": "eslint . --ext ts,tsx",
    "fix:eslint": "eslint . --ext ts,tsx --fix",

ここでは、単純にチェックだけかける lint:eslint コマンドと、自動修正までしてしまう fix:eslint コマンドを定義してみました。 これで、次のように簡単に ESLint を実行できるようになります。

$ npm run lint:eslint  # ESLint の実行
$ npm run fix:eslint   # 自動修正

npm スクリプト名を単純に lintfix にしていないのは、追加で Prettier(自動整形ツール)を導入することを想定したものです。 Prettier の方にも同様の機能があるため、lint:prettierfix:prettier という名前を付ける余地を残しています。

(おまけ)VS Code への ESLint プラグインのインストール

エディターとして VS Code を使用している場合は、VS Code 用の ESLint プラグインもインストールしておきましょう。 次のような機能が有効になります。

  • 編集中にエディター上にエラー表示
  • エラーの一覧を Output パネル (Ctrl + Shift + M) に表示
  • 上記それぞれから Quick Fix 可能

ESLint プラグインのインストールと有効化

/p/xz9iry9/img-001.png

ESLint プラグインは上記のサイトあるいは、VS Code の Extensions メニューからワンクリックでインストールできます。 ESLint プラグインをインストールした直後は、次のような警告が出て ESLint が有効になっていない可能性があります。

/p/xz9iry9/img-002.png

その場合は、VS Code 右下の ESLint という部分をクリックして有効化できます。

/p/xz9iry9/img-003.png

VS Code のフォーマッター設定

VS Code には、JavaScript/TypeScript のフォーマッターがデフォルトで搭載されています。 これらのフォーマットスタイルは ESLint で設定したスタイルに合わないことがあるので、ESLint のスタイル設定を優先するように設定しておきます。 Ctrl + , で設定画面を開いて、Formatter などで検索すると設定項目を見つけられます。

/p/xz9iry9/img-004.png

これで、Shift + Alt + F(あるいは Ctrl + Shift + PFormat Document)で編集中ファイルのフォーマットを実行できます。

(おまけ)React 用の設定

最新の React では、TypeScript コード内に JSX が含まれていても React モジュールをインポートする必要がなくなっています。 ESLint がこれを認識できずに、次のようなエラーを出力することがあります。

4:10  error  'React' must be in scope when using JSX  react/react-in-jsx-scope

このチェックを無効にするには、設定ファイルの rules プロパティで次のように指定します。

.eslintrc.yml(抜粋)
rules:
  react/react-in-jsx-scope: off

(おまけ)Airbnb スタイルで TypeScript のインポートエラーが出る場合

eslint --init で導入される Airbnb スタイルは、TypeScript のインポートまわりの扱いが不十分で、多少のマニュアル設定が必要になることがあります(2021-05 現在)。 具体的には、Airbnb スタイルの import 設定.js ファイルを前提としており、拡張子を省略して .ts ファイルをインポートできません(import/no-unresolvedimport/extensions エラーが出ます)。 このエラーは、次のように設定を上書きすることで回避することができます。

.eslintrc.yml(抜粋)
rules:
  import/extensions:
    - error
    - ts: never
      tsx: never
      js: never
      jsx: never
settings:
  import/resolver:
    node:
      extensions: [.ts, .tsx, .js, .jsx]

あるいは、airbnb (eslint-config-airbnb) 共有設定を使うのではなく、airbnb-typescript (eslint-config-airbnb-typescript) という共有設定を使う方法もあります。 こちらであれば、最初から TypeScript ファイルのインポートに対応しています(React にも対応しています)。 ただし、eslint --init でインストールできる共有設定は airbnb の方なので、airbnb-typescript を使いたい場合は、マニュアルで npm install する必要があります。

extends:
  - airbnb-typescript
parserOptions:
  ecmaVersion: 2021
  project: ./tsconfig.json

他にも、Standard スタイルで TypeScript を使う場合の eslint-config-standard-typescript などがあります。

extends:
  - standard-typescript
parserOptions:
  ecmaVersion: 2021
  project: ./tsconfig.json

インストール方法や、.eslintrc.* ファイルの記述方法は、各パッケージの GitHub サイトを参照してください。

(おまけ)Standard スタイルか Airbnb スタイルか

JavaScript/TypeScript の世界で一般的に採用されているスタイルは こちら で簡単にまとめていますが、個人的には、Standard スタイルのセミコロン省略はかなり楽でいいなと感じています。 単純にコードの見た目がスッキリするし、} の後ろにセミコロンを入れるか入れないかの一瞬の無駄な思考時間をゼロにできます。 一方で、もっと厳密にスタイルを定義したいのであれば、Airbnb スタイルを使うのがよいかもしれません。 Airbnb スタイルを適用した上で、セミコロンだけ省略するスタイルにするのもありですね。

.eslintrc.yml
env:
  es2021: true
extends:
  - airbnb-typescript
  # - airbnb-typescript/base # React を使わない場合
parser: "@typescript-eslint/parser"
parserOptions:
  ecmaVersion: 12
  ecmaFeatures:
    jsx: true
  project: ./tsconfig.json
plugins:
  - react
  - "@typescript-eslint"
rules:
  semi: [error, never]  # セミコロンを省略するスタイルにする
  react/react-in-jsx-scope: off  # JSX 用の React インポートエラー抑制

参考

まくろぐ
サイトマップまくへのメッセージ