Multi Vitamin & Mineral

Multi Vitamin & Mineral です。プログラムに関することを書いております。

React で TypeScript を使う環境を構築する手順(いつもどおり VSCode に ESLint と Prettier を添えます。)

React の開発環境を作る。 JavaScript ではなく TypeScript を使いたい。という場合の環境構築手順メモです。利用するのは VSCode 。 ESLint と Prettier も使ってコードのチェックやフォーマットを実行してくれるようにしておきました。

  • React
  • TypeScript
  • ESLint
  • Prettier
  • VSCode

以前、下記のような投稿をしました。こちらは React ではなかったのです。今回は下記の React 版になりますね。

multimineral-tech.com

今回は最小の設定、最小の構成を目指して環境を作りました。ここから各人の好みで調整しやすい構成にしたつもりです。参考になれば幸いです。

また、バージョンの違いによってはうまく行かないこともあるでしょう。実行時期により導入されるバージョンが変わってくると思いますので、そのあたりは適宜対応いただきたいです。(別のプロジェクトではうまく行ってたのが今回はエラーが消えなかったり、と、結構苦労しました。。。設定ミスかと思って調べたらバージョン違い(=作成時期の違い)に依るモノだった。。。)現時点でうまく行った例になりますが、その内容を漏らさず記載したつもりです。

環境情報(執筆時点)

執筆時点でのバージョンの情報を掲載しておきます。同一バージョンであれば同じ結果になる、はず。

手順開始前の環境

以下のような環境を前提とします。

種類 バージョン
windows 10 Pro
node v14.15.3
npm 6.14.9
VSCode 1.52.1
VSCode Extension / ESLint v2.1.14
VSCode Extension / Prettier - Code formatter v5.8.0
GitBash (GNU bash) version 4.4.23(1)-release

このあたりのツールの導入は過去記事を参照してもらえるとありがたいです。

multimineral-tech.com

multimineral-tech.com

multimineral-tech.com

手順実施後の結果

前述の環境を前提にして、当記事の作業(つまりこの後の文章にある作業)を行った最終結果を参考までに掲載しておきます。

バージョン情報は ./package.json に記載されますので、そちらの一部を抜粋して掲載します。

// package.json
{
  // 中略
  "dependencies": {
    "@testing-library/jest-dom": "^5.11.6",
    "@testing-library/react": "^11.2.2",
    "@testing-library/user-event": "^12.6.0",
    "@types/jest": "^26.0.19",
    "@types/node": "^12.19.11",
    "@types/react": "^16.14.2",
    "@types/react-dom": "^16.9.10",
    "react": "^17.0.1",
    "react-dom": "^17.0.1",
    "react-scripts": "4.0.1",
    "typescript": "^4.1.3",
    "web-vitals": "^0.2.4"
  },
  // 中略
  "devDependencies": {
    "@typescript-eslint/eslint-plugin": "^4.11.0",
    "@typescript-eslint/parser": "^4.11.0",
    "eslint": "^7.16.0",
    "eslint-config-airbnb": "^18.2.1",
    "eslint-config-prettier": "^7.1.0",
    "eslint-plugin-import": "^2.22.1",
    "eslint-plugin-jsx-a11y": "^6.4.1",
    "eslint-plugin-prettier": "^3.3.0",
    "eslint-plugin-react": "^7.21.5",
    "eslint-plugin-react-hooks": "^4.2.0",
    "prettier": "^2.2.1"
  }
}

React with TypeScript の準備

React の環境は create-react-app を使って構築することにします。

create-react-app の実行

npx create-react-app (任意のプロジェクト名) --template typescript で TypeScript を使った React プロジェクトが作成できます。

私の環境では npx create-react-app だけだとうまく動かなかったので、グローバルに create-react-app をインストールしてから実行しました。 create-react-app のインストールはしなくて済むならそれに越したことはないと思いますので、飛ばせるなら飛ばしちゃってください。

### 下記コマンドは最初は実行しないで試してみましょう。
$ npm install -g create-react-app
C:\Program Files (x86)\Nodist\bin\create-react-app -> C:\Program Files (x86)\Nodist\bin\node_modules\create-react-app\index.js
+ create-react-app@4.0.1
added 67 packages from 25 contributors in 5.529s
$ create-react-app --version
4.0.1
### 最初は下記コマンドからスタートしましょう。
### もしエラーになるようなら「npm install -g create-react-app」を実行してから
### 再び下記コマンドを試してみましょう。
$ npx create-react-app sample-project --template typescript

