TuBrief
구독 채널
비디오
커뮤니티

Cara Aman Menggabungkan Kode Antarmuka Buatan Claude Code ke Proyek yang Sudah Ada

TuBrief 편집팀
2026년 9월 12일
0
Computing/Software

원본 영상을 바탕으로 AI의 도움을 받아 작성했습니다. 원본 영상이 기준입니다.

Bahasa Indonesia한국어EnglishEspañol中文हिन्दीDeutschFrançaisالعربيةPortuguêsРусский日本語

관련 영상

Claude Code Baru Saja Mendapat Pembaruan Desain Terbesarnya Tahun Ini (Dan Begini Cara Menguasainya)10:58

Claude Code Baru Saja Mendapat Pembaruan Desain Terbesarnya Tahun Ini (Dan Begini Cara Menguasainya)

Chase AI

커뮤니티의 다른 글

사내 시스템에 llm api 붙일 때 마주하는 현실적인 한계와 대응법

2026년 9월 13일

레거시 백엔드에 GPT-6 Astra 붙일 때 예산 승인과 보안 통과를 먼저 끝내는 법이 있습니다

2026년 9월 13일

에이전트끼리 대화하다 6천만 원 청구서가 나오는 이유

2026년 9월 13일

사내 RAG 벡터 검색에 Okta 권한 필터를 직접 거는 방법

2026년 9월 13일

브라우저 에이전트에게 내 구글 계정을 통째로 넘기면 안 되는 이유

2026년 9월 12일

Apple Won the AI Race

2026년 9월 12일

댓글 (0)

Log in to leave a comment

아직 작성된 글이 없습니다

© 2026 . All rights reserved.

TuBrief
구독 채널
비디오
커뮤니티
로그인

Cara Aman Menggabungkan Kode Antarmuka Buatan Claude Code ke Proyek yang Sudah Ada

Menyalakan Claude Code di terminal dan mengetik /design akan memunculkan draf antarmuka dalam hitungan detik. Bagi pengembang solo, ini sangat praktis karena menghemat tenaga. Masalahnya dimulai tepat saat Anda membuka kode tersebut.

