Edited at

webpack + typescript + react + prettier + eslint + airbnb


TL;DR


  • webpack, typescript, react, prettier, eslint, airbnbを使ってreactの最新開発環境を構築する。


基本知識

下記のポストと文書を参考にしてこの記事を作成しました。


  1. https://ics.media/entry/16329/#webpack-ts-react

  2. https://www.typescriptlang.org/docs/handbook/react-&-webpack.html

  3. https://github.com/typescript-eslint/typescript-eslint#how-do-i-configure-my-project-to-use-typescript-eslint

  4. https://prettier.io/docs/en/integrating-with-linters.html#use-both

  5. https://medium.com/dubizzletechblog/setting-up-prettier-and-eslint-for-js-and-react-apps-bbc779d29062

  6. https://medium.com/@joshuacrass/javascript-linting-and-formatting-with-eslint-prettier-and-airbnb-30eb746db862

他のものはともかく1と2は目を通してください。

1と2のポストでは最小構成で説明しているので、自分なりに必要だと思った構成を3~6まで参考にして追加しました。

step by stepでコマンドを実行する形になっています。


プロジェクトの生成

Reactだけではないですが、プロジェクト単位でフォルダを作ってその中で必要なライブラリを設置し開発作業(コーディング)を行うのは基本です。

mkdir webpack-ts-react

cd webpack-ts-react
npm init -y
mkdir dist
mkdir src

srcはソースフォルダで、distはソースファイルをcompileしたファイルが保存されるフォルダになります。

dist以外にbuildやpublicなどの名前でフォルダを作る場合もあります。


webpackのインストール

webpackはデファクトスタンダードとして使われているモジュール(ライブラリ)バンドラーです。

npm i -D webpack webpack-cli webpack-dev-server


  • webpack


    • core library



  • webpack-cli


    • webpackのcommand line interface



  • webpack-dev-server


    • webpackのdevelopment server

    • ソースコードの変更事項をブラウザにすぐ反映してくれる。




typescriptのインストール

npm i -D typescript ts-loader


  • typescript


    • core library



  • ts-loader


    • webpackでtypescriptをcompileするために必要




reactのインストール

npm i -S react react-dom @types/react @types/react-dom

reactとreact-domでtypescriptの型定義1を使いたいので、@types/reactと@types/react-domも一緒にインストールします。


prettierのインストール

prettierはcode formatting(コード整形)を行ってくれるライブラリーです。

eslintも「eslint --fix」でcode formattingができますが、prettierの方がeslintより優れていて、eslintとprettierを併用して使うケースが多いです。

lintingはeslintを、code formattingはprettierを使うイメージです。

npm i -D prettier eslint-config-prettier eslint-plugin-prettier pretty-quick



  • prettier


    • core library




  • eslint-config-prettier


    • prettierと競合するeslintのルールを無視する。




  • eslint-plugin-prettier


    • eslintのルールでprettierを実行する。




  • pretty-quick


    • 変更されたファイルだけprettierを実行する。



.eslintrc.jsonに以下の内容を追記します。

eslintとprettierを一緒に使うための設定です。

{

"plugins": ["prettier"],
"extends": ["plugin:prettier/recommended"],
"rules": {
"prettier/prettier": "error"
}
}


eslint + airbnb

eslintのルールを拡張したairbnbのルール(コードコンベンション)を使います。

eslint-config-airbnbの最新バージョンの依存性パーケージを確認してください。

npm info "eslint-config-airbnb@latest" peerDependencies

{
eslint: '^4.19.1 || ^5.3.0',
'eslint-plugin-import': '^2.18.0',
'eslint-plugin-jsx-a11y': '^6.2.3',
'eslint-plugin-react': '^7.14.2'
}

eslint-config-airbnbとその依存性パーケージをインストールします。

npm i -D eslint-config-airbnb eslint@5.3.0 eslint-plugin-import eslint-plugin-jsx-a11y@6.2.3 eslint-plugin-react

npm 5+以上を使っている場合は下記のshortcutも使えます。

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

.eslintrc.jsonに以下の内容を追記します。

{

"extends": ["airbnb"]
}

reactを使わない場合は、airbnbの代わりにairbnb-baseを使います。


eslint + typescript

typescriptではlintingのためにtslintというものがあります。

eslintの方が幅広いルールを提供しているので、tslintではないeslintを使います。

typescriptとeslintを一緒に使うためには下記のパーケージをインストールする必要があります。

npm i -D @typescript-eslint/parser @typescript-eslint/eslint-plugin

.eslintrc.jsonに以下の内容を追記します。

eslintとtypescriptを一緒に使うための設定です。

{

"parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint"],
"extends": ["plugin:@typescript-eslint/recommended"]
}

typescriptを使わない場合は、parserとしてbabel-eslintを使います。


tsconfig.json

typescriptの設定ファイルです。

{

"compilerOptions": {
"outDir": "./dist/",
"sourceMap": true,
"target": "es5",
"module": "es2015",
"jsx": "react",
"moduleResolution": "node",
"lib": [
"es2019",
"dom"
]
},
"include": [
"src/**/*"
]
}

compileされたソースコードの出力場所はdistで、

sourceMapをtrueにしたので、complieされたソースコードは圧縮されずに保存されます。

targetをes5にしたので、es5でcomplieされます。

includeにはソースフォルダを指定します。これで自分が作成したソースコードも補完に利用されます。

excludeは設定しない場合、デフォルトでnode_modulesが設定されます。

