fe-stack

📁 ingpdw/pdw-fe-dev-tool 📅 6 days ago
1
总安装量
1
周安装量
#44046
全站排名
安装命令
npx skills add https://github.com/ingpdw/pdw-fe-dev-tool --skill fe-stack

Agent 安装分布

mcpjam 1
claude-code 1
replit 1
junie 1
zencoder 1

Skill 文档

Frontend Tech Stack Convention

기술스택

항목 선택
언어 TypeScript 5+ (strict mode)
UI 프레임워크 React 19+
메타 프레임워크 Next.js 16+ (App Router)
UI 컴포넌트 shadcn/ui + Radix UI
스타일링 Tailwind CSS v4
빌드 도구 Vite
테스트 Vitest + React Testing Library
패키지 매니저 pnpm
린팅 ESLint + Prettier

프로젝트 구조 (Next.js App Router)

src/
├── app/                    # App Router 라우트
│   ├── layout.tsx          # Root layout
│   ├── page.tsx            # Home page
│   ├── globals.css         # Global styles (Tailwind)
│   ├── (auth)/             # Route group
│   │   ├── login/page.tsx
│   │   └── signup/page.tsx
│   └── api/                # API Route Handlers
│       └── [resource]/route.ts
├── components/
│   ├── ui/                 # shadcn/ui 컴포넌트 (자동 생성)
│   ├── common/             # 공용 컴포넌트
│   └── [feature]/          # 기능별 컴포넌트
├── hooks/                  # 커스텀 훅
├── lib/                    # 유틸리티, 헬퍼
│   ├── utils.ts            # cn() 등 공용 유틸
│   └── api.ts              # API 클라이언트
├── types/                  # 전역 타입 정의
├── stores/                 # 상태 관리 (Zustand)
├── constants/              # 상수 정의
└── __tests__/              # 테스트 파일 (co-location 권장)

TypeScript 컨벤션

  • strict: true 필수
  • interface로 객체 타입 정의 (확장 가능), type은 유니온/인터섹션에 사용
  • any 사용 금지 → unknown + type guard 사용
  • 컴포넌트 Props는 interface로 정의, React.FC 사용하지 않음
  • as 타입 단언 최소화, 타입 가드 함수 선호
  • enum 대신 as const 객체 사용
// Props 정의
interface ButtonProps {
  variant?: "default" | "destructive" | "outline";
  size?: "sm" | "md" | "lg";
  children: React.ReactNode;
  onClick?: () => void;
}

// as const 패턴
const STATUS = {
  IDLE: "idle",
  LOADING: "loading",
  ERROR: "error",
} as const;
type Status = (typeof STATUS)[keyof typeof STATUS];

React 컨벤션

  • 함수 선언문으로 컴포넌트 정의 (function Component(), 화살표 함수도 허용)
  • Props destructuring 사용
  • 단일 책임 원칙: 컴포넌트는 하나의 역할만 담당
  • 조건부 렌더링: 삼항 연산자 또는 && (falsy 값 주의)
  • 이벤트 핸들러: handle[Event] 네이밍 (예: handleClick, handleSubmit)
  • 커스텀 훅: use[Name] 네이밍, 단일 관심사
  • key prop에 index 사용 금지 (안정적인 고유 ID 사용)
function UserCard({ name, email, onEdit }: UserCardProps) {
  const handleEditClick = () => onEdit(email);

  return (
    <Card>
      <CardHeader>
        <CardTitle>{name}</CardTitle>
      </CardHeader>
      <CardContent>
        <p className="text-muted-foreground">{email}</p>
        <Button variant="outline" onClick={handleEditClick}>
          Edit
        </Button>
      </CardContent>
    </Card>
  );
}

Next.js App Router 규칙

  • Server Component 기본, 필요 시 "use client" 선언
  • "use client"는 가능한 트리의 말단에 배치 (클라이언트 경계 최소화)
  • 데이터 페칭: Server Component에서 async/await로 직접 fetch
  • Server Actions: "use server" 함수로 폼 처리, 뮤테이션
  • loading.tsx, error.tsx, not-found.tsx 활용
  • Metadata: generateMetadata() 또는 정적 metadata 객체
  • Route Handler: GET, POST 등 named export 함수
  • 동적 라우트: [param] 폴더, generateStaticParams()로 정적 생성
  • Parallel Routes(@slot), Intercepting Routes((.)) 적절히 활용

shadcn/ui 규칙

  • npx shadcn@latest add [component]로 컴포넌트 추가
  • components/ui/에 생성된 코드를 프로젝트 요구에 맞게 커스터마이즈
  • cn() 유틸리티로 조건부 클래스 합성
  • Radix UI primitives 기반으로 접근성 내장
  • 테마 커스터마이즈는 globals.css의 CSS 변수로 관리
import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";

<Button className={cn("w-full", isActive && "bg-primary")} variant="outline">
  Click
</Button>

Tailwind CSS v4 규칙

  • 유틸리티 클래스 우선, 커스텀 CSS 최소화
  • @apply 사용 최소화 (컴포넌트 추출 선호)
  • 반응형: sm:, md:, lg:, xl:, 2xl: 접두사 (mobile-first)
  • 다크 모드: dark: 접두사 + CSS 변수 기반 테마
  • clsx 또는 cn() (tailwind-merge)로 동적 클래스 합성

상태 관리

  • 로컬 상태: useState, useReducer
  • 서버 상태: TanStack Query (React Query)
  • 전역 클라이언트 상태: Zustand
  • URL 상태: useSearchParams, nuqs
  • 폼 상태: React Hook Form + Zod 유효성 검사

파일 네이밍 규칙

대상 규칙 예시
컴포넌트 PascalCase UserProfile.tsx
훅 camelCase (use 접두사) useAuth.ts
유틸리티 camelCase formatDate.ts
타입 PascalCase UserTypes.ts
상수 camelCase 파일, UPPER_SNAKE 변수 apiEndpoints.ts
테스트 원본명.test UserProfile.test.tsx
페이지 (App Router) 소문자 폴더 app/dashboard/page.tsx

Import 순서

// 1. React/Next.js
import { useState } from "react";
import Link from "next/link";

// 2. 서드파티 라이브러리
import { useQuery } from "@tanstack/react-query";
import { z } from "zod";

// 3. 내부 컴포넌트 (shadcn/ui 포함)
import { Button } from "@/components/ui/button";
import { UserCard } from "@/components/user/UserCard";

// 4. 훅, 유틸, 타입
import { useAuth } from "@/hooks/useAuth";
import { cn } from "@/lib/utils";
import type { User } from "@/types";