任意ではありますが、以下のコマンドで実行を確認してもよいでしょう。ブラウザが立ち上がると思います。

$ cd sample-project
$ npm start

補足 : create-react-app のオプション

ちょっと古い記事だと npx create-react-app (任意のプロジェクト名) --typescript というオプションを使っている説明があります。今は公式サイトにて --template typescript を使うように指定されているので、こちらを使いましょう。

create-react-app.dev

ちなみに、公式サイトでは npm install -g create-react-app は止めとけと書かれています。。。いや、やらずに動くんならやりたくないんですが、まあ、動かないのはしょうがないので私の環境ではやっちゃってます。

あと、「 npm install --save typescript @types/node @types/react @types/react-dom @types/jest というコマンドも実行しとけ」と書かれていますが、特に実行しなくてもこれらは導入されますね。私は実行しませんでしたが、ちゃんと入っているか package.json の確認はしておいて良いかも知れませんね。

ESLint の導入と設定

続いて ESLint を導入し、設定を行いましょう。

VSCode で開く

[ファイル] > [フォルダーを開く] より、作成したプロジェクトのフォルダーを指定して開きます。(今回の例だと「sample-project」フォルダーです。)(エクスプローラで右クリックから「Code で開く」でも良し。)

その後、 ctrl + @ などで、下部にコンソールを開いておくと良いです。

ESLint の導入

ESLint は npx eslint --init で導入できます。プロジェクトの直下にてこのコマンドを入力し、各種設定を選択します。

選択した内容についてはインラインで記載していますが、「airbnb」の選択と「設定ファイルを JavaScript とする」部分の選択は好みでよいと思います。その2つ以外は下記の通りになっちゃうと思います。

$ npx eslint --init
### To check syntax, find problems, and enforce code style を選択
√ How would you like to use ESLint? · style       
### JavaScript modules (import/export) を選択
√ What type of modules does your project use? · esm
### React を選択
√ Which framework does your project use? · react
### Yes を選択
√ Does your project use TypeScript? · No / Yes
### Browser を選択
√ Where does your code run? · browser
### Use a popular style guide を選択
√ How would you like to define a style for your project? · guide
### Airbnb: https://github.com/airbnb/javascript を選択
√ Which style guide do you want to follow? · airbnb      
### JavaScript を選択
√ What format do you want your config file to be in? · JavaScript
...(中略)...
### Yes を選択
√ Would you like to install them now with npm? · No / Yes
...(中略)...
+ eslint-config-airbnb@18.2.1
+ eslint-plugin-jsx-a11y@6.4.1
+ eslint-plugin-react@7.21.5
+ eslint-plugin-react-hooks@4.2.0
+ eslint-plugin-import@2.22.1
+ eslint@7.16.0
+ @typescript-eslint/parser@4.11.0
+ @typescript-eslint/eslint-plugin@4.11.0
added 2 packages from 3 contributors, updated 7 packages and audited 1953 packages in 14.141s
...(中略)...
ESLint was installed locally. We recommend using this local copy instead of your globally-installed copy.

補足 : ESLint 関連プラグインの導入

他の記事によっては以下のコマンドを打つべしってありましたが、2020/12現在では不要みたいです。 npx eslint --init で一緒にインストールされましたね。まあ、やっても問題にはならないとおもいますが。

$ yarn add -D eslint-plugin-react @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-config-airbnb eslint-plugin-jsx-a11y eslint-plugin-import

ESLint の設定

React, TypeScript の環境にあった内容に変更します。

