15
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

NIJIBOXAdvent Calendar 2020

Day 19

React+TypeScript環境にESLint+Prettierを導入する

Last updated at Posted at 2020-12-18

みなさま初めまして。
ニジボックスに入社し、フロントエンドエンジニアを名乗り始めてから約1年が経ちました。

4ヶ月前くらいまで、Lintって何!?って感じであんまり良さを感じていなかった(というか何者か分かっていなかった)(というか既に案件のリポジトリには導入されていたので何も考えずに使っていた)ので、せっかくの機会なので調査してみました。
React+TypeScript環境にESLint+Prettierを導入するまでの手順にして備忘としてまとめてみます。

create-react-app

create-react-appを使えばコマンド一つでReactを書き始めることができます。
--template typescriptオプションを付けなければJSでも書けます。
ts-appの部分はお好きなプロジェクト名に変更してください。

npx create-react-app ts-app --template typescript

Prettier

Prettierはコードを自動整形するツールです。
ESLintにもコードフォーマットの機能はあるんですが、Prettierの方がコードフォーマットとしては優秀なようなので、ESLintとPrettierを併用するのが主流のようです。
なにはともあれ、Prettierをインストールしましょう。

npm install --save-dev prettier

Prettierの設定ファイルを作成

.prettierrc.yml
---
printWidth: 80
tabWidth: 2
singleQuote: true
trailingComma: none
jsxBracketSameLine: true
semi: false
arrowParens: avoid
  • printWidth 折り返しをする行の長さを指定(公式曰くおすすめは80文字なので従います)
  • semi 行の最後にセミコロンをつけるかどうか指定
  • arrowParens 引数が1つの時にはカッコを省略するかどうか

などなど、公式に指定できるオプションは詳しく載っています。この辺りはお好みでどうぞ。

いったん動作確認

package.jsonに以下のscriptを追加してきちんと動作するか確認してみます。

package.json
{
  "scripts": {
    "fix:prettier": "prettier --write src",
    "lint:prettier": "prettier --check src"
  }
}

ESLint

これってなんて読んでますか?
ミスチル的には「エス」なんですが、やっぱり「イーエス」が正しいんでしょうか。

ちなみにESLintは、JavaScriptのための静的検証ツールで、コードを実行する前に明らかなバグを見つけたり、括弧やスペースの使い方などのスタイルを統一するために使用されます。
先述の通り、ESLintでもコードを自動的に修正することはできますが、自動整形という点においてはPrettierの方が優れているため、コードの構文チェックはESLintが行い、コードの整形はPrettierに任せたいと思います。

ただし、この自動整形は、括弧が足りなかったり、カンマが足りなかったりした場合に自動で追加してくれるなんてことはないので、そこは自分で整えてあげる必要があります。

では以下のコマンドを実行して、ESLintを導入します。

npx eslint --init
ESLintをどのように使用しますか
? 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
あなたのプロジェクトはどんな種類のモジュールを使っていますか
❯ JavaScript modules (import/export)
  CommonJS (require/exports)
  None of these
プロジェクトで使用しているフレームワークはどれですか
? Which framework does your project use? … 
❯ React
  Vue.js
  None of these
プロジェクトはTypeScriptを使用していますか
? Does your project use TypeScript? › Yes
コードはどこで実行されますか
? Where does your code run? …  (Press <space> to select, <a> to toggle all, <i> to invert selection)
✔ Browser
  Node
プロジェクトのスタイルをどのように定義しますか
? 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)
どのスタイルガイドに従いたいですか
? 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
設定ファイルをどの形式にしますか
? What format do you want your config file to be in? … 
❯ JavaScript
  YAML
  JSON
関連する必要なパッケージをnpmでインストールするか
? Would you like to install them now with npm? › Yes

パッケージを全てインストールし終わったら、
追加で、Prettierとの連携用のパッケージを導入します。

npm install --save-dev eslint-config-prettier eslint-plugin-prettier
  • eslint-config-prettier
    Prettierと競合する可能性のあるESLintのルールをすべてオフにする

  • eslint-plugin-prettier
    ESLint上でPrettierを動作させるために使用する

ESLintの設定ファイルを編集する

インストールが終わったら、ルートディレクトリに.eslintrc.jsファイルが作成されているのでこちらを編集していきます。