tsconfig.jsonの詳細が知りたい場合は下記の文書を参照してください。

https://www.typescriptlang.org/docs/handbook/tsconfig-json.html


.eslintrc.json

ここまでして完成された.eslintrc.jsonのファイルです。

{

"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"project": "./tsconfig.json",
"useJSXTextNode": true
},
"plugins": ["@typescript-eslint", "prettier"],
"extends": [
"airbnb",
"plugin:@typescript-eslint/recommended",
"prettier/@typescript-eslint",
"plugin:prettier/recommended"
],
"env": {
"browser": true,
"node": true,
"es6": true
},
"rules": {
"prettier/prettier": "error",
"max-len": ["error", {"code": 100}],
"prefer-promise-reject-errors": ["off"],
"react/jsx-filename-extension": ["off"],
"react/prop-types": ["off"],
"no-return-assign": ["off"]
}
}

ルール(コードコンベンション)
ライブラリー

"airbnb"
eslint-config-airbnb, eslint, eslint-plugin-import, eslint-plugin-jsx-a11y, eslint-plugin-react

"plugin:@typescript-eslint/recommended"
@typescript-eslint/eslint-plugin

"prettier/@typescript-eslint"
eslint-config-prettier

"plugin:prettier/recommended"
eslint-plugin-prettier

rulesのところはご自分の設定に合わせてください。


.prettierrc

prettierの設定ファイルです。

option名を見れば大体わかると思うので、optionの説明は割愛します。

{

“printWidth”: 100,
“trailingComma”: “all”,
“tabWidth”: 2,
“semi”: true,
“singleQuote”: true
}


package.json

ここまでして完成されたpackage.jsonのファイルです。

{

"name": "webpack-ts-react",
"version": "1.0.0",
"description": "webpack + typescript + reactの最小構成",
"main": "index.js",
"scripts": {
"start": "webpack-dev-server",
"build": "webpack",
"watch": "webpack -w",
"lint": "eslint src -c .eslintrc.json --ext ts,tsx; exit 0",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^1.13.0",
"@typescript-eslint/parser": "^1.13.0",
"babel-eslint": "^10.0.2",
"eslint": "^5.3.0",
"eslint-config-airbnb": "^17.1.1",
"eslint-config-prettier": "^6.0.0",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-jsx-a11y": "^6.2.3",
"eslint-plugin-prettier": "^3.1.0",
"eslint-plugin-react": "^7.14.3",
"prettier": "^1.18.2",
"pretty-quick": "^1.11.1",
"ts-loader": "^6.0.4",
"typescript": "^3.5.3",
"webpack": "^4.38.0",
"webpack-cli": "^3.3.6",
"webpack-dev-server": "^3.7.2"
},
"dependencies": {
"@types/react": "^16.8.23",
"@types/react-dom": "^16.8.5",
"react": "^16.8.6",
"react-dom": "^16.8.6"
}
}


webpack.config.js

webpackの設定ファイルです。

module.exports = {

devtool: 'source-map',
// モード値をproductionに設定すると最適化される状態で、
// developmentに設定するとソースマップ有効でJSファイルが出力される。
mode: 'development',

// メインとなるjavascriptファイル(エントリーポイント)
entry: './src/main.tsx',
// ファイルの出力設定
output: {
// 出力ファイルのディレクトリ名
path: `${__dirname}/dist`,
// 出力ファイル名
filename: 'main.js'
},
module: {
rules: [
{
// 拡張子.tsもしくは.tsxの場合
test: /\.tsx?$/,
// TypeScriptをコンパイルする
use: 'ts-loader'
}
]
},
// import文で.tsや.tsxファイルを解決するため
resolve: {
extensions: ['.ts', '.tsx', '.js', '.json']
},
devServer: {
contentBase: './dist',
historyApiFallback: true,
inline: true,
hot: true,
port: 5000,
open: true
}
}


動作確認

サンプルコードはここを参照しました。

npm run lint

> webpack-ts-react@1.0.0 lint /Users/devtopia/apps/study/js/webpack-ts-react
> eslint src -c .eslintrc.json --ext ts,tsx; exit 0

/Users/devtopia/apps/study/js/webpack-ts-react/src/main.tsx
5:1 error Component should be written as a pure function react/prefer-stateless-function
6:3 error Missing accessibility modifier on method definition render @typescript-eslint/explicit-member-accessibility
6:9 warning Missing return type on function @typescript-eslint/explicit-function-return-type

/Users/devtopia/apps/study/js/webpack-ts-react/src/sub-component.tsx
12:29 warning Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
19:22 warning Missing return type on function @typescript-eslint/explicit-function-return-type
20:5 warning Unexpected console statement no-console
23:14 error Must use destructuring state assignment react/destructuring-assignment
23:14 error Use callback in setState when referencing the previous state react/no-access-state-in-setstate
27:3 error Missing accessibility modifier on method definition render @typescript-eslint/explicit-member-accessibility
27:9 warning Missing return type on function @typescript-eslint/explicit-function-return-type
30:14 error Must use destructuring props assignment react/destructuring-assignment
31:15 error Must use destructuring state assignment react/destructuring-assignment
32:9 error Missing an explicit type attribute for button react/button-has-type

✖ 13 problems (8 errors, 5 warnings)





  1. typescriptを使う場合もjavascriptのライブラリを使います。しかし、javascriptにはtypescriptのように型定義が存在しないので、そのままだとcompileできない場合があります。そこで、使うのが型定義ファイルです。