// .eslintrc.js
module.exports = {
  env: {
    browser: true,
    es2021: true,
    jest: true,        // <=ADD
  },
  extends: [
    'plugin:react/recommended',
    'airbnb',
  ],
  parser: '@typescript-eslint/parser',
  parserOptions: {
    ecmaFeatures: {
      jsx: true,
    },
    ecmaVersion: 12,
    sourceType: 'module',
  },
  plugins: [
    'react',
    '@typescript-eslint',
  ],
  rules: {
    // ↓↓↓ADD↓↓↓
    'no-use-before-define': 'off',
    '@typescript-eslint/no-use-before-define': ['error'],
    '@typescript-eslint/no-unused-vars': 'error',
    'react/jsx-filename-extension': ['error', { extensions: ['.jsx', '.tsx'] }],
    'import/extensions': [
      'error',
      { extensions: ['.js', '.jsx', '.json', '.ts', '.tsx'] },
    ],
    'react/prop-types': 'off',
    'spaced-comment': ['error', 'always', { markers: ['/ <reference'] }],
    // ↑↑↑ADD↑↑↑
  },
  // ↓↓↓ADD↓↓↓
  settings: {
    'import/resolver': {
      node: {
        extensions: ['.js', '.jsx', '.ts', '.tsx'],
      },
    },
  },
  // ↑↑↑ADD↑↑↑
}

env:jest: true がないと、テストに対して 'test' is not defined no-undef と怒られます。入れておきましょう。

stackoverflow.com

import 文にて 'React' was used before it was defined no-use-before-define と怒られることがあるので、 rules: の先頭2行に no-use-before-define に関する設定を入れています。なんだかバージョンによってはうまく動くよってな意見もありましたので、環境によっては不要かもしれません。

stackoverflow.com

他にも、 rules:settings: については追記した量が多いのですべての説明は省きます。

ESLint のコマンド実行

TypeScript のファイルを対象に ESLint を試しに実行してみます。コマンドは npx eslint . --ext .tsx --ext .ts です。

$ npx eslint . --ext .tsx --ext .ts

(略)\src\App.tsx
  11:16  error  `code` must be placed on a new line                          react/jsx-one-expression-per-line
  11:40  error  ` and save to reload.        ` must be placed on a new line  react/jsx-one-expression-per-line

...(中略)...

✖ 6 problems (6 errors, 0 warnings)
  6 errors and 0 warnings potentially fixable with the `--fix` option.

6つのエラーが出ました。「fixable with the --fix option.」とある通り --fix オプションを付けると強制修正を行ってくれます。この後 Prettier を入れますので、いま時点ではそのままにしておきます。

一点、「code must be placed on a new line」の指摘だけ直しちゃいます。

// ./src/App.tsx
// 修正前
        <p>
          Edit <code>src/App.tsx</code> and save to reload.
        </p>
// 修正後
        <p>Edit >src/App.tsx and save to reload.</p>

どのみち削除してしまうコードですので放ったらかしでも良いんですが、 ESLint がうるさいので <code> を削ってしまいます。まあ別に今やらなくてもいいとは思ってますが。

Prettier の導入と設定

続いて Prettier を導入し、設定を行いましょう。

Prettier の導入

Prettier および ESLint と連携するためのライブラリを導入します。

$ npm install ---save-dev prettier eslint-config-prettier eslint-plugin-prettier

ESLint の Prettier に関する設定

ESLint の設定を見直します。

// .eslintrc.js
module.exports = {
  env: {
    browser: true,
    es2021: true,
    jest: true,
  },
  extends: [
    'plugin:react/recommended',
    'airbnb',
    'plugin:prettier/recommended',         // <=ADD
    'prettier/@typescript-eslint',         // <=ADD
  ],
  parser: '@typescript-eslint/parser',
  parserOptions: {
    ecmaFeatures: {
      jsx: true,
    },
    ecmaVersion: 12,
    sourceType: 'module',
  },
  plugins: [
    'react',
    '@typescript-eslint',
    'prettier',                    // <=ADD
  ],
  rules: {
    'no-use-before-define': 'off',
    '@typescript-eslint/no-use-before-define': ['error'],
    '@typescript-eslint/no-unused-vars': 'error',
    'react/jsx-filename-extension': ['error', { extensions: ['.jsx', '.tsx'] }],
    'import/extensions': [
      'error',
      { extensions: ['.js', '.jsx', '.json', '.ts', '.tsx'] },
    ],
    'react/prop-types': 'off',
    'spaced-comment': ['error', 'always', { markers: ['/ <reference'] }],
    'prettier/prettier': 'error', // <=ADD
  },
  settings: {
    'import/resolver': {
      node: {
        extensions: ['.js', '.jsx', '.ts', '.tsx'],
      },
    },
  },
}

plugins: に Prettier を、 extends: には、 ESLint と Prettier を連動させるためのプラグインを追記しています。

