CircleCI 2.0 で ESLint を動かす config.yml の紹介（簡単な解説と実行例も）

自社ブログで書いた https://blog.tes.co.jp/entry/2018/08/16/090712 のクロス投稿になります。

## はじめに

[ESLint](https://eslint.org/) って便利ですよね。
Prettier と併用してエディタで動くようにすると JavaScript 開発が捗ります。

この ESLint を個人ではなくプロジェクト単位で強制化したい場合、その多くは CI で動かす方法が適しています。
CI を使うことで、個人のエディタの環境に依存することなく、ソースコードの品質を守ることができるからですね。

CI はいくつも種類がありますが、弊社でよく使うのは [CircleCI](https://circleci.com/) です。

今回の記事では、その CircleCI 2.0 で ESLint を動かすだけの config.yml を紹介します。

とにかく CircleCI 2.0 で ESLint を動かしたい時に適した内容を記載しておきますので、宜しければご活用ください。
簡単な解説と実行例も載せてます。

## .circleci/config.yml

早速、設定ファイルを公開します。

既に ESLint を使っているプロジェクトであれば、この設定ファイルで CircleCI を実行すれば大丈夫なはずです。

```yaml
version: 2
jobs:
  build:
    docker:
      - image: circleci/node:8.11.3
    steps:
      - restore_cache:
          keys:
            - source-v1-{{ .Branch }}-{{ .Revision }}
            - source-v1-{{ .Branch }}-
            - source-v1-
      - checkout
      - save_cache:
          key: source-v1-{{ .Branch }}-{{ .Revision }}
          paths:
            - .git
      - restore_cache:
          key: v1-npm-deps-{{ checksum "package.json" }}
      - run: npm install
      - save_cache:
          key: v1-npm-deps-{{ checksum "package.json" }}
          paths:
            - node_modules
      - run:
          name: lint
          command: |
            mkdir -p /tmp/test-reports/eslint
            node_modules/.bin/eslint . --format junit --output-file /tmp/test-reports/eslint/results.xml
      - store_test_results:
          path: /tmp/test-reports
```

## ちょっと解説

詳細は公式を見た方が確実ですが、私が理解した内容を書いておきますので、少しでも助けになれば幸いです。

### cache

```yaml
- restore_cache:
    keys:
      - source-v1-{{ .Branch }}-{{ .Revision }}
      - source-v1-{{ .Branch }}-
      - source-v1-
- checkout
- save_cache:
    key: source-v1-{{ .Branch }}-{{ .Revision }}
    paths:
      - .git
```

```yaml
- restore_cache:
    key: v1-npm-deps-{{ checksum "package.json" }}
- run: npm install
- save_cache:
    key: v1-npm-deps-{{ checksum "package.json" }}
    paths:
      - node_modules
```

ソースコードの checkout や npm install って遅いですよね。
CircleCI では cache を利用して高速化する方法が使えますので、上記はそのための設定です。

今回の肝ではありませんが、テストコード以外でスローテストに悩まされないためにも、実行速度は気にしておいた方が良いですね。

公式では、以下のページで解説されています。
https://circleci.com/docs/2.0/caching/

### run lint

```yaml
- run:
    name: lint
    command: |
      mkdir -p /tmp/test-reports/eslint
      node_modules/.bin/eslint . --format junit --output-file /tmp/test-reports/eslint/results.xml
- store_test_results:
    path: /tmp/test-reports
```

ここが本記事の肝です。

Circle CI はテストの実行結果を画面上に表示できます。

となれば、ESLint の静的解析結果で Failed になったものを表示したいですよね。
しかし、CircleCI で ESLint を実行しただけでは結果が認識されず、画面に表示できません。

なので、上記の設定を用いて「静的解析結果を JUnit のフォーマットでファイル出力」して、それを 「CircleCI に読み込ませる」必要があります。

#### 静的解析結果を JUnit のフォーマットでファイル出力

```yaml
node_modules/.bin/eslint . --format junit --output-file /tmp/test-reports/eslint/results.xml
```

`--format` で JUnit を指定して、`--output-file` でファイルの出力先を指定しています。

公式では、以下のページで解説されています。
https://eslint.org/docs/user-guide/command-line-interface#-f---format
https://eslint.org/docs/user-guide/command-line-interface#output

ファイルの出力先は任意に変更可能ですが、次の段落で解説する CircleCI に読み込ませるパスと合わせる必要があります。

#### CircleCI に読み込ませる

```yaml
- store_test_results:
    path: /tmp/test-reports
```

CircleCI に、テストの実行結果が格納されているパスを指定しています。

このディレクトリの配下に ESLint の静的解析結果のレポートを格納すると、CircleCI が JUnit を動かした時と同様に解析し、レポートを表示してくれるようになります。

公式では、以下のページで解説されています。
https://circleci.com/docs/2.0/configuration-reference/#store_test_results

## 実行例

### FAILED (Red)

```javascript
var hoge = null;
```

みたいな、とんでもないコードを置いて CircleCI を実行してみた結果が以下。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89904/c696c243-56d3-ecfb-e77f-07ec64dde6ac.png)

- `hoge` という変数が未使用であること
- `var` ではなく `let` か `const` を使うようにすること

という2つの指摘を見ることができます。

これは、この実行例で参照している `.eslintrc.json` に基づいた指摘です。
もちろん、プロジェクトごとの ESLint の設定ファイルに基づいて静的解析されます。

### FIXED (Green)

上記で追加したとんでもないコードを取り除くと、ちゃんと Green になります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89904/7e3addbc-794a-f747-29ee-f82f08778767.png)

Red → Green の流れを踏めると、それだけで気持ち良いですね。

## おわりに

CircleCI 2.0 で ESLint を動かすのにあたり、設定内容と解説、実行例を書いてみました。

健全なソースコードを担保し続けるためにも CI や Lint は重要だと思いますので、宜しければご活用ください。