【VSCode】ReactとTypeScript、ESLint、Prettier、Airbnbで環境構築する手順
今回はVSCodeでReactとTypeScript、ESLint、Prettier、Airbnbの環境構築について説明します。
前提条件は以下
- creat-react-appを使ってReact、TypeScriptの環境を作る
- ESLintとPrettierを追加して、VSCode上の拡張機能と連動させる
- AirbnbでESLintのルールを拡張して、チェック機能を強化
環境は以下です。
- macOS Catalina v10.15.5
- Visual Studio Code v1.57.0
- React v17.0.2
- TypeScript v4.5.5
- node.js v16.13.1
ReactとTypeScriptの環境構築する流れ
Reactの環境構築には公式でも紹介されているcreat-react-appを使い、そこにTypeScriptを追加します。ESLintでソースエラーのチェック、Prettierで自動フォーマット設定、 AirbnbでESLintのルール拡張してチェック機能を強化します。
creat-react-appについては以下をどうぞ。
ReactとTypeScriptをインストール
creat-react-appを使ってReactとTypeScriptをインストールします。すでにVSCode上で環境構築したいディレクトリに移動している場合は、以下のコマンドでそのディレクトリにインストールできます。
npx create-react-app ./ --template typescript
環境構築したいディレクトリを作成して、そこにインストールしたい場合は以下です。例として【react-typescript-starter】というディレクトリを作った場合です。
npx create-react-app react-typescript-starter --template typescript
正しくインストールできるとVSCode上は以下のように表示されてるはずです。
ESLintに関わるパッケージをインストール(Airbnbを含む)
creat-react-appにはデフォルトでESLintがインストールされていますが、ESLintの細かい設定をしていく必要があります。
ESLintの設定するために以下のコマンドを打ちます。
npm init @eslint/config
次は「ESLintをどのように使うか」聞かれます。以下の3つの選択肢がありますが、一番下のものを選択します。
- To check syntax only → 構文のチェックのみ
- To check syntax and find problems → 構文のチェックと問題の発見
- To check syntax, find problems, and enforce code style → 構文のチェックと問題の発見、コードの適用
? 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
「どのタイプのモジュールを使うか」聞かれます。以下の3つの選択肢がありますが、一番上のJavaScript modulesを選択します。
- JavaScript modules (import/export)
- CommonJS (require/exports)
- None of these
? What type of modules does your project use? …
> JavaScript modules (import/export)
CommonJS (require/exports)
None of these
「使うフレームワークはどれか」聞かれます。Reactを選択します。
- React
- Vue.js
- None of these
? Which framework does your project use? …
> React
Vue.js
None of these
「TypeScriptを使うか」聞かれます。使うのでYesを選択。
- Yes
? Does your project use TypeScript > No/ Yes
「コードはどこで実行するか」聞かれます。今回はReactなのでBrowserを選択。
- Browser
- Node
? Where does your code run? …
> Browser
Node
「プロジェクトに使うスタイルをどのように決めるか」聞かれます。一番上に人気のあるスタイルガイドを選択。
- Use a popular style guide
- Answer questions about your style
- Inspect your JavaScript file(s)
? 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)
「どのスタイルガイドを選択するか」聞かれます。以下の4つがある中で一番上のAirbnbを選択。
- 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
? 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
「ESLintの設定ファイルはどの形式が良いか」聞かれます。JavaScript形式を選択。
- JavaScript
- YAML
- JSON
? What format do you want your config file to be in? …
❯ JavaScript
YAML
JSON
「これらのパッケージをnpmで今インストールするか」聞かれます。Yesを選択することで、必要なパッケージと.eslintrc.jsが作成されます。
- Yes
? Would you like to install them now with npm? › No / Yes
作成された.eslintrc.jsを確認するとデフォルトでは以下のようになっています。
package.jsonを確認すると、あたらしくインストールされたパッケージが確認できます。
- @typescript-eslint/eslint-plugin … ESLintにTypeScriptのルールを追加
- @typescript-eslint/parser … ESLintでTypeScriptの解析をする用
- eslint … ESLint本体
- eslint-config-airbnb … ESLintにAirbnbスタイルを追加
- eslint-plugin-import … ESLintにES Modulesのルールを追加
- eslint-plugin-jsx-a11y … ESLintにJSXのルールを追加
- eslint-plugin-react … ESLintにReactのルールを追加
- eslint-plugin-react-hooks … ESLintにReact Hooksのルールを追加
足りないパッケージをインストール
追加でAirbnbをTypeScriptで強化するためにeslint-config-airbnb-typescriptをインストールしておきます。
npm i --save-dev eslint-config-airbnb-typescript
さらに使っていないimportを自動で削除するためにeslint-plugin-unused-importsをイストールしておきます。
npm i --save-dev eslint-plugin-unused-imports
Prettierのインストール
Prettierをインストールします。ESLintと一緒に使用することでESLintにルールに沿ってフォーマットしてくれるので便利です。
npm i --save-dev prettier eslint-config-prettier
インストールできたら、.prettierrc.jsという名前のファイルを作成してお好みの設定を書きます。以下は例です。
module.exports = {
printWidth: 120, //1行の文字列を120文字にする
singleQuote: true, //ダブルに代わりシングルクオーテーションを使う
semi: true, //行末にセミコロンを追加
trailingComma: 'es5', //複数行の場合は可能な限り末尾のカンマを表示
tabWidth: 2, //タグのスペース2 デフォルトは2
useTabs: false, //スペースをタブに代える デフォルトはfalse
}
設定できるオプションについては以下をどうぞ。
ESLintの詳細設定を書く
.eslintrc.jsにESLintの詳細設定を追記していきます。
module.exports = {
env: {
browser: true,
es2021: true,
},
extends: [
//'plugin:react/recommended', airbnbにほど設定されているので削除可能
'airbnb',
'airbnb-typescript', //追加
'airbnb/hooks', //追加
'plugin:@typescript-eslint/recommended', //型を必要としないプラグインの推奨ルールをすべて有効
'plugin:@typescript-eslint/recommended-requiring-type-checking', //型を必要とするプラグインの推奨ルールをすべて有効
'prettier', //追加 ESLintの情報に沿ってフォーマット
],
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaFeatures: {
jsx: true,
},
ecmaVersion: 12, //latestから12に変更
sourceType: 'module',
tsconfigRootDir: __dirname, //追加 tsconfig.jsonがある相対パスを指定
project: ['./tsconfig.json'], //追加 tsconfig.jsonを指定
},
plugins: [
'react',
'@typescript-eslint',
'unused-imports' //追加 使っていないimportを自動で削除用
],
ignorePatterns: ['build'], //追加 .eslintignoreに対象外にしているが無いとコンパイルに時間がかかる
/*-- ↓以下追加 --*/
rules: {
'no-use-before-define': 'off', //関数や変数が定義される前に使われているとエラーになるデフォルトの機能をoff
'@typescript-eslint/no-use-before-define': ["error"], //typescript側のno-use-before-defineを使うようにする
'import/prefer-default-export': 'off', //named exportがエラーになるので使えるようにoff
'@typescript-eslint/no-unused-vars': 'off', //unused-importsを使うため削除
'unused-imports/no-unused-imports': 'error', //不要なimportの削除
'unused-imports/no-unused-vars': [ //unused-importsでno-unused-varsのルールを再定義
'warn',
{ vars: 'all', varsIgnorePattern: '^_', args: 'after-used', argsIgnorePattern: '^_' },
],
'react/function-component-definition': [//アロー関数以外受け付けない設定
2,
{
namedComponents: 'arrow-function',
unnamedComponents: 'arrow-function',
},
],
'no-param-reassign': [2, { props: false }], //パラメーターのプロパティ変更を許可
'import/extensions': [ //importのときに以下の拡張子を記述しなくてもエラーにしない
'error',
{
js: 'never',
jsx: 'never',
ts: 'never',
tsx: 'never',
},
],
'react/jsx-filename-extension': [ //jsx形式のファイル拡張子をjsxもしくはtsxに限定
'error',
{
extensions: ['.jsx', '.tsx'],
},
],
'react/react-in-jsx-scope': 'off', //import React from 'react'が無くてもエラーを無くす
'react/prop-types': 'off', //TypeScriptでチェックしているから不要。offにする
'no-void': [ //void演算子の許可
'error',
{
allowAsStatement: true,
},
],
},
settings: {
'import/resolver': { //importするファイルをjsだけではなく、tsを含むファイルを許可する
node: {
paths: ['src'],
extensions: ['.js', '.jsx', '.ts', '.tsx'],
},
},
},
/*-- ↑追加ここまで --*/
};
コメントがある部分が.eslintrc.jsのデフォルトの指定に追加したものです。簡単に追加したものを説明します。
extends
拡張する機能を追加しています。
plugin:react/recommendedの情報はairbnbの中に含まれているので消しています。TypeScriptで使う型情報が入ったプラグインを読み込み、最後にprettierを読み込んでいます。ESLintの情報に沿ってフォーマットさせるのでprettierは最後に指定するようにしましょう。
extends: [
//'plugin:react/recommended', airbnbにほとんど設定されているので削除
'airbnb',
'airbnb/hooks', //追加
'plugin:@typescript-eslint/recommended', //型を必要としないプラグインの推奨ルールをすべて有効
'plugin:@typescript-eslint/recommended-requiring-type-checking', //型を必要とするプラグインの推奨ルールをすべて有効
'prettier', //追加 ESLintの情報に沿ってフォーマット
],
Airbnbについては以下を参照してください。
parserOptions
tsconfigRootDirでtsconfig.jsonがある相対パスを指定して、projectでtsconfig.jsonを指定しています。
parserOptions: {
ecmaFeatures: {
jsx: true,
},
ecmaVersion: 12, //latestから12に変更
sourceType: 'module',
tsconfigRootDir: __dirname, //追加 tsconfig.jsonがある相対パスを指定
project: ['./tsconfig.json'], //追加 tsconfig.jsonを指定
},
plugins
使っていないimportを自動で削除するためにunused-importsを追加しています。
plugins: [
'react',
'@typescript-eslint',
'unused-imports' //追加 使っていないimportを自動で削除用
],
ignorePatterns
ESLintの対象外にするファイルやフォルダを指定できます。後ほど.eslintignoreという名前でファイルを作り、ESLint対象外にするフォルダなどまとめて指定しますが、ここでもbuildフォルダを除外指定しておきます。(.eslintignoreにbuildフォルダを指定してもコンパイルが遅くなるため)
ignorePatterns: ['build'], //追加 .eslintignoreに対象外にしているが無いとコンパイルに時間がかかる
rules
rulesの中ではデフォルトのルールを自分に合うルールにカスタマイズできます。また、読み込んだプラグインの設定を書くのもこのrulesの中です。
ESLintのrulseについては以下をどうぞ。
それぞれの設定を見ていきます。
no-use-before-defineは関数や変数が定義される前に使われているとエラーになるというもの。デフォルトでこれが効いているので、こちらをoffにしてTypeScript側のno-use-before-defineを使うようにします。
'no-use-before-define': 'off', //関数や変数が定義される前に使われているとエラーになるデフォルトの機能をoff
'@typescript-eslint/no-use-before-define': ['error'], //typescript側のno-use-before-defineを使うようにする
以下の設定ではnamed exportを使えるようにimport/prefer-default-exportをoffにしています。
'import/prefer-default-export': 'off', //named exportがエラーになるので使えるようにoff
以下は使っていないimportを自動で削除するための設定です。
'@typescript-eslint/no-unused-vars': 'off', //unused-importsを使うため削除
'unused-imports/no-unused-imports': 'error', //不要なimportの削除
'unused-imports/no-unused-vars': [ //unused-importsでno-unused-varsのルールを再定義
'warn',
{ vars: 'all', varsIgnorePattern: '^_', args: 'after-used', argsIgnorePattern: '^_' },
],
unused-importsの設定については公式を参考にしました。
以下はアロー関数以外を受け付けない設定です。
'react/function-component-definition': [//アロー関数以外受け付けない設定
2,
{
namedComponents: 'arrow-function',
unnamedComponents: 'arrow-function',
},
],
以下ではパラメーターのプロパティを変更することを許可しています。
'no-param-reassign': [2, { props: false }], //パラメーターのプロパティ変更を許可
以下はimportするときにjs、jsx、ts、tsxの拡張子を省略してもエラーにしない設定です。
'import/extensions': [
//importのときにファイルの拡張子を記述しなくてもエラーにしない
'error',
{
js: 'never',
jsx: 'never',
ts: 'never',
tsx: 'never',
},
],
以下はjsx記法を使うファイルの拡張子がjsxのほかに、tsxも許可する設定です。
'react/jsx-filename-extension': [ //jsx形式のファイル拡張子をjsxもしくはtsxに限定
'error',
{
extensions: ['.jsx', '.tsx'],
},
],
以下はReactを使うときにimport React from 'react'を書かなくてもエラーにならない指定です。
'react/react-in-jsx-scope': 'off', //import React from 'react'が無くてもエラーを無くす
以下はデフォルトの型チェック機能をoffにしています。TypeScript側で型のチェックを行うので必要ありません。
'react/prop-types': 'off', //TypeScriptでチェックしているから不要。offにする
以下はvoid演算子の許可をしています。この指定をしないとreportWebVitals.tsでエラーがでます。
'no-void': [
'error',
{
allowAsStatement: true, //void演算子の許可
},
],
以下はsrcフォルダ内でjs、jsx、ts、tsxの拡張子がつくファイルのimportを許可しています。
settings: {
'import/resolver': {
//importするファイルをjsだけではなく、tsを含むファイルを許可する
node: {
paths: ['src'],
extensions: ['.js', '.jsx', '.ts', '.tsx'],
},
},
},
特定のフォルダ、ファイルにESLintを適用させない
ESLintを適用させたくないフォルダやファイルは.eslintignoreという名前のファイルを作成して、そこに指定します。
例えば以下。
これらのフォルダ、ファイルはESLintは必要ないので指定しておきましょう。
build/
public/
**/node_modules/
*.config.js
.*lintrc.js
/*.*
ESLintでフォーマットするコマンドを登録
package.jsonを開いて、scriptsにESLintでフォーマットするためのコマンドを登録しておきます。
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"lint": "eslint --ext 'src/**/*.{js,jsx,ts,tsx}'", //エラーチェック
"format": "eslint --cache --fix 'src/**/*.{js,jsx,ts,tsx}' && prettier --write 'src/**/*.{js,jsx,ts,tsx}'" //ESLintとPrettierによるフォーマット
},
以下のコマンドでsrcフォルダ内のjs,jsx,ts,tsxファイルをESLintでエラーチェックできます。
npm run lint
ESLintとPrettierでエラー修正する場合は以下。
npm run format
reportWebVitals.tsのエラー修正
これまでの設定ができるとcreat react appで作成されるreportWebVitals.tsにエラーが出ます。以下のようにvoidを加えることでエラーは修正できます。
import { ReportHandler } from 'web-vitals';
const reportWebVitals = (onPerfEntry?: ReportHandler) => {
if (onPerfEntry && onPerfEntry instanceof Function) {
void import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
getCLS(onPerfEntry);
getFID(onPerfEntry);
getFCP(onPerfEntry);
getLCP(onPerfEntry);
getTTFB(onPerfEntry);
});
}
};
export default reportWebVitals;
VSCode上でESLintとPrettierを連携させる
VSCodeでファイルを保存したタイミングでESLintとPreiiterによるエラーチェック、フォーマットを実行させるには、VSCodeの拡張機能をインストールして設定する必要があります。
VSCodeの拡張機能であるESLintとPrettierをインストール
以下のようにESLintとPrettierをインストールしたら有効化しましょう。
有効化できたら、VSCodeの設定ファイルに以下を追加します。
【 command + , 】で設定画面が開かれるので、以下の右上のアイコンをクリック。
アイコンをクリックして開かれたページ(settings.json)に以下を追加します。
{
"editor.defaultFormatter": "esbenp.prettier-vscode", //デフォルトのフォーマットはprettierを指定
"editor.formatOnSave": true, //保存したときにフォーマットする
"editor.codeActionsOnSave": { //ESLintに対応しているファイルはESLintでフォーマット
"source.fixAll.eslint": true
},
}
これでVSCode上でもESLintとPrettierがファイルを保存したタイミングで機能するようになります。
importのパスを省略したい場合は?
ディレクトリ構造が深くなるとimportで使うパスも長くなりがちです。
以下は極端な例です。
import { AddBlock } from '../../../components/blocks/AddBlock';
import { InputBlock } from '../../../components/blocks/InputBlock';
これを以下のように短くすることができます。
import { AddBlock } from '@/components/blocks/AddBlock';
import { InputBlock } from '@/components/blocks/InputBlock';
設定方法については以下の記事が参考になります。
おわりに
VSCodeでReactとTypeScript、ESLint、Prettier、Airbnbの環境構築について説明しました。creat-react-appを使えば何もしなくても ReactやTypeScriptの環境が整うわけではなく、いまのバージョンに合わせて設定していく必要があります。
またチームで作業する場合はESLintやPrettierの設定を合わせておきましょう。