프론트/React
사내 서비스 개편 후기
ZestLee
2024. 8. 12. 21:37
후기를 남겨 보자
개요
- 개편을 시작하게 된 이유
- UI 가 변경되면서, 프로젝트를 통합하고 최신 기술로 업그레이드할 기회로 삼았다.
- 개편의 주요 목표
- Next.js 도입
- 여러 프로젝트를 하나로 합치기
- 개편되는 페이지의 UI 통일
- 컴포넌트 스펙 일관성 유지
기술 선택
- Next.js
- 기존 프로젝트들이 모두 React 기반이었기에 자연스럽게 Next.js를 도입했다.
- Zustand
- 상태 관리가 필요해 전역적인 store로 Zustand를 사용했다.
개발 과정에서 있었던 문제점
- 공통 컴포넌트 설계
- CI 스크립트 작성
- Next.js에서 React로의 전환
- 정적 페이지로 전환해야 한다는 의견이 개발이 상당히 진행된 후에 나왔다.
- 서버 확장성에 대한 테스트가 완료되지 않은 상태였기 때문에.. 반대 의견이 나왔다.
- 정적 페이지로 전환해야 한다는 의견이 개발이 상당히 진행된 후에 나왔다.
- 전역 에러 페이지 발생
- 템플릿에서 타입 에러가 발생하면 페이지 전체가 에러로 연결되었다.
문제 해결 방법
- CI 스크립트 작성
- GitLab CI로 스크립트를 작성했다.
- 현재는 React 기반으로 배포 중이므로 그대로 사용해도 문제없으나, 서버를 운영하는 방향으로 전환된다면 Docker로 환경을 설정하는 것이 나을 것 같다.
- Next.js에서 React로의 전환
- React Router DOM을 도입하여 모든 라우트를 layout에 추가했다.
- Next.js 전용 페이지 이동 함수를 React Router DOM으로 변경했다.
- next build를 export 옵션으로 설정하여 정적인 index.html만 나오도록 수정했다.
- SEO가 필요한 부분은 Apache에서 user agent가 bot인 경우에만 PHP 파일을 참조하도록 설정했다.
- 이 PHP 파일은 정적인 title, description을 가지고 있다.
- 전역 에러 페이지 발생 문제
- 옵셔널 체이닝을 사용하여 데이터 접근 시 타입 에러를 방지했다.
- ErrorBoundary 컴포넌트를 추가하여, 오류가 자주 발생하는 부분을 보호했다.
- 이를 통해 컴포넌트 단위에서 에러를 처리하고, 페이지 전체로 전파되지 않도록 막았다.
후회되는 설계
공통 컴포넌트 설계의 아쉬움
- 컴포넌트의 공통화 실패
- API 응답값의 필드명이 일관되지 않아, 같은 성격의 필드에도 서로 다른 이름이 사용되었다.
- 그 결과, 같은 성격의 값들을 처리하기 위해 prop이 60개로 늘어나는 문제가 발생했다.
Zustand 사용 다시 생각해보기
- Zustand 도입의 장점
- 각 페이지의 상태를 컴포넌트 단위로 관리하면서, props drilling을 방지하기 위해 Zustand를 사용했다.
- 다이얼로그에서도 백그라운드의 데이터를 쉽게 업데이트할 수 있었다.
- 단점
- 컴포넌트가 커지면서 상태 업데이트가 중복되거나, 예상치 못한 업데이트가 발생했다.
- Zustand를 남발하기보다는, 정말 전역 상태가 필요한 부분에서만 사용하는 것이 더 나았을 것 같다.
- 오히려 props drilling을 허용했다면 상태 변경의 위치를 더 명확하게 파악할 수 있었을 것이다.
공통 로그 함수 설계의 아쉬움
- 공통 로그 함수의 복잡성 증가
- 로그 함수를 유틸리티로 빼기 위해 특정 함수를 만들었으나, 의도와 달리 복잡해졌다.
- 로그를 추적하기 어렵고, 알 수 없는 로그가 발생하는 문제가 생겼다.
- 차라리 초기 구상처럼 컴포넌트를 Context로 묶어 내부에서 훅으로 함수를 호출하는 방식이 나았을 것 같다.
- 로그 내용을 컴포넌트에 직접 두고 관리하는 편이 더 나았을 것 같다.
결론: 리팩토링의 필요
이번 개편을 통해 많은 부분이 개선되었지만, 진행 과정에서 발견된 몇 가지 문제들이 여전히 아쉽다.
특히 공통 컴포넌트에서 너무 많은 prop을 사용하는 문제, Zustand를 너무 광범위하게 사용한 점, 그리고 공통 로그 함수의 복잡성 등은 앞으로 유지보수와 확장성에 문제가 될 수 있다.
이런 문제들을 지금 해결하지 않으면, 나중에 더 큰 어려움을 겪을 수 있다. 그래서 지금이 리팩토링을 통해 코드를 개선할 좋은 시점이라고 생각한다.
아래와 같은 리팩토링 방향을 다시 생각하였다
1. 공통 컴포넌트의 구조 재설계
- 비슷한 성격의 필드 이름을 통일하고, prop의 수를 줄여서 컴포넌트를 더 단순하게 만들어야 한다. 이렇게 하면 코드가 더 읽기 쉬워지고, 유지보수도 더 수월해질 것이다.
- 예를 들어, 컴포넌트에서 필드 이름을 통일하고, 필요하다면 유틸리티 함수를 사용해 변환 작업을 처리할 수 있다.
2. 상태 관리 전략의 개선
- Zustand의 사용 범위를 더 명확히 해서, 정말 필요한 경우에만 전역 상태 관리로 사용하도록 제한하는 것이 좋다. props drilling을 적절히 사용하면 상태가 어디서 어떻게 변경되는지 더 쉽게 파악할 수 있을 것이다.
- 예를 들어, 주요 상태를 페이지 단위로 관리하고, 정말 전역적으로 필요한 상태만 Zustand로 관리하는 구조로 바꿀 수 있다.
3. 로그 함수의 단순화
- 공통 로그 함수를 단순화하고, 필요할 때 컴포넌트 내부에서 직접 로그를 호출하는 방식으로 바꾸는 것이 좋다. 이렇게 하면 로그 함수가 더 간단해지고, 관리도 더 쉬워질 것이다.
- 예를 들어, 로그를 Context로 묶고, 컴포넌트에서 직접 그 함수를 호출하도록 해서 관리 범위를 더 명확히 할 수 있다.