1. 배경 및 문제 정의
새로운 기능인 '홈 화면 퀴즈 위젯'을 도입하는 과정에서 두 가지 상반된 과제에 직면했습니다.
- 기능적 요구사항: 약 400문항이 넘는 방대한 퀴즈 데이터를 사용자에게 매끄럽게 전달하고 인터랙션을 처리할 수 있는 엔진 구축 필요.
- 개발 환경(DX)의 결함: Windows 환경 사용 팀원의 로컬에서
Delete ␍ prettier/prettier에러와 함께 모든 파일의 린트가 깨지는 현상 발생. 이는 CI/CD 파이프라인을 중단시키는 치명적인 허들이 되었습니다.
2. 원인 분석
2.1 CRLF vs LF의 해묵은 갈등
근본 원인은 운영체제별 줄 바꿈(Line Ending) 처리 방식의 차이였습니다.
- Windows: CR(\r) + LF(\n) 사용
- Unix/Mac: LF(\n)만 사용
Prettier 기본 설정이 LF를 강제하고 있었기에, Windows에서 자동 생성된 CR 문자를 "삭제해야 할 유효하지 않은 문자"로 인식한 것입니다.
2.2 대량 데이터 처리에 따른 아키텍처 부재
퀴즈 데이터가 400개를 넘어가면서 이를 컴포넌트 내부에 상수로 선언할 경우, 가독성 저하 및 번들 사이즈 증가가 예견되었습니다. 또한 클라이언트 측에만 로직이 존재할 경우 보안 및 확장성에 한계가 있었습니다.
3. 해결 방안 검토
| 방안 | 장점 | 단점 | 결정 |
|---|---|---|---|
| A. .gitattributes 설정 | 가장 근본적인 해결 | 모든 팀원의 로컬 설정 필요 | - |
| B. 린트 규칙 비활성화 | 설정 간소화 | 코드 일관성 저하 위험 | 폐기 |
| C. endOfLine: auto 변경 | OS별 유연한 대응 가능 | 약간의 관리 포인트 발생 | 최종 선택 |
4. 구현 과정
4.1 핵심 로직: 퀴즈 엔진과 API
데이터와 로직을 분리하기 위해 src/data 계층을 신설하고, 서버 측 API Route를 통해 검증을 처리했습니다.
// src/app/api/quiz/submit/route.ts
export async function POST(request: Request) {
const { quizId, answer } = await request.json();
const quiz = quizData.find((q) => q.id === quizId);
if (!quiz) {
return NextResponse.json({ error: 'Quiz not found' }, { status: 404 });
}
const isCorrect = quiz.answer === answer;
return NextResponse.json({ isCorrect, explanation: quiz.explanation });
}
4.2 설정 최적화
Windows 사용자의 생산성을 위해 .prettierrc를 다음과 같이 수정했습니다.
{
"singleQuote": true,
"endOfLine": "auto"
}
5. 개선 결과
- Lint Pass Rate Windows 환경 린트 에러 100% → 0% 해결.
- Build Stability CI 파이프라인 및 빌드 타임 정상화.
- Clean Code 데이터 레이어 분리를 통해 메인 컴포넌트 코드 라인을 300라인 이내로 유지.
정성적으로는 OS 차이로 인한 소모적인 논쟁이 사라지고, 퀴즈 도메인이 명확히 분리되어 확장성이 확보되었습니다.
6. 회고
이번 작업을 통해 다시 한번 느낀 점은, 기술적 이상향보다 팀의 유연한 협업을 돕는 설계가 더 중요하다는 것 앞으로 꾸준히 기록하고 복습하자.
'SSAC프로젝트' 카테고리의 다른 글
| [OAuth2] 카카오 보안 : 토큰 노출 계정 충돌 해결 (0) | 2026.04.22 |
|---|
