كيفية دمج كود الواجهة الذي أنشأه Claude Code في المشروع الحالي بأمان
TuBrief 편집팀
2026년 9월 12일
0
Computing/Software원본 영상을 바탕으로 AI의 도움을 받아 작성했습니다. 원본 영상이 기준입니다.
커뮤니티의 다른 글
댓글 (0)
Log in to leave a comment
아직 작성된 글이 없습니다
원본 영상을 바탕으로 AI의 도움을 받아 작성했습니다. 원본 영상이 기준입니다.
Log in to leave a comment
아직 작성된 글이 없습니다
عند تشغيل Claude Code في الطرفية (Terminal) وكتابة /design، تظهر مسودة الواجهة في غضون ثوانٍ قليلة. بالنسبة للمطور المستقل، يُعد هذا مريحًا لتقليل الجهد اليدوي. تبدأ المشكلة بمجرد فتح هذا الكود ورؤيته.
فهو لا يعير أي اهتمام لمكونات shadcn/ui التي تم إعدادها مسبقًا في المشروع، بل يقوم بإنشاء وسوم <button> خام وجديدة. وبدلًا من الألوان الدلالية المسجلة في لوحة الألوان، يقوم بنثر أكواد سداسية عشوائية (Hex codes) مثل bg-[#1e293b] في كل ملف. وفي كل مرة يتم فيها إنشاء واجهة جديدة، يتم إهدار 40 دقيقة في إصلاح مسارات الاستيراد التالفة وإزالة الأنماط المضمنة (Inline styles).
هذا ليس مجرد شعور؛ فوفقًا لدراسة أجرتها GitClear في عام 2024 والتي حللت 211 مليون سطر من الالتزامات (Commits)، ارتفعت نسبة الكود الذي يتم التخلص منه تمامًا أو إعادة كتابته بالكامل في غضون أسبوعين بعد اعتماد أدوات الذكاء الاصطناعي من 3.1% إلى 5.7% (أي ما يقرب من الضعف). وفي المقابل، هوت نسبة إعادة الهيكلة من 25% إلى أقل من 10%. تتراكم الديون البرمجية بنفس سرعة زيادة الأوامر والأكواد. لذلك، يجب التخلي عن توقع أن يقوم النموذج بالحفاظ على نظام التصميم الحالي تلقائيًا، وتقييد حركته على مستوى النظام.
السبب وراء تجاهل Claude Code للكود الحالي بسيط للغاية؛ فهو يقوم بفحص الملفات ذات الصلة بضيق شديد لتوفير نافذة السياق (Context window). وإذا لم يتم توفير أي قيود، سيقوم النموذج بجمع أبسط وسوم HTML لرسم الواجهة.
يتم الحفاظ على ملفات التعداد في جذر الجلسة (Session root) بنسبة 10% تقريبًا من تكلفة الإدخال الأساسية بفضل التخزين المؤقت للموجه (Prompt caching). ولا تختفي هذه الملفات حتى لو تمت إعادة تعيين المحادثة أو ضغطها. ومن خلال تضمين قواعد إعادة استخدام المكونات هنا، يمكنك منع النموذج من إنشاء وسوم خام عشوائية من تلقاء نفسه.
قم بكتابة مسارات المكونات المشتركة وقواعد الأنماط في ملف CLAUDE.md الموجود في جذر المشروع.
`markdown
`
لا داعي لتمرير ملف CSS عام مكون من آلاف الأسطر بالكامل في كل موجه (Prompt). ما عليك سوى استخراج أسماء الرموز (Tokens) وحدها كملف JSON من إعدادات Tailwind.
`javascript
// scripts/extract-tokens.mjs
import fs from 'fs';
import resolveConfig from 'tailwindcss/resolveConfig.js';
import tailwindConfig from '../tailwind.config.js';
const fullConfig = resolveConfig(tailwindConfig);
const semanticTokens = {
colors: Object.keys(fullConfig.theme.colors || {}).filter(
(name) => !['inherit', 'current', 'transparent'].includes(name)
),
spacing: Object.keys(fullConfig.theme.spacing || {}),
borderRadius: Object.keys(fullConfig.theme.borderRadius || {}),
};
if (!fs.existsSync('.claude')) {
fs.mkdirSync('.claude');
}
fs.writeFileSync(
'.claude/design-tokens.json',
JSON.stringify(semanticTokens, null, 2)
);
`
قم بربط هذا السكريبت بـ postinstall و predev في ملف package.json.
`json
{
"scripts": {
"postinstall": "node scripts/extract-tokens.mjs",
"predev": "node scripts/extract-tokens.mjs"
}
}
`
يتم تحديث قائمة فئات الأنماط المتاحة مع كل عملية بناء (Build). وبهذا يختفي الوقت اليدوي المستغرق في إصلاح فئات الأنماط الخاطئة.
مهما كتبت من تنبيهات في الموجه (Prompt)، سيخرج النموذج ببعض القيم الغريبة أحيانًا. فعندما تعطيه لقطة شاشة وتطلب منه إنشاء واجهة، سيقوم بتضمين أعراض عرض ثابتة مثل w-[380px] لتناسب نسبة الصورة، وهي السبب الرئيسي وراء ظهور التمرير الأفقي على الشاشات المحمولة.
لتحقيق معايير WCAG 2.1 AA، يجب توضيح المعايير لكل دقة شاشة، والفحص الإلزامي باستخدام أداة التدقيق اللغوي (Linter) بمجرد إنتاج الملف.
| منطقة التحقق | المعيار المستهدف | فئات Tailwind الإلغائية (الأساسية) | شرط الحظر |
|---|---|---|---|
| الهاتف المحمول | 390px (base) | flex-col, w-full, grid-cols-1 |
التمرير الأفقي الناتج عن استخدام عرض ثابت w-[...px] |
| الجهاز اللوحي | 768px (md:) |
md:flex-row, md:grid-cols-2, md:p-6 |
الحفاظ على هيكل العمود الواحد للهاتف على الشاشات الواسعة |
| سطح المكتب | 1440px (xl:) |
xl:max-w-7xl, mx-auto, xl:grid-cols-4 |
تمدد حاوية التخطيط بلا حدود في الدقة العالية |
| الوضع الليلي | محدد .dark |
bg-background, text-foreground |
ترك الفئات الأساسية منفردة مثل bg-white, text-black |
| إمكانية الوصول | WCAG 2.1 AA | aria-label, <main>, focus-visible:ring-2 |
نقص النص البديل لقارئ الشاشة في أزرار الأيقونات |
عند التحكم بنموذج غير منضبط، فإن استخدام خطافات دورة الحياة (Lifecycle hooks) هو الخيار الأضمن. باستخدام خطاف PostToolUse في Claude Code، يتم تنفيذ السكريبت فور كتابة الملف على القرص.
قم بتسجيل أمر الخطاف في ملف .claude/settings.json.
`json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit|MultiEdit",
"hooks": [
{
"type": "command",
"command": "node .claude/hooks/ast-lint-guard.mjs",
"timeout": 30
}
]
}
]
}
}
`
الآن قم كتابة سكريبت التدقيق. استبدل الأكواد السداسية الشائعة برموز المشروع باستخدام تعبيرات منتظمة (Regex)، وافرض القواعد باستخدام إضافة ESLint لـ Tailwind.
`javascript
// .claude/hooks/ast-lint-guard.mjs
import fs from 'fs';
import readline from 'readline';
import { execSync } from 'child_process';
const rl = readline.createInterface({ input: process.stdin });
let inputBuffer = '';
rl.on('line', (line) => { inputBuffer += line; });
rl.on('close', () => {
try {
const payload = JSON.parse(inputBuffer);
const filePath = payload.tool_input?.file_path || payload.tool_input?.path;
if (!filePath || !/\.(tsx|jsx)$/.test(filePath) || !fs.existsSync(filePath)) {
process.exit(0);
}
let code = fs.readFileSync(filePath, 'utf-8');
let changed = false;
const replacementMap = {
'#ffffff': 'bg-background',
'#000000': 'text-foreground',
'#020817': 'bg-background',
'#0f172a': 'bg-card',
'#1e293b': 'bg-muted',
'#64748b': 'text-muted-foreground',
'#2563eb': 'bg-primary',
};
for (const [hex, token] of Object.entries(replacementMap)) {
const regex = new RegExp(`(bg|text|border)-\[${hex}\]`, 'gi');
if (regex.test(code)) {
code = code.replace(regex, token);
changed = true;
}
}
if (changed) {
fs.writeFileSync(filePath, code, 'utf-8');
}
execSync(`npx eslint "${filePath}" --rule "tailwindcss/no-arbitrary-value: error"`, {
stdio: 'pipe',
});
process.exit(0);
} catch (error) {
const failureLog = error.stdout?.toString() || error.stderr?.toString() || error.message;
console.error([Lint Pipeline Block] انتهاك قواعد التصميم:\n${failureLog});
process.exit(1);
}
});
`
قم بتثبيت إضافة التدقيق اللغوي في المشروع.
`bash
npm install -D eslint-plugin-tailwindcss
`
إذا أعاد السكريبت رمز الخروج 1، فسقراقي Claude Code سجل الأخطاء ويقوم بإصلاح الكود بفئات دلالية في الدور التالي. هذا يقلل من الوقت الضائع في معالجة الشاشات ذات التصميمات التالفة خلال مرحلة ضمان الجودة (QA).
عندما تطلب من Claude Code تصميم واجهة، غالبًا ما يقوم بخلط دالة fetch، كائنات بيانات تجريبية ضخمة، و JSX معًا في ملف واحد. لإرفاق واجهة برمجة تطبيقات (API) حقيقية لاحقًا، ستضطر إلى تفكيك كود العرض بالكامل.
كود الواجهة لا يحتاج إلى معرفة كيفية تغيير الحالة (State). من الأفضل تقسيم دليل الميزة (Feature directory) إلى 4 ملفات وتحديد مخطط البيانات (Data schema) أولاً.
ابدأ أولاً بتعريف معيار البيانات.
`typescript
// src/components/features/dashboard-card/schema.ts
import { z } from "zod";
export const MetricItemSchema = z.object({
id: z.string(),
label: z.string(),
value: z.string(),
changePercentage: z.number(),
trend: z.enum(["up", "down", "neutral"]),
});
export const DashboardCardSchema = z.object({
title: z.string().min(1),
metrics: z.array(MetricItemSchema),
});
export type DashboardCardData = z.infer;
export interface DashboardCardViewProps {
data: DashboardCardData;
isLoading?: boolean;
onActionClick?: (metricId: string) => void;
}
`
بعد ذلك، عند استدعاء Claude Code من الطرفية، تأكد من حظره تمامًا عن استخدام الحالة الداخلية.
`bash
claude "src/components/features/dashboard-card/schema.ts의 DashboardCardViewProps를 구현하는 순수 UI 컴포넌트 src/components/features/dashboard-card/dashboard-card-view.tsx를 만들어줘. 내부에서 useState, useEffect, fetch는 절대 쓰지 말고 오직 넘겨받은 Props와 @/components/ui 요소만 사용해서 반응형으로 짜줘."
`
عند إرفاق البيانات، قم بتغليفها باستخدام Hook. أنشئ بيانات وهمية (Mock data) ووظائف استدعاء API الحقيقية بنيكل الهيكل نفسه.
`typescript
// src/components/features/dashboard-card/use-dashboard-card.ts
import { useQuery } from "@tanstack/react-query";
import { DashboardCardData } from "./schema";
const MOCK_DATA: DashboardCardData = {
title: "월간 활성 지표",
metrics: [
{ id: "m-1", label: "신규 유입", value: "1,240명", changePercentage: 12.5, trend: "up" },
{ id: "m-2", label: "이탈률", value: "2.1%", changePercentage: -0.4, trend: "down" },
],
};
export const useDashboardCard = (cardId: string, useMock = false) => {
return useQuery({
queryKey: ["dashboard-card", cardId],
queryFn: async () => {
if (useMock) {
return MOCK_DATA;
}
const res = await fetch(/api/dashboard/${cardId});
if (!res.ok) throw new Error("데이터 조회 실패");
return res.json();
},
});
};
`
قم بتجميع الاثنين في مكون الحاوية (Container component).
`typescript
// src/components/features/dashboard-card/index.tsx
"use client";
import React from "react";
import { DashboardCardView } from "./dashboard-card-view";
import { useDashboardCard } from "./use-dashboard-card";
export function DashboardCardContainer({ cardId, useMock = false }: { cardId: string; useMock?: boolean }) {
const { data, isLoading } = useDashboardCard(cardId, useMock);
if (!data) return null;
return (
<DashboardCardView
data={data}
isLoading={isLoading}
onActionClick={(id) => console.log(id)}
/>
);
}
`
قبل ظهور الواجهة الخلفية (Backend)، قم بضبط الواجهة باستخدام useMock={true}. وعند اكتمال API، قم بحذف هذا العلم فقط. لن تحتاج إلى لمس سطر واحد من كود العرض.
عند إجراء محادثات طويلة مع النموذج في الطرفية والعبث بواجهة المستخدم، غالبًا ما يتم تعديل ملف الإعدادات العامة السليم أو تظهر ملفات مؤقتة غير مستخدمة في أرجاء الدليل. من الأفضل ترك مساحة العمل الخاصة بك كما هي وإنشاء دليل مخصص للتجارب للعمل فيه.
باستخدام Git worktree، يمكنك تشغيل Claude Code في مجلد معزول تمامًا.
`bash
git worktree add ../saas-ui-sandbox -b experiment/ai-dashboard-ui
cd ../saas-ui-sandbox
claude
`
إذا فشلت التجربة، يمكنك التخلص من المجلد بالكامل دون تردد.
`bash
cd ../saas-platform
git worktree remove ../saas-ui-sandbox --force
git branch -D experiment/ai-dashboard-ui
`
إذا ظهرت النتيجة بالشكل المطلوب، فلا تقم بدمج الفرع بالكامل، بل استخدم الوضع التفاعلي (Interactive mode) لاختيار واستيراد قطع الكود الخاصة بملف العرض فقط.
`bash
git checkout main
git checkout -p experiment/ai-dashboard-ui -- src/components/features/dashboard-card/dashboard-card-view.tsx
`
أثناء رؤية قطع الكود الظاهرة في الطرفية، اضغط على y للأجزاء التي تعجبك، و n لتجاهل التعديلات الغريبة.
إذا تجاوزت الجلسة 5 دورات (Turns)، سيبدأ السياق في التشوش ويبدأ النموذج في الهلوسة. لذلك يجب تنظيف الجلسة في كل مرة يحدث فيها ذلك:
npx tsc --noEmit فورًا. انتقل إلى الموجه التالي فقط عندما تكون أخطاء الأنواع 0./compact بلا تردد لتقليل إهدار الرموز (Tokens)./clear لتفريغ الذاكرة بالكامل. وفي حالة الارتباك، ارجع إلى نقطة التحقق السابقة باستخدام /rewind.قدرة النموذج على التوليد شيء، وما إذا كان هذا الكود قادرًا على الدخول إلى بيئة الإنتاج (Production) شيء آخر تمامًا. من خلال تضييق مسار الإدخال باستخدام CLAUDE.md، والتحقق من كود الإخراج بخطافات دورة الحياة، وفصل مساحة العمل باستخدام worktree، يمكنك تجنب قضاء الليل بأكمله في إصلاح الأكواد التي يخرجها الذكاء الاصطناعي.