coding-standards について
coding-standardsは、コードの作成、レビュー、リファクタリングに使える汎用的なスキルです。可読性、型安全性、テスト、ファイル構成などを扱い、TypeScript/JavaScriptの指針も含みます。
主な機能
- 01明確な命名と一貫した書式を推奨
- 02シンプルな実装と重複回避を重視
- 03TypeScript/JavaScriptの規約を提示
- 04エラー処理と非同期処理を解説
- 05テスト、文書化、ファイル構成を案内
活用シーン
- 01新規プロジェクトやモジュールの規約策定
- 02コード品質と保守性のレビュー
- 03規約に沿ったコードのリファクタリング
- 04貢献者へのコーディング規約の共有
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ helloggx/ skill --skill coding-standardsインストール後、Claude Code で/coding-standardsを入力して読み込まれたか確認します。
詳細
コーディング規約とベストプラクティス
すべてのプロジェクトに適用できる、汎用的なコーディング規約です。
適用するタイミング
- 新しいプロジェクトやモジュールを開始するとき
- 品質と保守性を確保するためにコードをレビューするとき
- 既存のコードを規約に沿うようリファクタリングするとき
- 命名、フォーマット、構造の一貫性を徹底するとき
- リント、フォーマット、型チェックのルールを設定するとき
- 新しいコントリビューターにコーディング規約を案内するとき
コード品質の原則
1. 読みやすさを最優先する
- コードは書くよりも読まれる機会のほうが多いです
- 変数名や関数名は明確にします
- コメントより、コード自体が説明的であることを優先します
- フォーマットを統一します
2. KISS(シンプルにする)
- 動作する最もシンプルな解決策を選びます
- 過剰な設計を避けます
- 時期尚早な最適化は行いません
- 理解しやすさを、巧妙なコードより優先します
3. DRY(同じことを繰り返さない)
- 共通のロジックを関数に切り出します
- 再利用可能なコンポーネントを作成します
- モジュール間でユーティリティを共有します
- コピー&ペーストによる実装を避けます
4. YAGNI(必要になるまで作らない)
- 必要になる前に機能を作らないでください
- 憶測に基づく汎用化を避けます
- 必要な場合にのみ複雑さを加えます
- シンプルに始め、必要になったらリファクタリングします
TypeScript/JavaScript の規約
変数の命名
// ✅ GOOD: Descriptive names
const marketSearchQuery = 'election'
const isUserAuthenticated = true
const totalRevenue = 1000
// ❌ BAD: Unclear names
const q = 'election'
const flag = true
const x = 1000
関数の命名
// ✅ GOOD: Verb-noun pattern
async function fetchMarketData(marketId: string) { }
function calculateSimilarity(a: number[], b: number[]) { }
function isValidEmail(email: string): boolean { }
// ❌ BAD: Unclear or noun-only
async function market(id: string) { }
function similarity(a, b) { }
function email(e) { }
不変性のパターン(重要)
// ✅ ALWAYS use spread operator
const updatedUser = {
...user,
name: 'New Name'
}
const updatedArray = [...items, newItem]
// ❌ NEVER mutate directly
user.name = 'New Name' // BAD
items.push(newItem) // BAD
エラー処理
// ✅ GOOD: Comprehensive error handling
async function fetchData(url: string) {
try {
const response = await fetch(url)
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`)
}
return await response.json()
} catch (error) {
console.error('Fetch failed:', error)
throw new Error('Failed to fetch data')
}
}
// ❌ BAD: No error handling
async function fetchData(url) {
const response = await fetch(url)
return response.json()
}
Async/Await のベストプラクティス
// ✅ GOOD: Parallel execution when possible
const [users, markets, stats] = await Promise.all([
fetchUsers(),
fetchMarkets(),
fetchStats()
])
// ❌ BAD: Sequential when unnecessary
const users = await fetchUsers()
const markets = await fetchMarkets()
const stats = await fetchStats()
型安全性
// ✅ GOOD: Proper types
interface Market {
id: string
name: string
status: 'active' | 'resolved' | 'closed'
created_at: Date
}
function getMarket(id: string): Promise<Market> {
// Implementation
}
// ❌ BAD: Using 'any'
function getMarket(id: any): Promise<any> {
// Implementation
}
ファイル構成
ファイル名
components/Button.tsx # PascalCase for components
hooks/useAuth.ts # camelCase with 'use' prefix
lib/formatDate.ts # camelCase for utilities
types/market.types.ts # camelCase with .types suffix
コメントとドキュメント
コメントを記述するタイミング
// ✅ GOOD: Explain WHY, not WHAT
// Use exponential backoff to avoid overwhelming the API during outages
const delay = Math.min(1000 * Math.pow(2, retryCount), 30000)
// Deliberately using mutation here for performance with large arrays
items.push(newItem)
// ❌ BAD: Stating the obvious
// Increment counter by 1
count++
// Set name to user's name
name = user.name
公開 API の JSDoc
/**
* Searches markets using semantic similarity.
*
* @param query - Natural language search query
* @param limit - Maximum number of results (default: 10)
* @returns Array of markets sorted by similarity score
* @throws {Error} If OpenAI API fails or Redis unavailable
*
* @example
* ```typescript
* const results = await searchMarkets('election', 5)
* console.log(results[0].name) // "Trump vs Biden"
* ```
*/
export async function searchMarkets(
query: string,
limit: number = 10
): Promise<Market[]> {
// Implementation
}
テストの規約
テストの構成(AAA パターン)
test('calculates similarity correctly', () => {
// Arrange
const vector1 = [1, 0, 0]
const vector2 = [0, 1, 0]
// Act
const similarity = calculateCosineSimilarity(vector1, vector2)
// Assert
expect(similarity).toBe(0)
})
テストの命名
// ✅ GOOD: Descriptive test names
test('returns empty array when no markets match query', () => { })
test('throws error when OpenAI API key is missing', () => { })
test('falls back to substring search when Redis unavailable', () => { })
// ❌ BAD: Vague test names
test('works', () => { })
test('test search', () => { })
コードスメルの検出
次のアンチパターンに注意してください。
1. 長すぎる関数
// ❌ BAD: Function > 50 lines
function processMarketData() {
// 100 lines of code
}
// ✅ GOOD: Split into smaller functions
function processMarketData() {
const validated = validateData()
const transformed = transformData(validated)
return saveData(transformed)
}
2. 深すぎるネスト
// ❌ BAD: 5+ levels of nesting
if (user) {
if (user.isAdmin) {
if (market) {
if (market.isActive) {
if (hasPermission) {
// Do something
}
}
}
}
}
// ✅ GOOD: Early returns
if (!user) return
if (!user.isAdmin) return
if (!market) return
if (!market.isActive) return
if (!hasPermission) return
// Do something
3. マジックナンバー
// ❌ BAD: Unexplained numbers
if (retryCount > 3) { }
setTimeout(callback, 500)
// ✅ GOOD: Named constants
const MAX_RETRIES = 3
const DEBOUNCE_DELAY_MS = 500
if (retryCount > MAX_RETRIES) { }
setTimeout(callback, DEBOUNCE_DELAY_MS)
忘れないでください:コード品質に妥協はできません。明確で保守しやすいコードは、迅速な開発と安心して行えるリファクタリングを可能にします。
コメント
Markdown 対応