1月6日、TwitchのエンジニアJosh Ribakoff氏が「How Twitch Tamed a Million Lines of TypeScript」と題したブログ記事を公開し、注目を集めている。この記事では、巨大なコードベースにおけるエンジニアリング基準の維持と、Lintルールの例外管理をスケーラブルに行う手法について詳しく紹介されている。

以下に、その内容を紹介する。
Twitchにおいて、筆者のチームの役割は、パフォーマンス制約、アーキテクチャパターン、TypeScriptの使用法、テスト、およびLintルールといったコアなエンジニアリング基準を定義し、維持することであった。これらは単なる好みの問題ではなく、300人の開発者が急速に変化する環境の中でコードをリリースし、100万行規模のモノリシックなコードベースをスケールさせるためのメカニズムであった。
現実的な課題
チームにはすでに、Lintルール、TypeScriptの型、テスト、およびCODEOWNERS(ファイルやディレクトリごとにコードの責任者を定義し、変更時に自動でレビューを依頼する仕組み)といった標準的なツールが導入されていた。しかし、規模が拡大するにつれ、以下のような理由から、意図せず「ルールに違反したコード」が放置されるケースが目立ち始めた。
- エディタの補完機能による
// eslint-disable(ルール適用除外)コメントの自動挿入 - 既存のルール適用除外設定を含んだコードのコピー&ペースト
- ルールの存在理由を再確認しないまま行われるリファクタリングによるコード移動
- 型定義の不備やコンパイルエラーを回避するための
any型や@ts-ignoreの一時的な追加
これは開発者が基準を無視しているのではなく、可視化されないまま「ルールの例外設定」が蓄積しやすい環境に問題があった。コアチームにとって、どの例外設定が検討された上でのトレードオフであり、どれが単なる放置された乖離なのかを判別する信頼できる手段が失われていたのである。
解決策:システムによる管理
筆者らは、開発を妨げず、かつ例外設定を可視化してレビュー可能にするため、ルールの違反内容をコード内の注釈(インラインコメント)ではなく、「追跡可能な独立したファイル」として管理するシステムを構築した。
このシステムは以下の4つのステップで構成される。
- 全無効化コメントの無視: すべての
eslint-disableコメントを無視するフラグを立ててESLintを実行する。これにより、現在コードベース内に存在するすべての潜在的な違反を強制的に抽出する。 - スナップショットの生成: 抽出されたESLintの違反結果(エラー一覧)を、リポジトリのルートにある「スナップショットファイル」に記録する。
- 行番号の除外: スナップショットから行番号を削除し、「ファイル名 + 違反しているルール名」のみを記録する。
- 所有権の設定: そのスナップショットファイルをCODEOWNERSの設定により、コアチームの管理下に置く。
この仕組みを導入することで、以下の4つのノウハウ(特性)が実現された。
- 違反とファイルの紐付け: 各エントリが「どのファイルのどのルールが適用外となっているか」を正確に記録する。
- 不要な差分の抑制: 行番号を除外しているため、コードの行数が前後する程度の変更ではスナップショットに差分は発生しない。
- レビューの強制: ファイル名の変更や移動、あるいは既存ファイル内での「新たなルール違反」が発生した場合、スナップショットファイルに差分が生じる。このファイルはコアチームが所有者(Owner)として設定されているため、プルリクエスト作成時に自動的にコアチームがレビュー担当者として割り当てられる仕組みだ。
- 対話の促進: ルールの例外設定がコード内に埋もれるのではなく、スナップショットの更新を通じた明示的な議論のきっかけとなる。
なぜこの手法が有効だったのか
この手法が極めて有効であった最大の理由は、「例外の可視化」と「開発速度の維持」を両立させた点にある。
従来のインラインコメントによる管理では、例外設定がコードの奥深くに埋もれてしまい、維持管理チームがその存在に気づくことが困難であった。標準が形骸化するのは、開発者がルールを軽視しているからではなく、例外が不可視になることでフィードバックの機会が失われるからだ。
本システムは、開発者のミスを厳格に指摘・ブロックすることを目的としていない。開発者は必要に応じて例外を出しながら迅速に作業を進めることができ、一方でコアチームはスナップショットの差分を通じて、組織全体の「設計上のプレッシャーポイント(無理が生じている箇所)」をリアルタイムに把握できる。これにより、理論ではなく実際の利用状況に基づいた基準の改善という、健全なフィードバックループが構築されたのである。
詳細はHow Twitch Tamed a Million Lines of TypeScriptを参照していただきたい。