Komponen shadcn/ui yang sudah disetel di dalam proyek sama sekali tidak dihiraukan, dan ia malah merancang tag <button> mentah yang baru. Alih-alih menggunakan warna semantik yang terdaftar di palet, ia menyebar kode heksadesimal acak seperti bg-[#1e293b] di setiap file. Setiap kali membuat satu halaman, Anda membuang waktu 40 menit hanya untuk memperbaiki jalur impor yang berantakan dan menghapus gaya inline.

Ini bukan sekadar perasaan Anda saja. Berdasarkan studi GitClear tahun 2024 yang menganalisis 211 juta baris commit, rasio kode yang sepenuhnya ditinggalkan atau ditulis ulang dalam waktu 2 minggu setelah adopsi alat AI melonjak hampir dua kali lipat dari 3.1% menjadi 5.7%. Rasio refaktorisasi merosot drastis dari 25% ke bawah 10%. Utang teknis menumpuk secepat pertumbuhan kodenya. Alih-alih berharap model akan menjaga sistem desain yang ada dengan sendirinya, Anda harus mengikat tangan dan kakinya di tingkat sistem.


Mengunci Jalur Komponen dengan File Aturan Proyek

Alasan Claude Code mengabaikan kode yang sudah ada sangatlah sederhana. Ia memindai file yang diperlukan secara sempit demi menghemat window konteks. Tanpa batasan apa pun, model akan menggambar antarmuka dengan mengombinasikan tag HTML paling primitif.

Berkat caching prompt, file konfigurasi di root sesi dipertahankan pada tingkat sekitar 10% dari biaya input dasar. Konfigurasi ini tidak hilang meskipun percakapan diinisialisasi ulang atau dikompresi. Menanamkan aturan penggunaan komponen di sini dapat mencegah model membuat tag mentah semaunya.

Tulis jalur komponen umum dan aturan gaya di file CLAUDE.md pada root proyek.

`markdown

Design System Guidelines

  1. Component Reuse (STRICT)
  • DO NOT use raw DOM tags (, , ).
  • MUST import from @/components/ui:
    • Button: import { Button } from "@/components/ui/button"
    • Input: import { Input } from "@/components/ui/input"
    • Card: import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card"
    • Dialog: import { Dialog, DialogContent, DialogTrigger } from "@/components/ui/dialog"
  • If a component does not exist in @/components/ui, ask to run: "npx shadcn@latest add ".
  1. Token Boundaries
  • NEVER use arbitrary hex codes or pixel widths: NO bg-[#...], NO w-[...px].
  • Use Semantic CSS variables:
    • Surfaces: bg-background, bg-card, bg-muted
    • Text: text-foreground, text-muted-foreground, text-primary
    • Borders: border-border, border-input

`

Anda tidak perlu terus menerus meneruskan file CSS global berukuran ribuan baris secara utuh ke dalam prompt. Cukup pilih nama token dari konfigurasi Tailwind dan ekstrak ke dalam JSON.

`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)
);

`

Pasang skrip ini pada postinstall dan predev di package.json.

`json
{
"scripts": {
"postinstall": "node scripts/extract-tokens.mjs",
"predev": "node scripts/extract-tokens.mjs"
}
}

`

Daftar kelas yang tersedia akan diperbarui setiap kali Anda melakukan build. Waktu manual yang dihabiskan untuk memperbaiki kelas gaya yang salah ketik akan hilang.


Mengganti Gaya Sembarang secara Otomatis dengan Hook Script

Sebanyak apa pun peringatan yang ditulis dalam prompt, model terkadang tetap memberikan nilai yang melenceng. Jika Anda memberikan satu tangkapan layar dan meminta pembuatan antarmuka, ia akan memasang lebar tetap seperti w-[380px] yang disesuaikan dengan rasio gambar. Inilah pelaku utama munculnya scroll horizontal pada layar seluler.

Untuk memenuhi standar WCAG 2.1 AA, Anda harus menentukan kriteria berdasarkan resolusi dan mewajibkan pemeriksaan linter segera setelah file dibuat.

Area Verifikasi Kriteria Target Kelas Tailwind Wajib Kondisi Pemblokiran
Seluler 390px (base) flex-col, w-full, grid-cols-1 Scroll horizontal karena penggunaan lebar tetap w-[...px]
Tablet 768px (md:) md:flex-row, md:grid-cols-2, md:p-6 Struktur 1 kolom seluler tetap dipertahankan pada layar lebar
Desktop 1440px (xl:) xl:max-w-7xl, mx-auto, xl:grid-cols-4 Wadah layout melebar tanpa batas pada resolusi tinggi
Mode Gelap Selektor .dark bg-background, text-foreground Kelas dasar seperti bg-white, text-black dibiarkan sendiri
Aksesibilitas WCAG 2.1 AA aria-label, <main>, focus-visible:ring-2 Tombol ikon kekurangan teks alternatif untuk screen reader

Saat mengendalikan model yang sulit diatur, menggunakan hook siklus hidup adalah cara yang paling pasti. Dengan memanfaatkan hook PostToolUse dari Claude Code, skrip akan langsung dieksekusi begitu file ditulis ke disk.

Daftarkan perintah hook di .claude/settings.json.

`json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit|MultiEdit",
"hooks": [
{
"type": "command",
"command": "node .claude/hooks/ast-lint-guard.mjs",
"timeout": 30
}
]
}
]
}
}

`

Sekarang buat skrip pemeriksa. Tangkap kode heksadesimal umum dengan regex lalu ubah menjadi token proyek, serta paksa aturan menggunakan plugin 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] Pelanggaran Aturan Gaya:\n${failureLog});
process.exit(1);
}
});

`

Instal plugin linter ke dalam proyek.

`bash
npm install -D eslint-plugin-tailwindcss

