Claude Code: คู่มือแนวปฏิบัติที่ดี

🇹🇭 Thai claude-codebest-practicesanalysisthai
📋 Table of Contents (9 sections)
  1. คู่มือแนวปฏิบัติที่ดี
  2. ภาพรวม
  3. แนวปฏิบัติที่ดีทางสถาปัตยกรรม
  4. แนวปฏิบัติที่ดีด้านคุณภาพโค้ด
  5. แนวปฏิบัติที่ดีด้านประสิทธิภาพ
  6. แนวปฏิบัติที่ดีด้านความปลอดภัย
  7. แนวปฏิบัติที่ดีด้านการพัฒนา
  8. จุดผิดพลาดที่พบบ่อยที่ควรหลีกเลี่ยง
  9. คำแนะนำสำหรับโค้ดเบสใหม่

คู่มือแนวปฏิบัติที่ดี

ภาพรวม

คู่มือนี้สรุปแนวปฏิบัติที่ดีหลักที่แสดงให้เห็นในโค้ดเบสของ claude-code-leaked

แนวปฏิบัติที่ดีทางสถาปัตยกรรม

1. การออกแบบ Tool แบบโมดูลาร์

แนวปฏิบัติ: ทุกความสามารถถูกเปิดเผยเป็น tool ที่แยกออกมาเป็นอิสระ

เหตุผล: ทำให้ระบบสามารถขยายได้ง่ายและดูแลรักษาง่าย

ตัวอย่าง:

// แต่ละ tool มีไดเรกทอรีของตัวเองพร้อมตรรกะ, UI, และ prompt
src/tools/BashTool/
├── BashTool.ts - การดำเนินการของ tool
├── UI.tsx - ส่วนประกอบ UI
├── prompt.ts - การมีส่วนร่วมใน system prompt

2. สถาปัตยกรรมที่ใช้ Feature Flags

แนวปฏิบัติ: ใช้ bun:bundle feature flags สำหรับการตัดโค้ดที่ตาย

เหตุผล: ลดการใช้หน่วยความจำและเพิ่มประสิทธิภาพ

ตัวอย่าง:

const module = feature('FLAG_NAME')
  ? require('./module.js')
  : null;

3. การเริ่มต้นระบบแบบขนาน

แนวปฏิบัติ: เริ่ม MDM, Keychain, และ API preconnect พร้อมกัน

เหตุผล: ลดเวลาเริ่มต้นระบบโดยการดำเนินการอิสระแบบขนาน

ตัวอย่าง:

await Promise.all([
  ensureMdmSettingsLoaded(),
  ensureKeychainPrefetchCompleted(),
  fetchBootstrapData()
]);

4. การแยกชั้นบริการ (Service Layer)

แนวปฏิบัติ: แยกการเชื่อมต่อภายนอกเป็นชั้นบริการที่ชัดเจน

เหตุผล: การแยกหน้าที่ที่ชัดเจน, การทดสอบและการดูแลรักษาง่ายขึ้น

ตัวอย่าง:

src/services/
├── api/ - SDK ของ Anthropic
├── mcp/ - ระบบ MCP
├── oauth/ - การยืนยันตัวตน
├── lsp/ - เซิร์ฟเวอร์ภาษา
├── analytics/ - Feature Flags

5. ระบบ Permission

แนวปฏิบัติ: ควบคุมการดำเนินการของ tool ตามโหมด permission ที่ปรับแต่งได้

เหตุผล: ให้การควบคุมละเอียดเกี่ยวกับการเข้าถึง tool

ตัวอย่าง:

async checkPermissions(input, context) {
  // ตรวจสอบข้อจำกัดของไดเรกทอรีการทำงาน
  // ตรวจสอบกฎเฉพาะ tool
  return { result: true };
}

แนวปฏิบัติที่ดีด้านคุณภาพโค้ด

1. TypeScript แบบ Strict

แนวปฏิบัติ: ใช้ Strict TypeScript ทั่วทั้งโค้ดเบส

เหตุผล: รับประกันความปลอดภัยของ type และลดข้อผิดพลาดขณะรัน

ตัวอย่าง:

interface ToolInputJSONSchema {
  [x: string]: unknown;
  type: 'object';
  properties?: { [x: string]: unknown };
}

2. Schemas ของ Zod

แนวปฏิบัติ: ใช้ Zod สำหรับการตรวจสอบ schema แบบ runtime

