【Cursor活用】レガシーコードを3時間でクリーンに改善した実践テク

Cursor AIを使ったコードリファクタリングのイメージ

はじめに

3年前に書いた500行のレガシーコード。条件分岐が7段ネストし、変数名はtmp1data2の連続。正直、読むのも修正するのも億劫でした。「いつかリファクタリングしよう」と先延ばしにしていた結果、技術的負債が雪だるま式に増大。新機能追加のたびに、バグが連鎖的に発生する状況に陥っていました。

Cursor AIを使ってリファクタリングに挑戦したところ、3時間で可読性が劇的に向上し、テストカバレッジも70%から95%に改善しました。この記事では、実務で使った具体的なプロンプトとテクニックを解説します。

背景・課題:なぜレガシーコードは放置されるのか

エンジニアなら誰しも経験があるはず。「動いてるコードには触るな」という暗黙のルール。実際、私も以下のような理由でリファクタリングを先延ばしにしていました。

  • 時間がかかる:手作業でリファクタリングすると丸1日以上必要
  • リスクが高い:既存の動作を壊す可能性がある
  • 優先度が低い:新機能開発に比べて目に見える成果が少ない
  • テストが不十分:リファクタリング後の動作保証が難しい

結果として、コードベースはどんどん複雑化し、保守コストが増大する悪循環に陥っていました。特に困っていたのは、ネストが深すぎて処理の流れが追えないこと、そして変数名が意味不明で何をしているか理解できないことでした。

使用したツール・環境

今回のリファクタリングで使用したツールと環境は以下の通りです。

  • Cursor AI(v2.0以降):AIコーディングエディタ。VS Codeをフォークしており、既存の拡張機能がそのまま使える
  • Composer機能:複数ファイルを横断して一貫性のあるリファクタリングが可能
  • Long Context Chat:プロジェクト全体のコンテキストを理解しながらコード生成
  • 言語・フレームワーク:TypeScript、React(ただし、どの言語でも応用可能)

なぜCursorを選んだか?

  • GitHub CopilotやCodeiumと違い、プロジェクト全体を理解した上でリファクタリング提案をしてくれる
  • チャット機能でインタラクティブに調整できるため、段階的な改善がしやすい
  • 既存のVS Code環境をそのまま移行できるため、導入コストが低い

実際に使ったプロンプト

使用したプロンプト

以下のコードをリファクタリングしてください。

【現状の問題点】
- 条件分岐が7段ネストしており可読性が低い
- 変数名が tmp1, data2 など意味不明
- 関数が500行を超えており責務が曖昧
- エラーハンドリングが不十分

【リファクタリングの方針】
1. Early Return パターンで条件分岐を平坦化
2. 変数名を意味のある名前に変更(型推論を活用)
3. 機能ごとに関数を分割(1関数50行以内を目安)
4. エラーハンドリングを統一(try-catch で包む)
5. 既存のテストが通ることを保証

【追加要件】
- TypeScriptの型安全性を最大限活用
- コメントは最小限にし、コード自体で意図を表現
- リファクタリング前後で動作が完全一致することを保証

対象コード:
[ここにレガシーコードを貼り付け]

プロンプト設計のポイント

このプロンプトで工夫した点は以下の5つです。

1. 現状の問題点を具体的に列挙

「リファクタリングして」だけでは曖昧すぎます。何が問題なのかを明確に伝えることで、AIが適切な改善策を提案してくれます。

2. リファクタリングの方針を明示

Early Returnパターン、関数分割など、具体的な設計パターンを指定することで、一貫性のあるコードが生成されます。曖昧な指示だと、AIが独自の解釈で予期しないコードを生成することがあります。

3. 制約条件を明確にする

「既存のテストが通ること」「動作が完全一致すること」など、守るべき制約を明示することで、リスクの高い変更を防げます。これにより、リファクタリング後の検証作業が大幅に楽になります。

4. 数値基準を設定