.eslintrc.js
module.exports = {
  // ソースコードが対象としている環境
  // ここの指定によって使えるクラスや関数の種類が変わる
  env: {
    browser: true,
    es2021: true
  },
  // 設定をまとめて変更する場合はextendsに記述する
  // 配列の0番目から順番に上書きされるため、Prettier関連の記述は最後に追加する
  extends: [
    'airbnb',
    'airbnb/hooks',
    'eslint:recommended',
    'plugin:react/recommended',
    'plugin:@typescript-eslint/recommended',
    'prettier',
    'prettier/@typescript-eslint'
  ],
  parser: '@typescript-eslint/parser',
  parserOptions: {
    ecmaFeatures: {
      jsx: true
    },
    ecmaVersion: 12,
    sourceType: 'module'
  },
  // 機能を追加するプラグインを記述する
  plugins: ['react', '@typescript-eslint', 'prettier'],
  // プロジェクト内部で個別に機能を切り替えたい時はrulesに記述する
  rules: {
    'no-use-before-define': 'off',
    '@typescript-eslint/no-use-before-define': ['error'],
    'react/jsx-filename-extension': 'off',
    'react/jsx-closing-bracket-location': [
      'error',
      { selfClosing: 'tag-aligned', nonEmpty: 'after-props' }
    ],
    'react/jsx-one-expression-per-line': 0,
    'import/no-unresolved': ['off', { caseSensitive: true }],
    'import/extensions': 'off'
  },
  settings: {
    react: {
      version: 'detect'
    }
  }
}

  • **extends**は、ESLintのルールのON/OFFを設定するもので、例えば'eslint:recommended'は、推奨設定(チェックマークがついているもの)を全てONにする役割を持っています。それが、配列の0番目から上書きされていきます。

  • **plugins**は、ルールそのものを追加できます。
    上に入っていないものでも、例えば

    • eslint-plugin-immutable JavaScriptのすべてのミューテーションを無効にするESLintプラグインです。今回は入れていませんが、Reactで書くなら入れた方が良さそうな気がする
    • eslint-plugin-import import/export構文をサポートし、ファイルパスとインポート名のスペルミスの問題を防ぐことができるのでぜひ入れたい

いったん動作確認(パート2)

ESLint単体でもきちんと動作するか確認しておきましょう。

package.json
{
  "scripts": {
    "fix": "run-s fix:prettier fix:eslint",
    "fix:eslint": "eslint src --ext .ts,tsx --fix",
    "lint": "run-p lint:prettier lint:eslint",
    "lint:eslint": "eslint src --ext .ts,tsx",
  }
}

VSCode

VSCodeで使用する場合、保存時に自動整形されるように設定ファイルを作成します。
以下のように記述することで、ESLintのルールで自動整形されるようになります。

.vscode/extensions.json
{
  "recommendations": [
    "streetsidesoftware.code-spell-checker"
  ],
  "unwantedRecommendations": []
}
.vscode/settings.json
{
  "eslint.lintTask.enable": true,
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true
  },
  "editor.formatOnSave": true,
  "editor.defaultFormatter": "esbenp.prettier-vscode"
}

また、tsconfig.jsonで下記のようなエラーが出ている場合があります。
Cannot use JSX unless the '--jsx' flag is provided

tsconfig.json
{
  "compilerOptions": {
    "jsx": "react-jsx"
           ~~~~~~~~~~~
  },
}

VSCodeで古いバージョンのTypeScriptを使用している可能性があるので、以下の手順でバージョンを変更します。

  • コマンドパレットに移動(Control + Shift + P)
  • 「TypeScript:TypeScriptバージョンを選択...」を選択
  • 「ワークスペースバージョンを使用」を選択(4.1.3)

tsconfig.jsonは、TypeScriptで記述されたコードをJavaScriptにコンパイルする際のルールが記述されたファイルです。
詳しくは公式へどうぞ。

おまけ

ESLintの警告を特定のコードだけ除外したい場合

変数名の規則はcamelCaseだが、サーバーのレスポンスのみsnake_caseを許容したい場合など、特定の行やブロック内のみ警告を除外したい場合には、下記のようにコメントを入れることで無効化できます。

// eslint-disable-next-line camelcase
const { status_code } = await res.json();
/* eslint-disable camelcase */

const { status_code } = await res.json();

/* eslint-enable camelcase */

以上、ここまで来れば、あなたがエディター上でどんなに汚いコードを書いたとしても、Lintが綺麗に整頓してくれるようになっているでしょう👏
みなさま良いクリスマスを〜

15
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?