خطوط أنابيب الإنشاء لعزل مهارات تصميم Claude الخارجية عن كود الإنتاج
TuBrief 편집팀
2026년 9월 11일
0
Computing/Software원본 영상을 바탕으로 AI의 도움을 받아 작성했습니다. 원본 영상이 기준입니다.
커뮤니티의 다른 글
댓글 (0)
Log in to leave a comment
아직 작성된 글이 없습니다
원본 영상을 바탕으로 AI의 도움을 받아 작성했습니다. 원본 영상이 기준입니다.
Log in to leave a comment
아직 작성된 글이 없습니다
يبدو مستند مهارات التصميم الخارجي جذابًا للمطور الذي يقوم بإنشاء خدمة متكاملة (Full-stack) بمفرده دون مصمم. قد يبدو أن نسخ مطالبة (Prompt) نظام تصميم بحجم 5,000 سطر تم العثور عليها على تويتر أو غيت هب وإدخالها في إرشادات نظام Claude سيجعل الواجهة تبدو أنيقة.
في الواقع، تكون النتيجة عكس ذلك تمامًا. فبمجرد إرسال الرسالة الأولى، يظهر تحذير بخصوص حد رموز المميزات (Tokens)، ويستمر وقت انتظار استجابة واجهة برمجة التطبيقات (API) في الزيادة دونين أمل. والكود الذي ينتجه النموذج إما أن يضع أنماطًا مضمنة (Inline styles) غير معروفة داخل المكونات، أو يستورد وحدة Framer Motion لم يتم تثبيتها في المشروع من قبل. وفي النهاية، بعد قضاء ساعات الفجر في إصلاح واجهة المستخدم المعطلة يدويًا، ستعود إلى قالب shadcn/ui الأساسي.
المشكلة ليست في الحس الجمالي للنموذج. بل إن الطريقة نفسها التي يتم بها إلقاء نصوص Markdown غير المنظمة مباشرة في مطالبة النظام هي السبب. يجب تحويل أوصاف الأنماط المكتوبة باللغة الطبيعية إلى مواصفات رموز يمكن للآلة قراءتها، وبناء خط أنابيب لاختبار وعزل الكود الذي يبيّنه النموذج قبل أن يلمس ملفات الإنتاج.
إن لصق نظام تصميم Markdown بالكامل في المطالبة يؤدي إلى إهدار خطير للرموز (Tokens). فالعبارات الجمالية مثل "لون كحلي عميق يوحي للستخدم بالثقة" لا فائدة لها على الإطلاق في إنشاء تخطيط الصفحة. تستهلك هذه الجمل موارد الحساب داخل نموذج اللغة على حساب واجهات TypeScript أو منطق التحقق الذي يجب مراعاته بالفعل.
قم بالتخلص من أوصاف اللغة الطبيعية وإعادة بناء مطالبة النظام باستخدام كائنات JSON المتوافقة مع معيار مجموعة مجتمع رموز التصميم W3C (DTCG). احتفظ فقط بالألوان، والمسافات، وانحناءات الحواف.
`json
{
"color": {
"background": {
"surface": { "type": "color" },
"canvas": { "type": "color" }
},
"action": {
"primary": { "type": "color" },
"primary-hover": { "type": "color" }
}
},
"spacing": {
"compact": { "type": "dimension" },
"comfortable": { "type": "dimension" }
},
"radius": {
"md": { "type": "dimension" }
}
}
`
قم بدمج مواصفات الرموز المنسقة مع ميزة التخزين المؤقت للمطالبات (Prompt Caching) من Anthropic. اجعل الرموز الأساسية ودور النظام كتلة ثابتة وقم بتطبيق cache_control: { type: "ephemeral" }.
`typescript
import Anthropic from "@anthropic-ai/sdk";
const anthropic = new Anthropic();
export async function requestComponentGeneration(componentBrief: string) {
return await anthropic.messages.create({
model: "claude-3-5-sonnet-20241022",
max_tokens: 4096,
system: [
{
type: "text",
text: Next.js 및 Tailwind CSS 컴포넌트 생성기. 반드시 아래 DTCG 토큰 명세에 정의된 클래스만 사용하고 인라인 스타일(style 속성)은 출력하지 마십시오. [DTCG_TOKENS_JSON_DATA],
cache_control: { type: "ephemeral" },
},
],
messages: [
{
role: "user",
content: componentBrief,
},
],
});
}
`
يؤدي التخلص من مستندات النصوص الحرة إلى تقليص حجم المطالبة من حوالي 10,000 رمز إلى مستوى 1,200 رمز. وبناءً على وثائق Anthropic، تتم محاسبة قراءة ذاكرة التخزين المؤقت للمطالبة بنسبة 10% فقط من سعر رمز الإدخال الأساسي، مما يقلل من تكلفة واجهة برمجة التطبيقات بنكثر من 70% عند الاستدعاء المتكرر.
عند حقن مهارات خارجية، غالبًا ما يقوم Claude بزرع قيم تعسفية سرًا مثل style={{ marginTop: '13px' }}. كما أنه ينتج فئات عشوائية بين قوسين مربعين (w-[342px]) بشكل عشوائي. يؤدي هذا النوع من الكود إلى تقويض نظام الأنماط العامة شيئًا فشيئًا.
قم بربط eslint-plugin-react و eslint-plugin-tailwindcss بـ Flat Config الخاص بـ eslint.config.mjs لتصفيتها في مرحلة الإنشاء.
`javascript
import reactPlugin from "eslint-plugin-react";
import tailwindPlugin from "eslint-plugin-tailwindcss";
export default [
{
files: ["**/.{ts,tsx}"],
plugins: {
react: reactPlugin,
tailwindcss: tailwindPlugin,
},
settings: {
tailwindcss: {
callees: ["cn", "cva"],
config: "./tailwind.config.ts",
},
},
rules: {
"react/forbid-dom-props": [
"error",
{
forbid: [
{
propName: "style",
message: "인라인 스타일은 허용되지 않습니다. 지정된 Tailwind 유틸리티를 사용하세요.",
},
],
},
],
"tailwindcss/no-arbitrary-value": "error",
"tailwindcss/no-custom-classname": [
"error",
{
whitelist: ["animate-."],
},
],
},
},
];
`
قم تعيين الرموز المستخرجة إلى theme.extend في tailwind.config.ts. ستؤدي الكتابة فوق لوحة الألوان الأساسية إلى إتلاف الألوان التي تشير إليها المكونات الداخلية لـ shadcn/ui.
`typescript
import type { Config } from "tailwindcss";
import themeTokens from "./build/tailwind/theme.json";
const config: Config = {
content: ["./src/**/*.{ts,tsx}"],
theme: {
extend: {
colors: {
surface: themeTokens.color.background.surface,
canvas: themeTokens.color.background.canvas,
action: {
primary: themeTokens.color.action.primary,
"primary-hover": themeTokens.color.action["primary-hover"],
},
},
borderRadius: {
token: themeTokens.radius.md,
},
},
},
plugins: [require("tailwindcss-animate")],
};
export default config;
`
يتم عزل التفاعلات باستخدام متغيرات Class Variance Authority (CVA). فالمساس المباشر بأساسيات Radix UI يؤدي إلى محو خصائص شجرة إمكانية الوصول (ARIA).
`typescript
import * as React from "react";
import { Slot } from "@radix-ui/react-slot";
import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/lib/utils";
const buttonVariants = cva(
"inline-flex items-center justify-center rounded-token text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-action-primary disabled:pointer-events-none disabled:opacity-50",
{
variants: {
variant: {
default: "bg-action-primary text-white hover:bg-action-hover active:scale-[0.98]",
secondary: "bg-surface text-foreground hover:bg-surface/80",
ghost: "hover:bg-surface text-foreground",
},
size: {
default: "h-10 px-4 py-2",
sm: "h-8 px-3 text-xs",
lg: "h-12 px-8 text-base",
},
motion: {
subtle: "transition-all duration-150 ease-out",
expressive: "transition-all duration-300 cubic-bezier(0.16, 1, 0.3, 1)",
},
},
defaultVariants: {
variant: "default",
size: "default",
motion: "subtle",
},
}
);
export interface ActionButtonProps
extends React.ButtonHTMLAttributes,
VariantProps {
asChild?: boolean;
}
export const ActionButton = React.forwardRef<HTMLButtonElement, ActionButtonProps>(
({ className, variant, size, motion, asChild = false, ...props }, ref) => {
const Comp = asChild ? Slot : "button";
return (
<Comp
className={cn(buttonVariants({ variant, size, motion, className }))}
ref={ref}
{...props}
/>
);
}
);
ActionButton.displayName = "ActionButton";
`
عندما يُطلب من Claude توفير حركات لافتة للنظر، فإنه يستدعي Framer Motion كعادة متأصلة. وفقًا لقياسات Bundlephobia، يستحوذ Framer Motion على حوالي 60 كيلوبايت حتى بعد ضغط Gzip. في اللحظة التي تضيف فيها 60 كيلوبايت فقط لتحريك زرين، يتأثر مؤشر التحميل الأولي LCP سلبًا.
قم بحظر استيراد مكتبات الطرف الثالث في مطالبة النظام وفرض استخدام الخصائص الخاصة بخيط مركب المتصفح (Compositor Thread) فقط.
`typescript
// Formato no recomendado que causa reflujo de diseño en el hilo principal
//
// Formato recomendado procesado en el hilo del sintetizador GPU
`
الخصائص الهندسية مثل top و left و width و height تعيد حساب شجرة التخطيط في كل إطار. في المقابل، فإن أداة transform-gpu و opacity تتم معالجتهما في طبقة GPU المستقلة دون المرور عبر الخيط الرئيسي، مما يحافظ على سلاسة 60 إطارًا في الثانية (FPS).
كما يتم إزالة تأثير ضبابية الخلفية (backdrop-filter: blur()) من مناطق التمرير أيضًا. ففي متصفحات الأجهزة المحمولة منخفضة المواصفات، يقوم مرشح الضبابية داخل إطار عرض التمرير بإعادة حساب القوام في كل إطار مما يتسبب في انخفاض معدل تحديث الشاشة إلى ما دون 20 إطارًا في الثانية. وبدلاً من الضبابية، يمكن استخدام قناة ألفا شبه الشفافة ذات اللون الواحد (bg-background/80 مع حدود بكسل واحد) لمنع مشكلة شغل ذاكرة الفيديو.
إذا قمت بوضع الكود الذي أنشأه Claude مباشرة في دليل app/ لـ Next.js، فستتكسر التخطيطات وتحدث أخطاء معالجة الترطيب (Hydration). قم بالرسم أولاً في بيئة Storybook المستقلة ودمج المكونات التي اجتازت الاختبارات فقط في الإنتاج.
قم بإرفاق axe-playwright بـ .storybook/test-runner.js للتحقق من إمكانية الوصول بناءً على معايير WCAG 2.1 AA.
`javascript
const { injectAxe, checkA11y } = require("axe-playwright");
module.exports = {
async preVisit(page) {
await injectAxe(page);
},
async postVisit(page) {
await page.waitForSelector("#storybook-root", { state: "attached" });
await checkA11y(page, "#storybook-root", {
detailedReport: true,
axeOptions: {
runOnly: {
type: "tag",
values: ["wcag2a", "wcag2aa"],
},
},
});
},
};
`
إذا فشل الاختبار، أرسل سجل الخطأ مباشرة إلى Claude مرة أخرى.
`text
[AI 피드백 루프: 컴포넌트 정밀 교정 프롬프트]
생성된 코드가 axe-core 접근성 테스트에 실패했습니다.
로그를 분석해 기존 구조를 유지한 채 결함만 수정한 코드를 출력하십시오.
[실패 상세]
위반 항목: color-contrast
실패 노드:
사유: 명도 대비가 2.8:1로 WCAG AA 기준인 4.5:1에 미달함.
해결 지침: 텍스트 유틸리티를 text-foreground 또는 text-action-primary-hover로 교체하십시오.
`
قم بإعداد برنامج شل نصي (Shell script) لالتقاط لقطات الانحدار البصري (Visual Regression) باستخدام Playwright، ولا يتم إنشاء الفرع إلا عند اجتياز كافة الفحوصات.
`typescript
import { test, expect } from "@playwright/test";
import storybookManifest from "../../storybook-static/index.json";
const stories = Object.values(storybookManifest.entries).filter(
(entry) => entry.type === "story"
);
for (const story of stories) {
test(스냅샷 검증: ${story.title} - ${story.name}, async ({ page }) => {
await page.goto(/iframe.html?id=${story.id}&viewMode=story);
await page.waitForSelector("#storybook-root");
await page.waitForLoadState("networkidle");
await expect(page).toHaveScreenshot(`${story.id}.png`, {
animations: "disabled",
maxDiffPixelRatio: 0.01,
threshold: 0.2,
});
});
}
`
`bash
#!/usr/bin/env bash
set -e
COMPONENT_NAME=$1
if [ -z "$COMPONENT_NAME" ]; then
echo "오류: 검증할 컴포넌트 이름을 입력하세요."
exit 1
fi
echo "1. 린트 가드레일 검사"
pnpm eslint "src/components/ui/${COMPONENT_NAME}.tsx" --max-warnings=0
echo "2. Storybook 정적 빌드"
pnpm build-storybook --quiet
echo "3. Storybook 접근성 CLI 테스트"
pnpm test-storybook
echo "4. Playwright 시각 회귀 스냅샷 비교"
pnpm playwright test tests/visual/component-regression.spec.ts
echo "5. 통과: 브랜치 생성 및 PR 발송"
git checkout -b "feature/ui-{COMPONENT_NAME}.tsx"
git commit -m "feat(ui): {COMPONENT_NAME}"
gh pr create --title "feat(ui): ${COMPONENT_NAME} 추가" --body "Storybook A11y 및 Playwright 회귀 검사를 통과한 컴포넌트입니다."
`
لا داعي لفتح أدوات مطوري المتصفح والعبث بالهوامش ببضع بكسرات في كل مرة تتشوه فيها الشاشة. من خلال تمرير قواعد التحقق إلى برنامج نصي للطرفية (Terminal)، يمكنك إنشاء واجهة مستخدم بأمان بمفردك.