🧸

React+TypeScript+ESLint+Prettierをまとめて環境構築

2021/07/16に公開

環境構築をしっかりするメリット

正直な話、React+TypeScriptは公式にあるコマンドを一個打ち込めばプロジェクト自体は出来ます。
環境構築がめんどくさくてそれだけで済ませていた人も多いと思いますが、今回紹介する環境構築をする事で、様々なメリットがあります。

  1. チーム制作などでコーディングルールを厳格化できる
    ->チーム一人一人が我流のコーディングをすると誰も読み取る事が出来ないモノが完成します。
  2. 初心者のうちからコーディングの変な癖をなくす
    ->初心者のうちから変な癖がついてしまうと、修正するのが大変です。
  3. コーディングの穴をなくす
    ->JavaScript自体はとてもルールが甘い言語です、よって我流でやった結果セキュリティの穴ができる事もあります。そういった、ミスを減らす事が出来ます。
  4. 綺麗なコードが完成する
    ->自分のコードが綺麗になりますので、公開しても恥ずかしく無くなります。

などなど、
様々なメリットが挙げられます。
一回環境構築の流れを知れば、簡単になりますので是非やってみてください。

環境構築の注意点

バージョンや細かい仕様はいつ変わるか分かりません。
明日にでも今の環境構築がエラーになる可能性があります。
エラーコードを送っていただければ、答えれる範囲でお答えしますが、Googleさんとお友達になる事をオススメします。
ちなみに、今回紹介する各バージョンは
React -> 17.0.2
TypeScript -> 4.1.2
ESLint -> 7.2.0
Prettier -> 2.3.2
es2021
これらを使用しています。

全部まとめて環境構築

React+TypeScriptのプロジェクトを作成

npx create-react-app my-app --template typescript

このコマンドでTypeScriptを使用したReactプロジェクトを作成出来ます。
公式でyarnを使ったインストール方法もありますが、最近はnpxでのインストールが主流になってきています。
https://create-react-app.dev/docs/adding-typescript/

お馴染みのこれが出れば成功です!

ESLintのインストール

初期設定をまとめてしてくれる--initを使ってインストールします。

yarn run eslint --init

公式サイトで他のインストール方法も載っていますので、好みに合わせて使うといいと思います。
https://eslint.org/docs/user-guide/getting-started

初期設定を選択する

  1. How would you like to use ESLint?

To check syntax, find problems, and enforce code style

  1. What type of modules does your project use?

JavaScript modules(import/expoer)

  1. Which framework does your project use?

React

  1. Does your project use TypeScript?

Yes

  1. Where does your code run?

Browser

  1. How would you like to define a style for your project?

Use a popular style guide

  1. Which style guide do you want to follow?

Airbnb

  1. What format do you want your config file to be in?

JavaScript

  1. Would you like to install them now with npm?

Yes

選択項目の解説

最後、このような表示になっていれば大丈夫です!

7番の項目は好きなものを選択すれば大丈夫です。
Standardが基本的なものでAirbnbが一番厳しいチェックをしてくれるのでオススメです!
8番の項目も同様で好きなもので大丈夫ですが、今後の設定の仕方が多少変わりますので注意です。
個人的にですが、JavaScriptが1番分かりやすいと思います。
JSONの設定マニュアルもネットで結構あるので扱いやすいです。

ESLintの追加パッケージをインストール

まずは、TypeScript用の追加パッケージをインストールします。

yarn add -D @typescript-eslint/eslint-plugin @typescript-eslint/parser

Airbnbの細かい設定をしてくれるパッケージをインストール

npx install-peerdeps --dev eslint-config-airbnb

Yarn使ってるん?みたいな感じな事を聞かれますのでyを押せばインストールがスタートします。


Yes

Prettierのインストール

Prettierのパッケージをインストールします。

yarn add -D prettier eslint-config-prettier

ESLintとPrettierの設定

.eslinyrc.jsでESLintの設定ををします。
ある程度設定をしますが、不要な部分の削除や必要な設定を追加してください

