뒤로가기
GameCord - 01 프로젝트 세팅하기
목차
- 프로젝트 기획하기
- 프로젝트에 사용할 기술 결정하기
- NextJs로 프로젝트 구성하기
- 핵심 기술 구현 세부사항
프로젝트 기획하기
어떤 주제를 프로젝트 주제로 선정할까?
해당 프로젝트를 처음 기획한 건 2024년 봄쯤이었습니다.
그때 한창 여러 싱글 PC 게임을 즐기고 있었고, 여러 모드들을 구하거나 제작하였습니다.
하지만 모드 대부분의 정보는 해외 사이트에 존재하였고, 게임에 대한 정보들도 주로 해외 사이트에서 구하는 일이 많았습니다.
이러한 상황에 불편함을 느껴 시작하게 된 것이 해당 프로젝트입니다.
프로젝트를 한줄로 설명하기
게임 관련 정보와 평가를 공유하고 커뮤니티 활동을 할 수 있는 종합 플랫폼을 만들어 국내 게이머들에게 제공하고자 합니다.
프로젝트에 사용할 기술 결정하기
핵심 기술 선택 과정
1. 인증 시스템: Auth.js vs Clerk
Auth.js를 선택한 주요 이유
- 커스터마이징의 자유도: Clerk은 편리하지만, 커스터마이징에 제한이 있습니다. Auth.js는 완전한 제어가 가능합니다.
- 비용 효율성: Clerk의 경우 사용자 수가 증가하면 비용이 급격히 증가할 수 있습니다.
- Prisma 통합: Auth.js는 Prisma adapter를 통해 원활한 통합이 가능합니다.
- 오픈소스: 커뮤니티 지원과 투명성이 높습니다.
2. ORM: Prisma vs Drizzle
Prisma를 선택한 이유
- 타입 안정성: Prisma의 강력한 타입 생성 기능은 개발 안정성을 높여줍니다.
- 스키마 관리: 직관적인 스키마 정의와 마이그레이션 관리가 가능합니다.
- 개발자 경험: 풍부한 자동완성과 IDE 지원으로 생산성이 향상됩니다.
- Auth.js 통합: Prisma adapter를 통한 매끄러운 인증 시스템 통합이 가능합니다.
3. 데이터베이스: PostgreSQL
PostgreSQL을 선택한 이유
- 확장성: 게임 데이터와 사용자 정보의 복잡한 관계를 효율적으로 처리할 수 있습니다.
- JSON 지원: 게임 메타데이터와 같은 유연한 데이터 구조를 저장하기 용이합니다.
- 전문 검색: 게임 검색 기능 구현에 필요한 고급 검색 기능을 제공합니다.
- 무료 호스팅: Vercel Postgres를 통해 초기 단계에서 무료로 시작할 수 있습니다.
4. UI 프레임워크: shadcn/ui
shadcn/ui를 선택한 이유
- 재사용성: 잘 설계된 컴포넌트로 일관된 UI를 구축할 수 있습니다.
- 커스터마이징: Tailwind CSS 기반으로 쉽게 스타일을 수정할 수 있습니다.
- 접근성: 기본적으로 높은 접근성 표준을 준수합니다.
- 번들 크기: 필요한 컴포넌트만 복사하여 사용할 수 있어 번들 크기를 최적화할 수 있습니다.
핵심 구현 세부사항
1. Prisma 초기화 최적화
import { PrismaClient } from '@prisma/client';
const globalForPrisma = globalThis as unknown as { prisma: PrismaClient };
export const prisma = globalForPrisma.prisma || new PrismaClient();
if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma;
이러한 구현 방식을 선택한 이유:
- 핫 리로딩 최적화: 개발 환경에서 불필요한 데이터베이스 연결 생성을 방지합니다.
- 커넥션 풀 관리: 단일 Prisma 인스턴스를 보장하여 리소스를 효율적으로 관리합니다.
- 글로벌 상태 관리: Next.js의 개발 환경에서 발생할 수 있는 다중 인스턴스 문제를 해결합니다.
Prisma Client 초기화 방식 비교
Optimized Initialization
const globalForPrisma = globalThis as unknown as {
prisma: PrismaClient
};
export const prisma =
globalForPrisma.prisma || new PrismaClient();
if (process.env.NODE_ENV !== "production") {
globalForPrisma.prisma = prisma;
}
Development Hot Reload Simulation
Database
Connections: 1
Hot Reloads: 0
주요 차이점:
- 기본 방식: 매 핫 리로드마다 새로운 Prisma Client 인스턴스가 생성됩니다.
- 최적화된 방식: globalThis를 활용하여 단일 인스턴스를 유지하며, 개발 환경에서의 불필요한 연결을 방지합니다.
- 현재 1개의 연결만 유지
2. Auth.js와 Prisma 통합
import { PrismaAdapter } from '@auth/prisma-adapter';
import { prisma } from '@/db/prisma';
export const authConfig = {
adapter: PrismaAdapter(prisma),
providers: [
// OAuth providers configuration
],
callbacks: {
session: async ({ session, user }) => {
if (session.user) {
session.user.id = user.id;
// Additional user data
}
return session;
},
},
};
통합 구현의 장점
- 타입 안정성: Prisma의 타입 시스템과 Auth.js가 완벽하게 통합됩니다.
- 세션 관리: 데이터베이스 기반의 안정적인 세션 관리가 가능합니다.
- 확장성: 사용자 정보를 쉽게 확장할 수 있습니다.
부가적인 기술 스택
-
상태 관리 & 폼
- React Hook Form
- Zod 스키마 검증
-
UI/UX
- Framer Motion
- Radix UI
- sonner
-
개발 도구
- TypeScript
- ESLint & Prettier
- Turbopack
NextJs로 프로젝트 구성하기
프로젝트 구조
프로젝트는 다음과 같은 구조로 설계되었습니다
src/
├── actions/ # 서버 액션
├── app/ # 페이지 및 레이아웃
├── components/ # 재사용 가능한 컴포넌트
├── constants/ # 상수 값
├── db/ # 데이터베이스 설정
├── hooks/ # 커스텀 훅
├── lib/ # 유틸리티 함수
├── providers/ # 컨텍스트 프로바이더
├── schemas/ # 검증 스키마
├── services/ # API 서비스
└── types/ # 타입 정의
주요 설정
-
환경 요구사항
- Node.js >= 21
- pnpm >= 9
-
개발 환경
pnpm dev # 개발 서버 실행 (Turbopack) pnpm build # 프로덕션 빌드 pnpm lint # 린트 검사 pnpm format # 코드 포맷팅
-
주요 의존성
- 인증: @auth/prisma-adapter, next-auth, bcryptjs
- UI: radix-ui 컴포넌트, framer-motion
- 개발 도구: TypeScript, ESLint, Prettier
0