rules: に追加した 'prettier/prettier': 'error', これなんですが、「Prettier の全ルールを一発で全部追加するぜ!」という意味です。全部まとめて error として追加しています。(個別にレベルを設定できないという問題があるってことになりますね。これで困ったことはありませんが。)

qiita.com

Prettier に関する設定

さて、その ESLint と連動させた Prettier 自身の設定をしていきましょう。

まずは設定ファイルを用意します。

$ touch .prettierrc.json

設定ファイルの中身は以下のようにしておきます。ここらへんは好みでいいと思いますが、以下は、私が最小限で良さそうなものを用意したつもりです。設定内容は好みで変えてください。(セミコロンは無い方が好きな人が多そう。)

// .prettierrc.json
{
  "endOfLine": "lf",
  "semi": true,
  "singleQuote": true,
  "tabWidth": 2,
  "trailingComma": "es5"
}

補足 : VSCode は再起動しておくと吉

次項では Prettier のプラグインについて書いていますが、もし既にインストール済みであったなら、エディタ上のエラーの表示がおかしくなっているのではないでしょうか? いや、おかしくなかったら良いんですが。。。

私は VSCode の再起動で表示が正されたので、取り敢えず再起動してみると良いかもしれません。いや、おかしくなかったら良いんですが。。。

ESLint のコマンド実行(Prettier 付き)

Prettier を連動させた状態で試しに実行してみましょう。

$ npx eslint . --ext .tsx --ext .ts

(略)\src\react-app-env.d.ts
  1:40  error  Delete `␍`  prettier/prettier

✖ 1 problem (1 error, 0 warnings)
  1 error and 0 warnings potentially fixable with the `--fix` option.

なんか改行コードがおかしいっぽいですね。

ファイルを開いて直接修正してもよいですが、試しに強制修正を実施してみましょう。

$ npx eslint . --ext .tsx --ext .ts --fix

これでエラーが消えました。

VSCode の設定

プラグインの導入

毎回 npx eslint ... コマンドを打つのもいいですが、自動でチェックしてコード上に表示してくれると嬉しいです。そのために ESLint と Prettier のプラグインを導入します。

プラグインの導入方法は下記に書きましたので割愛します。(プラグイン入れるだけなので大した話ではないですが。。。)

multimineral-tech.com

プラグインの利用を促す

VSCode ではプロジェクトにて推奨するプラグインの利用を促すことができます。 .vscode/extensions.jsonを書いておけばVSCodeでプロジェクトを開いた時に推奨プラグインとして出せます。

まずはファイルを用意します。

$ mkdir .vscode
$ touch .vscode/extensions.json

次に、利用を促すプラグインを記載します。

// .vscode/extensions.json
{
  "recommendations": ["dbaeumer.vscode-eslint", "esbenp.prettier-vscode"]
}

もし、プラグインが入っていない場合は VSCode から以下のような催促が入ります。

プラグインの利用を促す
プラグインの利用を促す

インストールボタンを押せば、2つのプラグインがインストールされます。

ファイル保存時に強制的に --fix をかける

npx eslint (...略...) --fix で強制修正ができました。この修正をファイル保存時に実行されるよう設定します。

まずは設定ファイルを用意します。

$ touch .vscode/settings.json

次に、ファイル保存時に設定する内容を記載します。(他の設定も混じってます。)

// .vscode/settings.json
{
  "editor.codeActionsOnSave": {
  "source.fixAll.eslint": true
  },
  "eslint.format.enable": true,
  "files.eol": "\n"
}

上記はファイルを touch で作成しましたが、以下の過去記事では、

multimineral-tech.com

次に VSCode の設定を行います。 Ctrl + , で設定を開き、 Workspace タブにして、 code action on save で検索します。GUIでそのまま設定したいところですが、ここでは「Edit in setting.json」をクリックします。すると .vscode/setting.json が生成され、このファイルが開きます。

という説明をしました。どちらも結果は同じになりますので、お好きな方法で設定ファイルを用意してください。

ESLint をファイル保存で実行

それでは VSCode に設定した内容が反映されたか試してみましょう。

何でもいいのですが、取り敢えず App.tsx の1行目のセミコロンを外して、それから保存をしてみます。

// ./src/App.tsx
// 試しに修正
import React from 'react'  // 最後のセミコロンを外す
// Ctrl + s で保存する
import React from 'react'; // 自動でセミコロンが付与された

セミコロンが自動で付与されたら成功です。