【入門・React・TypeScript・Enzyme】Create React AppからEnzyme導入まで

この記事は [2020 年の RevComm アドベントカレンダー 22日目](https://qiita.com/advent-calendar/2020/revcomm)の記事です。
21日目は @k_ishi さんの「ElasticsearchのSignigicant Terms AggregationのCustom Scoreによる特徴語抽出」でした。

こんにちは。株式会社RevCommで主にフロントエンド周りを担当しております、@mpayu2です。

こちらの記事では、Create React AppからEnzyme導入までの方法をまとめます。
それでは、よろしくお願いします。

## この記事で書くこと

- [Create React App](https://ja.reactjs.org/docs/create-a-new-react-app.html#create-react-app)でTypeScriptを使える環境を構築
- [ESLint](https://eslint.org/)を導入する
- [Jest](https://jestjs.io/ja/)と[Enzyme](https://enzymejs.github.io/enzyme/)でコンポーネントのテストを実行

## この記事で書かないこと

下記のような詳しい仕様についてはこの記事では記載しません。

- Reactの詳しい仕様
- ESLintの詳しい仕様
- Jestの詳しい仕様
- Enzymeの詳しい仕様

## 各種インストール

Create React Appをするために必要なコマンドをインストールします。

### Node.jsをインストールする

[Node.js](https://nodejs.org/en/)は、JavaScriptの実行環境作成に必要なため、インストールします。

インストール方法は下記の記事が参考になります。
[MacにNode.jsをインストール(Mac向け)](https://qiita.com/kyosuke5_20/items/c5f68fc9d89b84c0df09)
[Node.jsをインストールする(Windows向け)](https://qiita.com/sefoo0104/items/0653c935ea4a4db9dc2b)



Node.jsとは何かについて、下記の記事が参考になります。
[本当の初心者のためのNode.js超入門　~環境構築編~](https://qiita.com/qulylean/items/0ad521885a04a5ebd202)

## プロジェクトを作成する

### npx create-react-appコマンドでReactアプリのプロジェクトを作る

プロジェクトとは、これから作成するアプリの総称で、作成するアプリの一番上のフォルダにつける名前です。

ターミナルでアプリを作成したいフォルダまで移動し、下記のコマンドを実行します。
末尾に`--template typescript`と付けることで、typescriptを使用できるプロジェクトを作成できます。

```zsh
$ npx create-react-app {プロジェクト名} --template typescript
```

今回は、サンプルの名前として、`sample-app`というプロジェクト名にします。

[Create React App](https://ja.reactjs.org/docs/static-type-checking.html#using-typescript-with-create-react-app)

```zsh
$ npx create-react-app sample-app --template typescript
```

上記のコマンドを実行すると、ずらずらっと下記のような表記が出てきます。プロジェクトの作成完了です。

```zsh
（省略）
✨  Done in 9.29s.

Created git commit.

Success! Created sample-app at /Users/rc_dev/sample-app
Inside that directory, you can run several commands:

  yarn start
    Starts the development server.

  yarn build
    Bundles the app into static files for production.

  yarn test
    Starts the test runner.

  yarn eject
    Removes this tool and copies build dependencies, configuration files
    and scripts into the app directory. If you do this, you can’t go back!

We suggest that you begin by typing:

  cd sample-app
  yarn start

Happy hacking!
```

### アプリケーションを立ち上げる

作成したプロジェクトのフォルダへ移動します。

```zsh
$ cd sample-app
```

下記のコマンドを実行すると、アプリケーションが立ち上がります。

```zsh
$ yarn start
```

ターミナルに下記のような表示がされ、Chromeなどのブラウザから`http://localhost:3000`または、`On Your Networkに表示されているURL`（下記はXとなっていますが、実際は数値です）へアクセスすると、アプリケーションが動いている状態を確認できます。

```zsh
Compiled successfully!

You can now view sample-app in the browser.

  Local:            http://localhost:3000
  On Your Network:  http://XXX.XXX.XXX.XXX:3000

Note that the development build is not optimized.
To create a production build, use yarn build.
```

ちなみに、上記のアプリケーションの実行を止めたい場合は、上記の表示があるターミナルを開いた状態で、`Contrl + C`キーで止めることができます。
また起動する際は、`yarn start`をします。

<span id='browser'></span>
ブラウザで、下記のような画面が立ち上がりました。
![スクリーンショット 2020-12-09 23.19.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890762/36d70c42-d30e-6205-acfe-c789070e9b22.png)

## ESLintを入れる（ESLintが不要な場合は、この章を飛ばしてください）

もし、コードの文法チェックをしてくれるESLintをインストールしたい場合は、上記プロジェクトを作成したディレクトリで下記のコマンドを実行します。

ESLintのインストールについて、詳しくは[Getting Started with ESLint - ESLint公式ドキュメント](https://eslint.org/docs/user-guide/getting-started)に記載があります。

```zsh
$ yarn add eslint --dev
```

そして、ESLintの設定を下記のコマンドで行います。
下記のコマンドを実行すると、設定方法をどうするか質問を聞かれるため、適宜、自分が設定したい形で回答をして設定します。PCの矢印キーで選択肢を選び、Enterキーで決定して設定内容を指定できます。

```zsh
$ yarn run eslint --init
```
今回は、下記のような設定にしました。
![スクリーンショット 2020-12-13 21.49.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890762/560cb7ed-7a06-3b4e-632d-4e36bb711159.png)

ちなみに、上記でセットアップしたESLintは、`.eslintrc.json`ファイルにて設定を変更できます。
設定可能な項目については、[Configuring ESLint - ESLint公式ドキュメント](https://eslint.org/docs/user-guide/configuring)に記載があります。

## ReactのTypeScript向けの型定義ファイルをインストールする

Reactの@typesもインストールします。
`@types`をインストールすることで、Reactのモジュールに関するTypeScriptの型定義ファイルをインストールすることができます。

```zsh
$ yarn add @types/react @types/react-dom
```

## テスト用にプロジェクトを書き換える

まずは、`src/App.tsx`を開き、下記のように書き換えます。
下記の`Hoge`コンポーネントが、今回テストを追加する対象のコンポーネントです。

```typescript:src/App.tsx
import React from "react";
import "./App.css";
import Hoge from "./components/Hoge";

const App: React.FC = () => {
  return (
    <div className="App">
      <header className="App-header">
        <Hoge />
      </header>
    </div>
  );
};

export default App;
```

そして、`src`フォルダ配下に`components`フォルダを作成します。
その中に、下記のファイル`Hoge.tsx`を追加します。

```typescript:src/components/Hoge.tsx
import React from "react";

const Hoge: React.FC = () => {
  return <p className="hoge">Hoge</p>;
};

export default Hoge;
```

`Command + S`キーで書き換えたファイルを保存します。
その後、再度、ブラウザで立ち上げている画面を開きます。（「アプリケーションを立ち上げる」箇所を参照ください）

`Hoge`という文字が表示されるようになりました。

![スクリーンショット 2020-12-13 23.38.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890762/2026fc4f-3a64-36b6-3da6-8571223917c2.png)


## Enzymeを入れる
では、上記で作成したコンポーネントにテストコードを追加します。
Jestというテストを書くためのライブラリはCreate React Appをした際にすでに入っています。
こちらでは、コンポーネントのテストをしやすくするEnzymeをインストールします。

このあとご紹介するコマンドについても、上記で作成したプロジェクト配下のディレクトリで実行します。

[Enzyme](https://enzymejs.github.io/enzyme/)のサイトで、EnzymeをインストールしたいReactのプロジェクトのバージョンに合わせてインストールします。

プロジェクト直下の`package.json`でバージョンを確認します。
今回、私の環境では`"react": "^17.0.1",`となっています。

※2020年12月時点、Reactのバージョン17に関しては「[`enzyme-adapter-react-16`を使用するとEnzymeの`mount()`でエラーが出る](https://github.com/enzymejs/enzyme/issues/2429)」問題があります。
Reactのバージョン17のまま一時的に非公式の[enzyme-adapter-react-17](https://www.npmjs.com/package/@wojtekmaj/enzyme-adapter-react-17)を使用するか、Reactをバージョン16へダウングレードします。

今回は、Reactをバージョン16の中で一番最新の`１６.14.0`へダウングレードします。
Reactのバージョンは[React Versions - 公式ドキュメント](https://ja.reactjs.org/versions/)に記載があります。
![スクリーンショット 2020-12-14 22.52.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890762/6b47b9c4-33a4-fcc0-7895-b7b62338c4d5.png)


`１６.14.0`へダウングレードする場合は、下記のコマンドを実行します。
末尾の`16.14.0`をダウングレードしたいバージョンへ書き換えて実行します。

```zsh
$ yarn upgrade react@16.14.0
```

下記のようなメッセージが表示されて、ダウングレードが完了しました。
![スクリーンショット 2020-12-14 23.10.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890762/c023bd1e-3be9-5ba4-c52a-a527fe625dc1.png)

Reactをバージョン16へ変更したので、[Enzyme](https://enzymejs.github.io/enzyme/)のサイトで確認し、該当する`enzyme-adapter-react-16`をインストールします。

下記のコマンドの末尾の`enzyme-adapter-react-16`を必要なバージョンに合わせて変更し、実行します。

```zsh
$ yarn add -D enzyme enzyme-adapter-react-16
```

そして、TypeScriptの型定義ファイルを追加するために下記のコマンドも実行します。

```zsh
$ yarn add @types/enzyme @types/enzyme-adapter-react-16
```

Enzymeを読み込ませるために、`src/setupTests.ts`に下記のコードを追加します。

```typescript:src/setupTests.ts
import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';

Enzyme.configure({ adapter: new Adapter() });
```

## テストコードを追加する

まず、今回の説明上、不要となるファイル`src/App.test.tsx`を削除します。

そして、`src/components`フォルダの配下に`Hoge.test.tsx`というファイルを新しく作成し、下記のソースを貼り付けます。
テスト用のファイルには、`.test.tsx`を付けます。
Enzymeを使ってできることは[Enzyme API Reference](https://enzymejs.github.io/enzyme/docs/api/)に記載があります。

```typescript:src/components/Hoge.test.tsx
import React from "react";
import { shallow } from "enzyme";

import Hoge from "./Hoge";

describe("hoge", () => {
  it("className Hoge length", () => {
    expect(shallow(<Hoge />).find(".hoge").length).toBe(1);
  });
});
```

## テストを実行する

テストを追加したプロジェクトのディレクトリで、下記のコマンドを実行します。

```zsh
$ yarn test
```

すると、テストが実行されます。
`1 passed`と記載されているので、記載のテストが正常に通りました。
![スクリーンショット 2020-12-14 13.49.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890762/b59348e3-d22f-db0b-6da1-0787a1bfbe26.png)


>参照：
[enzyme-example-jest - Github](https://github.com/vjwilson/enzyme-example-jest)
[Enzyme API Reference](https://enzymejs.github.io/enzyme/docs/api/)

## まとめ

ReactのプロジェクトをCreate React Appを使って作成し、Enzymeを導入するところまでをまとめました。
最後までお付き合いただき、ありがとうございました🙇‍♀️
少しでもお役に立てたら嬉しいです。

それではみなさま、良いクリスマスを！[^1]

![christmas_inu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890762/5e41a3a1-6bfc-c2b0-7a3e-f6d9925387c2.png)


Revcommで一緒に働いてくれる方を絶賛募集しています。
募集中のポジションは、[株式会社RevComm 採用情報](https://hrmos.co/pages/revcomm/jobs) をご覧ください。

次回は@zoetaka38のさんの記事になります。

[^1]: 「[いらすとや](https://www.irasutoya.com/)」さんのイラストを使用させて頂いています。