TODOコメントをチケット管理するためのESLint Custom Rule

2023/12/10に公開

この記事は株式会社スリーシェイク3-shake Advent Calendar 2023 10日目の記事です。

概要

以下のようにTODOコメントをチケット管理するためのESLint Custom Ruleを作りました。
TODOコメントとセットでチケット起票することを促し、技術的負債を管理しやすくします。
🙆 GOODな例 (チケットが起票されていることが分かる 👍)

🙅 BADな例 (チケットが起票されておらず忘れ去られてしまうTODOコメント 😭)

リポジトリ / NPM パッケージ

背景

今年から今までのテックリードの役割に加えEMとしても活動することになり、自分でバリバリコードを書くだけではなくチームの生産性やコードの品質を向上させる仕組み作りが重要だと感じる機会が多くなりました。

そういった中でエンジニアがよくやるコード中のTODOコメントについて、コメントとして記載されたことが忘れ去られてしまい後々バグに発展してしまうケースに何度か遭遇しました。

😭 永遠に対応されないTODOコメント
// TODO: テストを追加
const sum = (numbers: number[]) =>  numbers.reduce((acc, cur) => acc + cur, 0)

解決策

TODOコメントを書くときは必ずチケットを起票するという運用ルールを設けることである程度TODOコメントを管理しやすくなるのではないかと考えました。

そしてTODOコメントと一緒にチケットURLを記載してもらうために、チケットURLの記載がないTODOコメントに警告等を出すESLint Custom Ruleが有効ではないかと考えました。

そこで実際にESLint Custom Ruleを実装しNPMに公開した上で自チームで利用しています。
(現在のところ、この仕組みは上手く機能しています)

利用方法

パッケージのインストール

# npm
npm i -D eslint-plugin-todo-comment

# yarn
yarn add -D eslint-plugin-todo-comment

ESLintの設定

{
  "plugins": [
    "todo-comment"
  ],
  "rules": {
    "todo-comment/ticket-url": "error"
  }
}

🙆 GOODな例: チケットが起票されており技術的負債を管理しやすい

// TODO: にテストを追加
// https://app.asana.com/ticketId/123456789 <-- 🎫 チケットが起票されている
const sum = (numbers: number[]) =>  numbers.reduce((acc, cur) => acc + cur, 0)

🙅 BADな例: チケットが起票されていないためLint時やCIでエラーとなる

// TODO: テストを追加
const sum = (numbers: number[]) =>  numbers.reduce((acc, cur) => acc + cur, 0)

運用

yarn lintでTODOコメントをチェックするようにした上で、GithubAction等のCI中でルール違反の場合にエラーを出すよう設定しておくと良いかと思います。

package.json
{
  "scripts": {
    "lint": "eslint src/**"
  }
}

Github Actionの設定

- name: lint package (Check Todo comment)
  run: yarn lint

苦労した点

ESLint Custom Ruleについて、コードの非コメント部分を扱う例は公式ドキュメントを含めて沢山あったのですがコメント部分を扱うための情報は少なかったため少し苦戦しました。

ルールの実装は、最終的に@typescript-eslint/utilsを利用して以下のように記述しました。

まずファイル中の全コメントを取得します。
https://github.com/ToyB0x/eslint-plugin-todo-comment/blob/b307aff310f7dc1d0bacfff18268c1109294da59/src/rules/ticket-url/ticket-url.ts#L10-L15

次にブロックコメントとラインコメントに分けて個別で対応しています。
(以下はブロックコメントの対応例)
https://github.com/ToyB0x/eslint-plugin-todo-comment/blob/b307aff310f7dc1d0bacfff18268c1109294da59/src/rules/ticket-url/lib/checkBlockComments.ts#L5-L23

テストケースについて

以下のように結構しっかり目にテストをつけています 🚀
https://github.com/ToyB0x/eslint-plugin-todo-comment/blob/main/test/rule.test.ts

Discussion