[인프런 워밍업 클럽 Full Stack 3기] 2주차

[인프런 워밍업 클럽 Full Stack 3기] 2주차

1. 학습 내용

1.1. Supabase Storage

  • 파일과 이미지를 저장하고 관리하기 위한 서비스 (아마존 S3와 유사)

1.1.1. 주요 개념

  • 버킷(Buckets): 파일을 논리적으로 구분하는 컨테이너

  • 객체(Objects): 저장된 개별 파일

  • 정책(Policies): 파일에 대한 접근 권한 규칙

 

2. 미션

2.1. 미션 내용

  • 파일 목록에서 각 파일의 "마지막 수정 시간"을 표시

2.2. 미션 진행

- 리액트 쿼리로 요청, 응답 받은 이미지 데이터 객체 내 update_at 키-값을 이미지 컴포넌트에 표시함으로써 작업을 진행했습니다.

image

3. 추가 학습 및 적용 기술

3.1. pnpm 도입과 경험

npm의 문제점(패키지 중복 설치, 디스크 낭비)에 불편함을 느껴 이번 기회에 pnpm을 도입했습니다. 설치 속도가 확연히 빨라진 것을 체감할 수 있었습니다.

3.1.1. npm과 pnpm의 주요 차이점

저장 구조와 디스크 사용량

  • npm: 프로젝트마다 의존성 중복 저장으로 디스크 낭비

  • pnpm: 전역 저장소에 패키지를 한 번만 저장하고 심링크로 연결하여 공간 절약

성능

  • npm: 중복 다운로드로 인한 네트워크 부하 및 시간 소요

  • pnpm: 공유 저장소와 링크 기반 구조로 설치 속도 향상, 병렬 처리 최적화

3.2. material-tailwind 경고 제거

material-tailwind 컴포넌트 사용 시 발생하는 경고 메시지를 d.ts 파일을 통해 제거했습니다. 이 방법이 안전한지 고민했지만, 큰 문제가 없다고 판단하여 적용했습니다. 인프런 커뮤니티의 질문과 답변이 해결에 도움이 되었습니다.

3.3. supabase storage type 적용

db type과 달리 storage type은 supabase cli를 통해 자동 생성할 수 없다는 점을 알게 되었습니다. 대신 `@supabase/storage-js` 플러그인을 통해 필요한 type을 활용할 수 있었습니다.

// UploadedImage Component
import { FileObject } from '@supabase/storage-js';
// ...existing code...