เหตุผล: ให้การตรวจสอบ input ที่ชัดเจนและข้อความข้อผิดพลาด

ตัวอย่าง:

inputSchema: z.object({
  command: z.string(),
  timeout: z.number().optional(),
  workdir: z.string().optional(),
})

3. Lazy Loading

แนวปฏิบัติ: โหลดโมดูลหนักเฉพาะเมื่อต้องการ

เหตุผล: ลดการใช้หน่วยความจำเริ่มต้นและเพิ่มเวลาเริ่มต้นระบบ

ตัวอย่าง:

const messageSelector = (): typeof import('src/components/MessageSelector.js') =>
  require('src/components/MessageSelector.js')

4. การจัดการข้อผิดพลาด

แนวปฏิบัติ: ดำเนินการการลดผลกระทบจากข้อผิดพลาดอย่างนุ่มนวล

เหตุผล: ป้องกันการหยุดทำงานและรักษาเสถียรภาพของระบบ

ตัวอย่าง:

try {
  await serviceOperation();
} catch (error) {
  if (isRetryableError(error)) {
    await retryOperation(error);
  }
  logEvent('service_error', { service: 'api', error: error.message });
}

5. กลยุทธ์ Caching

แนวปฏิบัติ: Cache การดำเนินการที่หนักเพื่อเพิ่มประสิทธิภาพ

เหตุผล: หลีกเลี่ยงการคำนวณและ I/O ซ้ำซ้อน

ตัวอย่าง:

export function clearPluginCache(reason: string): void {
  // ล้าง cache เมื่อการตั้งค่าหรือไฟล์เปลี่ยนแปลง
}

แนวปฏิบัติที่ดีด้านประสิทธิภาพ

1. การดำเนินการแบบขนาน

แนวปฏิบัติ: ดำเนินการอิสระพร้อมกัน

เหตุผล: เพิ่มการใช้งาน CPU และ I/O ให้สูงสุด

ตัวอย่าง:

void Promise.all([
  initUser(),
  getUserContext(),
  prefetchSystemContextIfSafe(),
  getRelevantTips(),
  prefetchOfficialMcpUrls()
]);

2. การตรวจสอบ Event Loop

แนวปฏิบัติ: ตรวจจับการหยุดชะงักของ event loop สำหรับปัญหาประสิทธิภาพ

เหตุผล: ระบุเมื่อ main thread ถูก block

ตัวอย่าง:

void import('./utils/eventLoopStallDetector.js')
  .then(m => m.startEventLoopStallDetector());

3. การตัดโค้ดที่ตาย

แนวปฏิบัติ: ใช้ feature flags เพื่อตัดโค้ดที่ไม่ได้ใช้จากการ build

เหตุผล: ลดขนาด binary และการใช้หน่วยความจำ

ตัวอย่าง:

const module = feature('FLAG') ? require('./module.js') : null;

4. กลยุทธ์การโหลดล่วงหน้า

แนวปฏิบัติ: โหลดข้อมูลล่วงหน้าก่อนที่จำเป็น

เหตุผล: ลดเวลาแฝงเมื่อข้อมูลถูกต้องการจริง

ตัวอย่าง:

void prefetchOfficialMcpUrls();
void prefetchAwsCredentialsAndBedRockInfoIfSafe();

แนวปฏิบัติที่ดีด้านความปลอดภัย

1. โหมด Permission

แนวปฏิบัติ: ดำเนินการโหมด permission ที่ปรับแต่งได้ (default, plan, auto, bypass)

เหตุผล: ให้การควบคุมละเอียดเกี่ยวกับการเข้าถึง tool

2. ข้อจำกัดของไดเรกทอรีการทำงาน

แนวปฏิบัติ: จำกัดการดำเนินการในไดเรกทอรีการทำงานที่ได้รับอนุญาต

เหตุผล: ป้องกันการเข้าถึงไฟล์ที่ไม่ได้รับอนุญาต

3. ความปลอดภัยที่ควบคุมด้วย Feature

แนวปฏิบัติ: ควบคุมฟีเจอร์ความปลอดภัยด้วย feature flags

เหตุผล: อนุญาตการเปิดใช้งานฟีเจอร์ความปลอดภัยแบบเลือกได้

4. ขอบเขตข้อผิดพลาด

แนวปฏิบัติ: แยกข้อผิดพลาดเพื่อป้องกันระบบล้มเหลวทั้งระบบ

