reviewdog を使用して厳しい tsconfig や eslint rule を段階的に適用する方法の紹介
概要
プロジェクトが進行するにつれて失敗からの学びを得たり、フェーズの変化により強力な eslint の rule を追加したい場合があります。しかし、次に示す特性を持つ rule を途中から追加するのは、手動で変更するファイルが多すぎて困難になるケースがあります。
- 既存コードに対してのエラーの件数が100件を超えている
-
--fix
による自動修正が提供されていない
この記事では サービスを止めずにコードのクオリティを上げる TypeScript+Reactで安全に開発を続ける方法 - ログミーTech を参考に reviewdog を使用して、厳しい tsconfig や eslint rule を段階的に適用する方法を紹介します。
方法
以降は eslint rule について説明していきます。tsconfig やその他ツールについても同様に設定が可能です。
reviewdog は linter ツールの出力を GitHub Checks などを使ってレビューコメントとして投稿するツールです。reviewdog は、linter の出力をプルリクエストで追加/削除された行(もしくはファイル)だけに filter する機能を持っています。
今回はこの reviewdog の機能を使って、より厳しい eslint の出力結果をプルリクエストで追加/削除されたファイルだけに対して filter してもらうことで、徐々にプロジェクトの治安を改善していきます。
具体的には、通常の.eslintrc.js
に対してより厳しいルールを追加した .eslintrc.strict.js
を準備します。この .eslintrc.strict.js
を eslint
の config オプションに渡して、その出力を reviewdog で filter します。
詳しいやり方はサンプルリポジトリで説明します。
サンプルリポジトリ
コードの紹介
サンプルリポジトリです。
今回は .eslintrc.strict.js
に "no-return-await": "error"
を追加してみました。
module.exports = {
extends: "./.eslintrc.js",
rules: {
"no-return-await": "error"
}
}
reviewdog
の config ファイルの .reviewdog.yml
を用意します。
runner:
tsc:
cmd: yarn --silent test:build --project tsconfig.strict.json --noEmit
format: tsc
eslint:
cmd: yarn --silent test:lint --config ./.eslintrc.strict.js
format: eslint
yarn
を使用している場合、yarn が出力するテキストが邪魔になるので --selent
オプションを追加します。
あとは CI で reviewdog を実行します。
- name: run eslint strict
run: |
reviewdog -runners=eslint -diff="git diff master" -fail-on-error -reporter=github-pr-check -filter-mode=file
env:
REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-filter-mode=file
はプルリクで追加/削除されたファイルを filter するオプションです。
動作例
このプルリクは、strict な eslint では lint に失敗するファイルを編集したケースを想定しています。
以下の画像の通り、変更があった no-strict-file.ts
に対してより厳しい eslint が実行されてエラーが発生しています。
no-strict-file.ts
と同じ内容が書いている no-strict-file-no-update.ts
はより厳しい eslint には怒られていません。
終わりに
reviewdog のプルリクで変更があったファイルだけ eslint の結果を filter するという機能を使って、段階的に厳しい eslint を適用していくサンプルを紹介しました。
実用では、.eslintrc.strict.js
に error として追加した rule は .eslintrc.js
に waring として追加しておくと、コード編集時により厳しい rule に気付けるため良いかもしれません。
Discussion