React+ESLintの環境にFlowを導入するためのファーストステップ

# はじめに
Flowを導入することでReactでも型を利用できるようになります。今回はESLintで静的コードチェックを行なっているReactプロジェクトにFlowを導入する手順を説明します。
また、ReactにESLintが導入されている前提で話を進めますので、もし開発環境がない場合は[たった3コマンドを叩くだけ！Atomで始めるReact(JSX)を静的コード解析するESLint簡単導入手順
](https://qiita.com/nishina555/items/3bc981b5d1dca8b04f58)を参考にしてください。

# flow-typed をグローバルインストール
まずはflow-typedをグローバルインストールします。**flow-typedを利用することで外部ライブラリの型定義が利用できるようになります。**例えば、Reduxをフレームワークとして採用して開発を行う場合、Reduxで定義された型を利用するときなどにflow-typedが活用されます。
今回はFlowを導入するまでをゴールとするため、flow-typedの具体的な利用方法については今回は省略します。

```bash
$ yarn global add flow-typed
```


# Flowをプロジェクトにインストール

まずはプロジェクトにFlowをインストールします。

```bash
$ yarn add --dev flow-bin
```


# Flowの初期設定

Flowの初期設定を行います。初期設定は`flow init`で行います。

```bash
$ ./node_modules/.bin/flow init
```

Flowの設定は`.flowconfig`に記述していきます。Flowで無視したいファイルやライブラリのパスなどがある場合は`.flowconfig`に記載していきます。必要に応じて適宜追加していきます。

# Babelのプラグインをインストールする

Flowの型定義をトランスパイル時に取り除くためにBabelのプラグインをインストールします。

```bash
$ yarn add --dev babel-plugin-transform-flow-strip-types
```

webpackの設定を変更します。

```diff:webpack.config.js
const path = require('path');

module.exports = {
  entry: path.resolve(__dirname, 'src/index.jsx'), // トランスパイル対象
  output: {
    path: path.resolve(__dirname, 'dist'), // 出力先ディレクトリ
    filename: 'bundle.js', // 入力されたファイルをまとめて出力するときのファイル名
  },
  module: {
    rules: [
      {
        test: /\.js[x]?$/,
        exclude: /node_modules/,
        loader: 'babel-loader', // Babelをwebpackで利用できるようにする
        options: {
          presets: ['react', 'es2015'], // reactとes2015をトランスパイル対象とする
        },
      },
    ],
  },
   options: {
     'presets': ['es2015', 'react'],
+    'plugins': ['babel-plugin-transform-flow-strip-types'],
   },
  devServer: {
    contentBase: path.resolve(__dirname, 'dist'), // distディレクトリのファイルを確認する
    port: 3000, // 3000ポートを利用
  },
  resolve: {
    extensions: ['.js', '.jsx'], // jsファイル, jsxファイルを対象とする
  },
};
```

# ESLintにFlowを対応させる

型宣言されたReactでもESLintが使えるようにするeslint-plugin-flowtypeというプラグインをインストールします。インストールは[公式](https://github.com/gajus/eslint-plugin-flowtype)に書かれているインストール手順に従います。

```bash
$ yarn add --dev babel-eslint
$ yarn add --dev eslint-plugin-flowtype
```

次に`.eslintrc`を編集します。
補足ですが、settingsの部分についてonlyFilesWithFlowAnnotationをtrueにすることでFlowのアノテーションがついたファイル(ソースコードの1行目に「// @flow」と記載)だけがFlowのチェック対象になります。

```javascript:.eslintrc.js
{
  "extends": [
    "airbnb",
    "plugin:flowtype/recommended",
  ],
  "plugins": [
      "flowtype"
  ],
  "parser": "babel-eslint",
  "settings": {
    "flowtype": {
      "onlyFilesWithFlowAnnotation": true
    }
  }
}
```

# 動作検証
では実際にFlowが導入されているか確認していきます。[前回](https://qiita.com/nishina555/items/3bc981b5d1dca8b04f58)作ったHelloWorldのサンプルコードの1行目にアノテーションをつけます。

```diff:Hello.jsx
+ // @flow
  import React from 'react';

  const Hello = () => (
    <h1>Hello!</h1>
  );

  export default Hello;

```

Flowの型チェックをするには`yarn run flow`を実行します。今回はHelloWorldを表示するプログラムなので特にエラーはないです。以下のように表示されればOKです。

```bash
$ yarn run flow

yarn run v1.2.0
$ /Users/nishina/workspace/react-webpack-sample/node_modules/.bin/flow
No errors!
✨  Done in 0.44s.
```

実際にFlowによるエラーチェックと修正方法については[こちら](https://www.webprofessional.jp/writing-better-javascript-with-flow/)に色々とサンプルがあるのでプロジェクトに新規ファイルを作成して実際に確認してみてください。

# 参考
- [eslit-plugin-flowtype](https://www.npmjs.com/package/eslint-plugin-flowtype)
- [Flow導入時に最初にやることまとめ](https://qiita.com/zaki-yama/items/3567b316f0fb62986809)
- [Flowによる型チェックでJavaScriptのつまらないミスを防ぐ方法](https://www.webprofessional.jp/writing-better-javascript-with-flow/)