Claude Code द्वारा बनाए गए UI कोड को मौजूदा प्रोजेक्ट में सुरक्षित रूप से कैसे एकीकृत करें
TuBrief 편집팀
2026년 9월 12일
0
Computing/Software원본 영상을 바탕으로 AI의 도움을 받아 작성했습니다. 원본 영상이 기준입니다.
커뮤니티의 다른 글
댓글 (0)
Log in to leave a comment
아직 작성된 글이 없습니다
원본 영상을 바탕으로 AI의 도움을 받아 작성했습니다. 원본 영상이 기준입니다.
Log in to leave a comment
아직 작성된 글이 없습니다
टर्मिनल में Claude Code खोलकर /design टाइप करने पर कुछ ही सेकंड में एक UI ड्राफ्ट सामने आ जाता है। एक एकल डेवलपर (solopreneur) के लिए यह काम आसान बना देता है। समस्या तब शुरू होती है जब आप उस कोड को खोलकर देखते हैं।
प्रект में पहले से सेट किए गए shadcn/ui घटकों को पूरी तरह नजरअंदाज कर दिया जाता है और नए रॉ <button> टैग लिखे जाते हैं। पैलेट में रजिस्टर्ड सिमेंटिक रंगों के बजाय, हर फाइल में bg-[#1e293b] जैसे मनमाने हेक्स कोड भर दिए जाते हैं। हर बार एक नया UI स्क्रीन बनाने पर, अस्त-व्यस्त इम्पोर्ट पाथ को ठीक करने और इनलाइन स्टाइल हटाने में 40 मिनट बर्बाद हो जाते हैं।
यह सिर्फ आपका भ्रम नहीं है। 21.1 करोड़ (211 million) लाइनों के कमिट्स का विश्लेषण करने वाले GitClear के 2024 के अध्ययन से पता चलता है कि AI टूल अपनाने के दो सप्ताह के भीतर पूरी तरह से छोड़े गए या दोबारा लिखे गए कोड का अनुपात 3.1% से बढ़कर 5.7% यानी लगभग दोगुना हो गया है। रिफैक्टरिंग का अनुपात 25% से गिरकर 10% से भी कम हो गया है। कोड जितनी तेजी से बढ़ता है, तकनीकी कर्ज (technical debt) भी उतनी ही तेजी से जमा होता है। यह उम्मीद करना छोड़ दें कि मॉडल खुद-ब-खुद आपके मौजूदा डिज़ाइन सिस्टम का पालन करेगा; आपको सिस्टम लेवल पर उस पर लगाम लगानी होगी।
Claude Code द्वारा मौजूदा कोड को नजरअंदाज करने का कारण सीधा है। कॉन्टेक्स्ट विंडो को बचाने के लिए यह केवल आवश्यक फाइलों को ही संकीर्ण रूप से स्कैन करता है। यदि कोई प्रतिबंध न दिया जाए, तो मॉडल UI को रेंडर करने के लिए सबसे आदिम HTML टैग्स को मिला देता है।
प्रॉम्प्ट कैशिंग के कारण सेशन रूट की कॉन्फिगरेशन फाइल मूल इनपुट लागत के लगभग 10% पर बनी रहती है। चैट को रीसेट या कॉम्पैक्ट करने पर भी यह गायब नहीं होती है। यदि आप इसमें कंपोनेंट पुनर उपयोग (reuse) के नियमों को एम्बेड कर देते हैं, तो आप मॉडल को मनमाने ढंग से रॉ टैग बनाने से रोक सकते हैं।
प्रोजेक्ट रूट में CLAUDE.md फाइल में कॉमन कंपोनेंट पाथ और स्टाइल नियम लिखें।
`markdown
`
हर बार हजारों लाइनों की ग्लोबल CSS फाइल को प्रॉम्प्ट में पूरी तरह से पास करने की कोई आवश्यकता नहीं है। आप Tailwind कॉन्फिगरेशन से केवल टोकन के नामों को चुनकर JSON के रूप में निकाल (extract) सकते हैं।
`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)
);
`
इस स्क्रिप्ट को package.json के postinstall और predev में सेट कर दें।
`json
{
"scripts": {
"postinstall": "node scripts/extract-tokens.mjs",
"predev": "node scripts/extract-tokens.mjs"
}
}
`
बिल्ड करते समय हर बार उपलब्ध क्लास की सूची अपडेट हो जाती है। गलत स्टाइल क्लास को ठीक करने में लगने वाला मैनुअल समय बच जाता है।
प्रॉम्प्ट में कितनी भी सावधानियां क्यों न लिखी हों, मॉडल कभी-कभी गलत वैल्यू दे देता है। यदि आप एक स्क्रीनशॉट देकर UI बनाने के लिए कहते हैं, तो यह इमेज के अनुपात के आधार पर w-[380px] जैसी निश्चित चौड़ाई (fixed width) तय कर देता है। यही मोबाइल स्क्रीन में हॉरिजॉन्टल स्क्रॉल आने का मुख्य कारण है।
WCAG 2.1 AA मानकों को पूरा करने के लिए, आपको रिज़ॉल्यूशन-विशिष्ट मानदंडों को स्पष्ट रूप से बताना होगा और फाइल बनते ही लिंटर के माध्यम से उनकी जबरन जांच करनी होगी।
| सत्यापन क्षेत्र | लक्ष्य मानदंड | आवश्यक Tailwind क्लास | अवरोधन की स्थिति |
|---|---|---|---|
| मोबाइल | 390px (base) | flex-col, w-full, grid-cols-1 |
w-[...px] फिक्स चौड़ाई के कारण हॉरिजॉन्टल स्क्रॉल |
| टैबलेट | 768px (md:) |
md:flex-row, md:grid-cols-2, md:p-6 |
जब मोबाइल 1-कॉलम संरचना बड़ी स्क्रीन पर बनी रहे |
| डेस्कटॉप | 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 |
आइकन बटन पर स्क्रीन-रीडर का विकल्प गायब होना |
बात न मानने वाले मॉडल को नियंत्रित करने के लिए लाइफसाइक्ल हुक का उपयोग करना अधिक विश्वसनीय है। Claude Code के PostToolUse हुक का उपयोग करके, जैसे ही डिस्क पर कोई फाइल लिखी जाती है, स्क्रिप्ट तुरंत निष्पादित हो जाती है।
.claude/settings.json में हुक कमांड रजिस्टर करें।
`json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit|MultiEdit",
"hooks": [
{
"type": "command",
"command": "node .claude/hooks/ast-lint-guard.mjs",
"timeout": 30
}
]
}
]
}
}
`
अब जांच स्क्रिप्ट लिखें। नियमित अभिव्यक्तियों (regex) का उपयोग करके सामान्य हेक्स कोड को प्रोजेक्ट टोकन में बदलें, और Tailwind ESLint प्लगइन के साथ नियमों को लागू करें।
`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 चरण के दौरान टूटे हुए UI डिज़ाइन से जूझने का समय कम हो जाता है।
जब आप Claude Code को UI बनाने के लिए कहते हैं, तो यह अक्सर एक ही फाइल में fetch फ़ंक्शन, विशाल डमी डेटा ऑब्जेक्ट और JSX को एक साथ मिला देता है। बाद में वास्तविक API जोड़ने के लिए रेंडरिंग कोड को भी हटाना पड़ता है।
UI कोड को यह जानने की आवश्यकता नहीं है कि स्टेट को कैसे बदला जाए। एक फ़ीचर निर्देशिका (directory) को 4 फाइलों में विभाजित करना और डेटा स्कीमा को पहले से तय करना सुरक्षित है।
सबसे पहले, डेटा विनिर्देश (spec) को परिभाषित करें।
`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 को कॉल करते समय यह सख्त निर्देश दें कि आंतरिक स्थिति (internal state) का बिल्कुल भी उपयोग न किया जाए।
`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 तत्वों का उपयोग करके इसे रिस्पॉन्सिव बनाएं।"
`
डेटा जोड़ते समय, इसे हुक के साथ लपेटें। मॉक डेटा और वास्तविक 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();
},
});
};
`
कंटेनर कंपोनेंट में दोनों को एक साथ जोड़ें।
`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)}
/>
);
}
`
बैकएंड आने से पहले, useMock={true} के साथ UI को परिष्कृत करें। API पूरा होने पर केवल फ्लैग को हटा दें। व्यू कोड को एक लाइन भी छूने की कोई आवश्यकता नहीं है।
टर्मिनल में मॉडल के साथ लंबी बातचीत करते हुए UI के साथ काम करते समय, मूल ग्लोबल कॉन्फिगरेशन फाइलें संशोधित हो जाती हैं या निर्देशिका में अस्थायी फाइलें बन जाती हैं। अपने मुख्य कार्यक्षेत्र को वैसे ही छोड़कर केवल प्रयोग के लिए एक अलग निर्देशिका (directory) बनाना अधिक सुविधाजनक है।
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
`
यदि वांछিত परिणाम मिल जाता है, तो पूरे शाखा (branch) को एक साथ मर्ज न करें, बल्कि इंटरएक्टिव मोड का उपयोग करके केवल व्यू फाइल के कोड स्निपेट को लाएं।
`bash
git checkout main
git checkout -p experiment/ai-dashboard-ui -- src/components/features/dashboard-card/dashboard-card-view.tsx
`
टर्मिनल में दिखने वाले कोड चंक को देखकर, केवल पसंद के हिस्से के लिए y दबाएं और गलत संशोधनों को n से खारिज कर दें।
यदि सेशन 5 टर्न से अधिक हो जाता है, तो कॉन्टेक्स्ट धुंधला हो जाता है और मॉडल बकवास करने लगता है। आपको हर बार सेशन को साफ करना होगा।
npx tsc --noEmit चलाएं। टाइप त्रुटियों की संख्या 0 होने पर ही अगले प्रॉम्प्ट पर जाएं।/compact टाइप करें।/clear का उपयोग करें। गड़बड़ी होने पर /rewind के साथ पिछले चेकपॉइंट पर वापस जाएं।मॉडल की उत्पादन क्षमता (generation capability) बेहतरीन होने और उस कोड के प्रोडक्शन में जाने योग्य होने के बीच जमीन-आसमान का फर्क है। CLAUDE.md के साथ इनपुट चैनल को संकीर्ण करने, लाइफसाइक्ल हुक के साथ आउटपुट कोड को सत्यापित करने और worktree के साथ कार्यक्षेत्र को अलग करने से आप AI द्वारा उत्पन्न कोड को ठीक करने में अपनी रातें जागकर बिताने से बच सकते हैं।