「1関数50行以内」のように定量的な基準を示すと、適切な粒度で関数分割してくれます。曖昧な表現よりも、具体的な数値があると精度が上がります。

5. 言語固有の特性を活用

「TypeScriptの型安全性を活用」のように、使用言語の強みを明示することで、より最適化されたコードが生成されます。単なるリファクタリングではなく、言語の特性を活かした改善が可能になります。

実行結果・効果

Cursor AIを使ったリファクタリングの結果、以下の成果が得られました。

Before / After 比較

指標 Before After 改善率
コード行数 500行 320行(8関数に分割) -36%
最大ネスト深度 7段 2段 -71%
テストカバレッジ 70% 95% +36%
リファクタリング時間 (推定)8時間 3時間 -63%

想定外だった良い点

  • エッジケースの発見:AIがリファクタリング中に「この条件、本当に必要ですか?」と指摘してくれ、不要な条件分岐が3つ見つかった
  • 型安全性の向上any型を具体的な型に置き換えてくれたことで、実行前にバグを検出できるようになった
  • ドキュメント自動生成:関数分割後、各関数にJSDoc形式のコメントを自動生成してくれた

特に驚いたのは、Cursorが単なる表面的な整形ではなく、ロジックの本質を理解した上で改善提案をしてくれた点です。例えば、ネストした条件分岐を Early Return パターンで書き直すだけでなく、「この2つの条件は排他的なので統合できます」といった提案もありました。

応用パターン・カスタマイズ例

今回の手法は、リファクタリング以外にも応用できます。

1. レガシーコードのTypeScript化

以下のJavaScriptコードをTypeScriptに変換してください。
- 型推論を最大限活用
- interface/typeを適切に定義
- nullチェックをオプショナルチェーンに置き換え

2. パフォーマンス最適化

以下のコードのパフォーマンスを改善してください。
- 不要な再レンダリングを削減(React.memo、useMemo活用)
- ループ処理の最適化
- 非同期処理の並列化

3. テストコード生成

以下の関数に対して、包括的なユニットテストを作成してください。
- 正常系、異常系、境界値テストを含む
- テストフレームワーク:Jest
- カバレッジ95%以上を目標

プロンプトの「リファクタリングの方針」部分を変えるだけで、様々なコード改善タスクに対応できます。重要なのは、AIに何を期待するかを明確に伝えることです。

注意点・限界

Cursor AIは強力ですが、完璧ではありません。実際に使って感じた注意点を共有します。

1. 複雑なビジネスロジックの理解は限定的

ドメイン固有の複雑なロジック(例:金融計算、医療システムの業務ルール)は、AIが完全に理解できないことがあります。リファクタリング後、必ず人間が仕様を再確認する必要があります。

2. テストが不十分だとリスクが高い

既存のテストカバレッジが低い場合、リファクタリング後に動作が変わっていても気づけません。リファクタリング前に最低限のテストを書くことを強く推奨します。

3. 大規模なコードベースでは段階的に進める

500行を超えるコードを一度にリファクタリングすると、AIが迷走することがあります。100〜200行ずつ段階的に進める方が安全です。

4. レビューは必須

AIが生成したコードをそのまま本番環境に投入するのは危険です。必ずコードレビューとテストを実施し、意図しない変更がないか確認してください。

まとめ

  • Cursor AIでレガシーコードのリファクタリング時間が1/3に短縮(8時間→3時間)
  • プロンプトで「問題点」「方針」「制約」を明示することが精度向上の鍵
  • 単なる整形ではなく、ロジックの本質を理解した改善提案が得られる

まず試してみてほしいこと:手元のレガシーコードから100行程度の小さな関数を選び、上記のプロンプトテンプレートを使ってリファクタリングしてみてください。AIの提案を鵜呑みにせず、「なぜこの変更が必要か?」を考えながら進めることで、自分自身のリファクタリングスキルも向上します。

技術的負債の返済は、もう「重労働」ではありません。AIを味方につければ、クリーンなコードベースを維持しながら新機能開発に集中できます。