เหตุผล: รักษาเสถียรภาพของระบบเมื่อเกิดข้อผิดพลาด

แนวปฏิบัติที่ดีด้านการพัฒนา

1. แนวปฏิบัติการตั้งชื่อที่สม่ำเสมอ

แนวปฏิบัติ: ใช้แพทเทิร์นการตั้งชื่อที่คาดเดาได้

เหตุผล: ทำให้โค้ดเบสง่ายต่อการค้นหา

ตัวอย่าง:

  • ไฟล์ Tool: <ToolName>Tool.ts
  • ไฟล์ UI: UI.tsx
  • ไฟล์ Prompt: prompt.ts

2. โครงสร้างไดเรกทอรีที่ชัดเจน

แนวปฏิบัติ: จัดระเบียบโค้ดตามฟังก์ชัน

เหตุผล: ทำให้หาง่ายสำหรับโค้ดที่เกี่ยวข้อง

ตัวอย่าง:

src/
├── tools/ - การดำเนินการของ tools ทั้งหมด
├── commands/ - คำสั่ง slash ทั้งหมด
├── services/ - การเชื่อมต่อภายนอก
├── components/ - ส่วนประกอบ UI
├── utils/ - ฟังก์ชันช่วย

3. เอกสารในตัว

แนวปฏิบัติ: เพิ่มคอมเมนต์ JSDoc สำหรับความชัดเจน

เหตุผล: ทำให้โค้ดอธิบายตัวเองได้

ตัวอย่าง:

/**
 * findGitRoot - ค้นหา root ของ repository Git
 * 
 * @param cwd - ไดเรกทอรีการทำงานปัจจุบัน
 * @returns เส้นทาง root ของ Git หรือ null ถ้าไม่พบ
 */
export function findGitRoot(cwd: string): string | null {
  // การดำเนินการ
}

4. ระบบ Migration

แนวปฏิบัติ: ดำเนินการ migrations ที่มีเวอร์ชันสำหรับการตั้งค่า

เหตุผล: รับประกันความเข้ากันได้หลังการเปลี่ยนแปลง

ตัวอย่าง:

const CURRENT_MIGRATION_VERSION = 11;

if (getGlobalConfig().migrationVersion !== CURRENT_MIGRATION_VERSION) {
  migrateSonnet1mToSonnet45();
  migrateLegacyOpusToCurrent();
  saveGlobalConfig(prev => ({
    ...prev,
    migrationVersion: CURRENT_MIGRATION_VERSION
  }));
}

จุดผิดพลาดที่พบบ่อยที่ควรหลีกเลี่ยง

  1. การขึ้นต่อกันแบบวงกลม: อาจทำให้เกิด import cycles และทำให้การเริ่มต้นระบบช้าลง
  2. การใช้ออกแบบ Feature Flags มากเกินไป: Flags ที่มากเกินไปอาจทำให้การตั้งค่า build ซับซ้อน
  3. ไฟล์โมโนลิธิกขนาดใหญ่: ไฟล์ที่มี 29K-46K บรรทัดอาจทำให้ยากต่อการเข้าใจ
  4. ความซับซ้อนของระบบ Permission: หลาย handlers อาจทำให้สับสนสำหรับผู้มาใหม่
  5. ภาระเอกสาร: ผู้มาใหม่ต้องเข้าใจเอกสารหลายไฟล์

คำแนะนำสำหรับโค้ดเบสใหม่

เมื่อสร้างโค้ดเบสใหม่แบบเดียวกัน ให้เน้นที่:

  1. ระบบ Tool: ดำเนินการรูปแบบโรงงานของ tool อย่างสม่ำเสมอ
  2. ชั้นบริการ: รักษาระบบการเชื่อมต่อภายนอกแยกจากตรรกะหลัก
  3. Feature Flags: ใช้สำหรับการตัดโค้ดที่ตาย
  4. การเริ่มต้นระบบแบบขนาน: เริ่มต้นระบบอิสระพร้อมกัน
  5. การควบคุมด้วย Permission: ดำเนินการโหมด permission ที่ปรับแต่งได้
  6. Lazy Loading: โหลดโมดูลหนักเมื่อต้องการ
  7. กลยุทธ์ Caching: Cache การดำเนินการที่หนัก
  8. การจัดการข้อผิดพลาด: ดำเนินการการลดผลกระทบจากข้อผิดพลาดอย่างนุ่มนวล
← Back to claudecodeanalysis