.eslintrc.js
module.exports = {
  env: {
    browser: true,
    es2021: true,
  },
  extends: [
    'plugin:react/recommended',
    'airbnb',
+   'airbnb/hooks',
+   'plugin:@typescript-eslint/recommended',
+   'plugin:@typescript-eslint/recommended-requiring-type-checking',
+   'prettier',
  ],
  parser: '@typescript-eslint/parser',
  parserOptions: {
    ecmaFeatures: {
      jsx: true,
    },
    ecmaVersion: 12,
    sourceType: 'module',
+   tsconfigRootDir: __dirname,
+   project: ['./tsconfig.json'],
  },
  plugins: [
    'react',
    '@typescript-eslint',
  ],
+ "ignorePatterns": [
+   ".eslintrc.js"
+ ],
  rules: {
+   'no-use-before-define': "off",
+   "@typescript-eslint/no-use-before-define": "off",
+   'import/prefer-default-export': "off",
+   'import/extensions': [
+       'error',
+       {
+         js: 'never',
+         jsx: 'never',
+         ts: 'never',
+         tsx: 'never',
+       },
+     ],
+     'react/jsx-filename-extension': [
+       'error',
+       {
+         extensions: ['.jsx', '.tsx'],
+       },
+     ],
+     'react/react-in-jsx-scope': 'off',
+     'no-void': [
+       'error',
+       {
+         allowAsStatement: true,
+       },
+     ],
+ },
+ settings: {
+   'import/resolver': {
+     node: {
+       paths: ['src'],
+       extensions: ['.js', '.jsx', '.ts', '.tsx']
+     },
+   },
  },
};

.prettierrc.jsという名前のファイルをプロジェクト直下に作成してください。
このファイルの設定がPrettierに適応されます。
コピペで大丈夫ですが、こちらも不要な部分の削除と必要な設定の追加をしてください

.prettierrc.js
module.exports = {
  printWidth: 120,
  singleQuote: true,
  semi: false,
}

.eslintignoreというファイルをプロジェクト直下に作成してください
ESLintを適用しないファイルの指定をします
こちらもコピペで大丈夫です

.eslintignore
build/
public/
**/node_modules/
*.config.js
.*lintrc.js
/*.*

package.jsonに以下の設定を追加してください。
これで、yarn run lintyarn run fixといったコマンドが使用できるようになります。

package.json
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
+   "lint": "eslint --ext .ts,.tsx ./src",
+   "fix": "yarn format && yarn lint:fix",
+   "format": "prettier --write 'src/**/*.{js,jsx,ts,tsx}'",
+   "lint:fix": "eslint --fix 'src/**/*.{js,jsx,ts,tsx}'"
  },

デフォルトのエラーコードを調整&削除

React17からimport Reactを書く必要が無くなりました
エラーになるのでこの一文を削除します。

App.test.tsx
- import React from 'react';

先程と同様の削除と記述の書き換えをします。

App.tsx
- import React from 'react';
+ import { VFC } from 'react';

- function App() {
+ const App: VFC = () => (
- return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.tsx</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
- }

型定義しろよーみたいなエラーが出るのでvoidを設定します

reportWebVitals.ts
- const reportWebVitals = (onPerfEntry?: ReportHandler) => {
+ const reportWebVitals = (onPerfEntry?: ReportHandler): void => {
  if (onPerfEntry && onPerfEntry instanceof Function) {
-   import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
+   void import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
      getCLS(onPerfEntry);
      getFID(onPerfEntry);
      getFCP(onPerfEntry);
      getLCP(onPerfEntry);
      getTTFB(onPerfEntry);
    });
  }
};

終わりに

文章ばかりで分かりにくい部分もあると思います。
GitHubで設定のソースコードを公開していますので、是非ご活用ください。
https://github.com/AsaneJP/React-TS-ESlint-Prettier.git
最初は面倒でやる意味あるの?と思うと思いますが、最初のうちに変なコーディングの癖を減らす事でより効率の良いコーディングが可能になります。
最初に慣れてしまえば、あとは簡単な環境構築なのでやってみてください。

Discussion