Hirooooo’s Labo

開発メモ、ガジェット、日記、趣味など、思った事を思ったまんま書くブログ

React × Redux 初心者入門(3日目:ESLintにAirbnbのJavaScriptスタイルガイドを導入する)

f:id:hirooooo-lab:20160713002241j:plain

今回も前回に引き続き開発環境のための設定説明です。  

ESLintを使用してJavascriptのコードスタイルガイドを導入している人は多いと思います。
その中でも、Airbnbのスタイルガイドが人気なので、できるだけ準拠するよう実装してみたいと思います。

eslint-config-airbnbのインストール

ESLint用のAirbnbの設定ファイルをインストールしたいと思います。
いつも通り以下のコマンドでインストールしてみます。

$ npm install --save-dev eslint-config-airbnb

すると、何やら怒られました。

$ npm install --save-dev eslint-config-airbnb
npm WARN eslint-config-airbnb@16.1.0 requires a peer of eslint-plugin-import@^2.7.0 but none is installed. You must install peer dependencies yourself.
npm WARN eslint-config-airbnb@16.1.0 requires a peer of eslint-plugin-jsx-a11y@^6.0.2 but none is installed. You must install peer dependencies yourself.
npm WARN eslint-config-airbnb-base@12.1.0 requires a peer of eslint-plugin-import@^2.7.0 but none is installed. You must install peer dependencies yourself.
npm WARN god@1.0.0 No description
npm WARN god@1.0.0 No repository field.

+ eslint-config-airbnb@16.1.0
added 3 packages in 4.337s

どうやらeslint-config-airbnbにはeslint-plugin-importeslint-plugin-jsx-a11yを必要とするようなので、追加でインストールします。

$ npm install --save-dev eslint-plugin-import eslint-plugin-jsx-a11y

これで必要なモジュールのインストールは完了です。

package.jsonはこんな感じになったと思います。

// package.json

{
  "name": "god",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "NODE_ENV=local webpack-dev-server --hot --inline --progress --colors",
    "build": "webpack --progress --colors"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "prop-types": "^15.6.0",
    "react": "^16.2.0",
    "react-dom": "^16.2.0",
    "react-redux": "^5.0.6",
    "react-hot-loader": "^4.0.0-beta.15",
    "redux": "^3.7.2"
  },
  "devDependencies": {
    "babel-cli": "^6.26.0",
    "babel-core": "^6.26.0",
    "babel-eslint": "^8.2.1",
    "babel-loader": "^7.1.2",
    "babel-preset-env": "^1.6.1",
    "babel-preset-react": "^6.24.1",
    "babel-preset-stage-0": "^6.24.1",
    "eslint": "^4.15.0",
    "eslint-config-airbnb": "^16.1.0",
    "eslint-loader": "^1.9.0",
    "eslint-plugin-import": "^2.8.0",
    "eslint-plugin-jsx-a11y": "^6.0.3",
    "eslint-plugin-react": "^7.5.1",
    "file-loader": "^1.1.6",
    "html-webpack-plugin": "^2.30.1",
    "webpack": "^3.10.0",
    "webpack-dev-server": "^2.11.0"
  }
}

続いてeslint-config-airbnbの読み込みをしていきます。

eslint-config-airbnbの反映

.eslintrcの修正

すでに前回の状態でもESLintの設定ファイルは作成済みですので、以下の1行を追加します。

  "extends": "airbnb",

全体ではこんな感じ

// .eslintrc

{
  "env": {
    "es6": true,
    "browser": true,
    "node": true
  },
  "rules": {},
  "parser": "babel-eslint",
  "plugins": [
    "react"
  ],
  "extends": "airbnb",
  "ecmaFeatures": {
    "arrowFunctions": true,
    "jsx": true
  }
}

反映するための設定は以上です。

エラーを修正する

設定を反映させると、いろいろな箇所でエラーが発生すると思います。
とりあえず、それらのエラーを推奨されているコードスタイルに修正していきます。

Component should be written as a pure function

react/prefer-stateless-function

github.com

state変更しないのなら、classじゃなくてfunctionで作りましょう。(だと思う...)

components/Header.jsxcontainers/App.jsxで発生したので直します。

components/Header.jsxの修正

次のように変更しました。
もうただのファンクションです。

// components/Header.jsx 
import React from 'react';

const Header = () => (
  <header className="header">
    <h1>ヘッダだZE</h1> {/* YOをZEに変更 */}
  </header>
);

export default Header;

containers/App.jsxの修正

こちらは、functionに変更するのではなく、PureComponentに書き換えて対応します。

import React, { Component } from 'react';
↓
import React, { PureComponent } from 'react';

class App extends Component {
↓
class App extends PureComponent {

PureComponentについてはこちらの記事が参考になりました。

jyane.jp

Block must not be padded by blank lines

padded-blocks

eslint.org

ようするに空行いれんじゃねぇ。ということ。(だと思う...)

containers/App.jsxで発生したので直します

containers/App.jsxの修正

class App extends PureComponent {

  static propTypes = {
    counter: PropTypes.object.isRequired,
    actions: PropTypes.object.isRequired,
  };
    .....
↓
class App extends PureComponent {
  static propTypes = {
    counter: PropTypes.object.isRequired,
    actions: PropTypes.object.isRequired,
  };
    .....

Prop type object is forbidden

react/forbid-prop-types

github.com

propTypesReact.PropTypes.arrayReact.PropTypes.objectとかを宣言したときに、中身の構成がわからないよ!(だと思う...)

正直これは参りました・・・。

直し方はPropTypes.shape()PropTypes.arrayOf()に書き換えて、ちゃんと内部の構造も定義してあげればいいんですけど、ちょっと今回は・・・・。

スルーさせてください

ちなみにちゃんと治す場合は以下のサイトが大変参考になりました。

engineering.wondershake.com

断念したので.eslintrcの修正

.eslintrcに以下を追記して、今回はreact/forbid-prop-typesを無視させていただきたいと思います。

  "rules": {
    "react/forbid-prop-types": 0
  },

全体はこんな感じ

// .eslintrc

{
  "env": {
    "es6": true,
    "browser": true,
    "node": true
  },
  "rules": {
    "react/forbid-prop-types": 0
  },
  "parser": "babel-eslint",
  "plugins": [
    "react"
  ],
  "extends": "airbnb",
  "ecmaFeatures": {
    "arrowFunctions": true,
    "jsx": true
  }
}

以上でとりあえずのエラーはなくなりました。

まとめ

まだソースが少ないので、ほとんどエラーにならずに済みましたが、こちらのAirbnbのルールについては、ver16.1.0のルールについてですので、今後ルールが変更になったりしたときはご了承ください。

個人的にはAirbnbのコードスタイルガイドってかなり厳しいと思うんですけど・・・・。みなさんどう感じているのでしょう?

まぁ、準拠するに越したことはないと思いますので、これからも出来る限り守っていきたいです。
(すでに1つ無視してしまっていますが・・。)

参考にさせていただいたサイト

次回予告

次回予告というか、あとやらなきゃいけないと思ってること

  • 開発環境の効率化をするためにHotReloadとソースマップを実装する → Done!
  • ESLintでAirbnbのスタイルガイドを実装する → Done!
  • MaterialデザインとCSSを実装する
  • ページルーティングを実装する
  • REST通信を実装する
  • ログイン制御のフローを実装する
  • デプロイ方法を検討、実装する

次回の記事

www.hirooooo-lab.com

今までの記事