`

Jika skrip mengeluarkan kode keluar (exit code) 1, Claude Code akan membaca log error dan menulis ulang kode menggunakan kelas semantik pada giliran berikutnya. Hal ini mengurangi waktu bergelut dengan tampilan antarmuka yang rusak pada tahap QA.


Memisahkan Tampilan dan Logika Bisnis secara Fisik

Jika Anda menyuruh Claude Code merancang antarmuka, ia cenderung mencampur fungsi fetch, objek data palsu yang besar, dan JSX ke dalam satu file. Nantinya, jika Anda ingin menghubungkan API nyata, Anda harus membongkar seluruh kode perenderaannya.

Kode antarmuka tidak perlu tahu cara mengubah status. Lebih aman untuk memecah satu direktori fitur menjadi 4 file dan menetapkan skema data terlebih dahulu.

Definisikan spesifikasi data terlebih dahulu.

`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;
}

`

Selanjutnya, saat memanggil Claude Code di terminal, pastikan untuk menegaskan agar tidak menggunakan status internal sama sekali.

`bash
claude "Buatlah komponen UI murni src/components/features/dashboard-card/dashboard-card-view.tsx yang mengimplementasikan DashboardCardViewProps dari src/components/features/dashboard-card/schema.ts. Jangan pernah menggunakan useState, useEffect, atau fetch di dalam, dan buatlah secara responsif hanya menggunakan Props yang diteruskan serta elemen @/components/ui."

`

Saat menghubungkan data, bungkus dengan hook. Buat data mock dan fungsi panggilan API asli dengan struktur yang sama.

`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();
},
});
};

`

Gabungkan keduanya di komponen container.

`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)}
/>
);
}

`

Sebelum backend tersedia, sempurnakan tampilan dengan useMock={true}. Setelah API selesai, cukup hapus flag tersebut. Tidak ada alasan untuk menyentuh kode tampilan bahkan satu baris pun.


Isolasi Worktree dan Mengambil Perubahan secara Selektif

Saat mengobrol panjang dengan model di terminal dan mengutak-atik UI, file konfigurasi global yang tadinya normal sering kali ikut termodifikasi atau file-file sementara yang tidak terpakai bermunculan di berbagai sudut direktori. Lebih nyaman untuk membuat direktori khusus eksperimen tanpa mengganggu ruang kerja utama.

Dengan menggunakan Git worktree, Anda dapat menjalankan Claude Code di folder yang sepenuhnya terisolasi.

`bash
git worktree add ../saas-ui-sandbox -b experiment/ai-dashboard-ui
cd ../saas-ui-sandbox
claude

`

Jika eksperimen rusak, Anda bisa langsung menghapus foldernya tanpa perlu pusing.

`bash
cd ../saas-platform
git worktree remove ../saas-ui-sandbox --force
git branch -D experiment/ai-dashboard-ui

`

Jika hasilnya sudah sesuai, jangan gabungkan (merge) seluruh cabang sekaligus; gunakan mode interaktif untuk mengambil cuplikan kode file tampilan saja.

`bash
git checkout main
git checkout -p experiment/ai-dashboard-ui -- src/components/features/dashboard-card/dashboard-card-view.tsx

`

Sambil melihat potongan kode yang muncul di terminal, tekan y hanya untuk bagian yang Anda sukai, dan ketik n untuk menolak modifikasi yang aneh.

Jika sesi melewati 5 giliran, konteksnya akan mulai kabur dan model mulai melantur. Anda harus membersihkan sesi setiap kali hal itu terjadi.

  1. Pemeriksaan Tipe: Segera jalankan npx tsc --noEmit setelah membuat satu komponen. Lanjutkan ke prompt berikutnya hanya jika error tipe berjumlah 0.
  2. Kompresi Konteks: Jika percakapan menjadi panjang, ketik /compact tanpa ragu untuk mengurangi pemborosan token.
  3. Mengosongkan Sesi: Setelah pekerjaan layar selesai, tinggalkan commit dan bersihkan memori sepenuhnya dengan /clear. Jika terjadi kekacauan, gunakan /rewind untuk kembali ke titik pemeriksaan sebelumnya.

Kemampuan pembuatan model yang luar biasa dan kelayakan kode tersebut untuk masuk ke dalam produksi adalah dua hal yang sama sekali berbeda. Dengan mempersempit saluran input melalui CLAUDE.md, memverifikasi kode output dengan hook siklus hidup, dan memisahkan ruang kerja menggunakan worktree, Anda dapat menghindari begadang semalaman hanya untuk membereskan kode yang dimuntahkan oleh AI.