export default function UploadedImage({
  file: { name, updated_at },
}: {
  file: FileObject;
}) {
  return (// component)
}

3.4. prettier 설정

GitHub Copilot의 도움을 받아 Next.js 프로젝트에 적합한 옵션으로 설정했으며, prettier-plugin-tailwindcss를 통해 Tailwind 클래스 자동 정렬 기능을 추가했습니다.

// .prettierrc
{
  "singleQuote": true,
  "semi": true,
  "useTabs": false,
  "tabWidth": 2,
  "trailingComma": "es5",
  "printWidth": 80,
  "arrowParens": "avoid",
  "jsxSingleQuote": false,
  "bracketSpacing": true,
  "bracketSameLine": false,
  "htmlWhitespaceSensitivity": "css",
  "requirePragma": false,
  "insertPragma": false,
  "proseWrap": "preserve",
  "endOfLine": "auto",
  "plugins": [
    "prettier-plugin-tailwindcss"
  ]
}

3.5. eslint 설정

@tanstack/eslint-plugin-query를 도입하여 React Query 사용 시 모범 사례를 따르도록 설정했습니다. 이를 통해 쿼리 키 검증, 의존성 확인 등의 이점을 얻을 수 있었습니다.

// .eslint.json
{
  "plugins": ["@tanstack/query"],
  "extends": ["next/core-web-vitals", "plugin:@tanstack/query/recommended"]
}

 

4. 아쉽게 적용하지 못한 기술

아래 3 가지 항목들은 모두 조사, 기능 개발 계획, 프로젝트에 일부 적용까지 하기도 했으나 시간이 부족해 결국 완성되지 못한 기능들입니다.

4.1. 한글 파일명 업로드 문제 해결

Supabase Storage에서 한글 이름의 파일을 업로드할 수 없는 문제에 직면했습니다. 원인은 파일명 인코딩 과정이 없어서 발생한 문제였습니다. 두 가지 해결책을 구상했지만 시간 부족으로 완성하지 못했습니다.

  1. 파일정보 DB 테이블 접근법: 파일명과 UUID를 매핑하여 DB에 저장하고, 실제 스토리지엔 UUID로 업로드하는 방식

    image

  2. customMetadata 활용: Supabase Storage의 메타데이터 기능을 활용하는 방식

4.2. 직접 Tailwindcss 컴포넌트 구현 시도

material-tailwind 대신 Tailwindcss만으로 모든 컴포넌트를 스타일링해보고 싶었으나, 시간 부족으로 실현하지 못했습니다.

4.3. 컴포넌트 구조 설계의 고민

개발자 관점에서 명확하고 구분하기 쉬운 파일 구조를 만들기 위해 다양한 React 컴포넌트 구조 패턴을 조사했습니다.
각 패턴의 장단점을 분석하며 프로젝트에 가장 적합한 구조를 고민했지만, 시간 관계상 실제 적용은 제한적이었습니다.
제가 찾아본 React 주요 패턴들은 다음과 같습니다. 이해를 돕기 위해 각 패턴마다 특징 및 예시 코드까지 준비하였으나 글이 너무 길어져 읽는데 어려움이 있을 것 같아 최종적으로 간단하게 한 줄로 요약했습니다.

4.3.1. Presentational and Container Pattern

로직과 UI를 분리하는 패턴으로, 재사용성과 테스트 용이성이 향상되지만 props drilling 문제가 발생할 수 있습니다.

4.3.2. Compound Component Pattern

복합적인 UI를 구성하는 관련 컴포넌트들을 그룹화하고 내부적으로 상태를 공유하는 패턴입니다. API 사용 경험은 향상되지만 TypeScript 타입 정의가 복잡해질 수 있습니다.

4.3.3. Render Props Pattern

컴포넌트의 렌더링 로직을 prop 함수로 전달하는 방식으로, 로직 재사용은 용이하지만 콜백 중첩으로 인한 디버깅 어려움이 있을 수 있습니다.

4.3.4. Custom Hook Pattern

로직을 훅으로 추출하여 여러 컴포넌트에서 재사용하는 패턴입니다. React의 핵심 패턴 중 하나로, UI와 로직의 분리가 명확합니다.

4.3.5. Context API Pattern

여러 컴포넌트에서 데이터를 공유하기 위한 패턴으로, props drilling을 방지할 수 있지만 불필요한 리렌더링이 발생할 수 있습니다.

4.3.6. Atomic Design Pattern

UI 컴포넌트를 원자(Atoms), 분자(Molecules), 유기체(Organisms), 템플릿(Templates), 페이지(Pages)로 나누는 구조로, 체계적인 UI 구성이 가능하지만 초기 설계 시간이 많이 소요됩니다.

4.3.7. Client/Server Component Pattern

Next.js 14 App Router의 핵심 패턴으로, 서버에서 데이터를 페칭하고 클라이언트에서 인터랙션을 처리하여 번들 크기를 최적화합니다.

4.3.8. Server Components and Suspense Pattern

데이터 로딩 상태를 선언적으로 처리하는 패턴으로, 점진적 UI 로딩을 지원하고 사용자 경험을 향상시킬 수 있습니다.

 

5.마무리

이번 스터디를 통해 많은 것을 배우고 적용해보는 즐거움을 느꼈습니다. 계획했던 것보다는 적게 구현했지만, 새로운 기술들을 탐색하고 실험해본 경험은 매우 가치 있었습니다.
더 많은 공부 시간을 확보하니 다양한 시도를 해볼 수 있었지만, 동시에 욕심이 커져 모든 계획을 실현하지는 못했습니다. 3주 차에는 개인 약속으로 인해 학습 시간이 줄어들 것 같지만, 지금까지의 경험을 바탕으로 더 효율적으로 학습하고 구현해보겠습니다.
무엇보다, 호기심을 가지고 새로운 기술을 탐색하고 적용해보는 과정 자체가 개발자로서 성장하는 중요한 발판이 된다는 것을 다시 한번 느낄 수 있었습니다.

 

댓글을 작성해보세요.


채널톡 아이콘