リファクタリング
社内で取り決めたリファクタリングのルールをシステムプロンプトに含めておくことで、ClaudeCodeは一貫したコードスタイルを生成できます。弊社では、ファイルを小さく保ちトークンを節約する実用的なルールや、可読性を向上させるルールを設定することで、効率的な開発環境の実現を図っています。
弊社の推奨ルール
- 1ファイル1責務の原則 - 1つのファイルに1つの関数またはクラスのみを定義する
- 命名規則の統一 - ファイル名は小文字ケバブケース、関数名はキャメルケース
- 型安全性の確保 - anyは許容するが、実行時エラーを引き起こす型アサーションは禁止
- 分割代入を避ける - propsや引数の出所を明確にするため
- 変数名は内容が分かる命名 - dataやresultなどの汎用的な名前を避ける
ClaudeCodeでの利用
「このファイルを1ファイル1関数に分割して。
各関数は適切なファイル名で別ファイルに切り出して」
「変数名をすべて内容が分かる名前に変更して。
配列は複数形、Boolean はis/hasプレフィックスを付けて」
「分割代入を使っている箇所をすべてpropsから直接参照する形に変更して」
「ファイル名をすべて小文字ケバブケースに変更して。
関数名はキャメルケース、Reactコンポーネントはパスカルケースに」
複数の機能ではなく1ファイル1責務を使う
ファイルの責務を明確にするため、1つのファイルに1つの機能のみを定義します。
// ❌ 避ける:複数の機能が混在
// utils.ts
export function uploadFile(file: File) { /* ... */ }
export function validateEmail(email: string) { /* ... */ }
export function formatDate(date: Date) { /* ... */ }
// ✅ 推奨:1ファイル1機能
// upload-file.ts
export async function uploadFile(file: File): Promise<string> {
const formData = new FormData()
formData.append('file', file)
const response = await fetch('/api/upload', {
method: 'POST',
body: formData
})
return response.json()
}
// validate-email.ts
export function validateEmail(email: string): boolean {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)
}
// format-date.ts
export function formatDate(date: Date): string {
return date.toLocaleDateString('ja-JP')
}
大文字ファイル名ではなく小文字ケバブケースを使う
Webフレームワークのルーティングとの整合性のため、すべて小文字で統一します。
// ❌ 避ける:大文字やキャメルケース
UserService.ts
xxxPayPay.ts
AdminPanel.tsx
// ✅ 推奨:小文字ケバブケース
user-service.ts
xxx-paypay.ts // PayPayも小文字
admin-panel.tsx
分割代入ではなく直接参照を使う
変数の出所を明確にし、リファクタリング時の問題を防ぎます。
// ❌ 避ける:分割代入
type Props = {
name: string
age: number
}
function MyComponent({ name, age }: Props) {
return <p>{name} ({age}歳)</p> // nameの出所が不明確
}
// ✅ 推奨:propsから直接参照
function MyComponent(props: Props) {
return <p>{props.name} ({props.age}歳)</p> // propsから来たことが明確
}
型アサーションではなくanyを使う
型が不明な場合は危険な型アサーションよりもanyを使用します。
// ❌ 避ける:危険な型アサーション
const user = data as User // dataがUserでない可能性
const name = user.name! // 実行時エラーのリスク
// ✅ 推奨:anyを使用
const data: any = await fetchUnknownAPI()
// TODO: APIの型定義が決まったら修正する
if (data && data.name) {
console.log(data.name) // 安全にアクセス
}
汎用的な名前ではなく内容が分かる名前を使う
変数の中身を名前から推測できるようにします。
// ❌ 避ける:汎用的で中身が不明
const data = await getPosts() // dataの中身は?
const result = await getUser(id) // resultの型は?
const items = users.filter(u => u.active) // 何のitems?
// ✅ 推奨:内容が明確
const posts = await getPosts() // 複数の投稿
const user = await getUser(id) // 1件のユーザー
const activeUsers = users.filter(u => u.active) // アクティブなユーザー
// Boolean変数はis/hasプレフィックス
const isLoading = false
const hasPermission = true
const canEdit = user.role === 'admin'
よくある問題
複数形が分からない単語がある
英語の複数形が不明または不自然な単語がある問題です。List、Items、Arrayなどの接尾辞を使用することで解決できます。
// ❌ 複数形が不明または不自然
const informations = [] // informationは不可算名詞
const newses = [] // newsは単複同形
const historys = [] // historyの複数形はhistories
// ✅ 代替案
const infoList = [] // Listを付ける
const newsItems = [] // Itemsを付ける
const historyEntries = [] // 具体的な名詞を使う
長い変数名になってしまう
変数名が長くなりすぎる問題です。コンテキストから明確な部分を省略することで解決できます。
// ❌ 冗長
class UserService {
private userServiceActiveUsersList: User[] = []
getUserServiceActiveUsersListCount() {
return this.userServiceActiveUsersList.length
}
}
// ✅ コンテキストから明確な部分を省略
class UserService {
private activeUsers: User[] = []
getActiveCount() {
const active = this.activeUsers.filter(u => !u.deletedAt)
return active.length
}
}
日本語の概念に対応する英単語が分からない
適切な英単語が見つからない問題です。一般的なWeb開発で使われる単語を調査して使用することで解決できます。
// ✅ 一般的な対応
const draft = {} // 下書き
const published = {} // 公開済み
const archived = {} // アーカイブ済み
const pending = {} // 保留中
const approved = {} // 承認済み