-
Notifications
You must be signed in to change notification settings - Fork 50
[4팀 한선민] Chapter2-1. 프레임워크 없이 SPA 만들기 #34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Code ReviewQ1저는 router/index.js로 named exports 하고, Q2평소에는 통일하지만, 이번 과제에선 안했던 것 같슨.. Q3저는 팀 위키 노션 | 페이지 활용해서 둘 다 쓰는 편입니다. 작업 전 보통 husky로 논의하게 되고, 추가하고 싶으면 슬랙 등으로 이슈 올리고 협의해서 데일리 스크럼에서 논의 후 확정하는 편..? |
JunilHwang
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이 피드백은 n8n + ai (gpt-5-mini)를 활용하여 자동으로 생성된 내용입니다.
전체 리뷰 요약
이번 PR은 기능 구현 요구사항을 잘 반영하여 SPA 완성도를 높인 점이 매우 인상적입니다. 특히 제품 목록 로딩, 필터/검색, 무한 스크롤, 장바구니 상태 관리, 토스트 메시지, URL 기반 상태 복원 등 실무에서 쓰이는 핵심 기능을 꼼꼼히 구현하셨습니다.
현재 프로젝트 아키텍처 주요 특징
- 기능별 폴더 분리(api, components, events, pages, router, store, utils 등)로 관심사 분리가 잘 되어 있음
- 옵저버 패턴 및 이벤트 버스(eventBus)를 활용한 상태 관리 및 컴포넌트 간 느슨한 결합
- 커스텀 라우터 설계 및 enhancer 패턴 적용으로 라우터 확장성 고려
- 상태 변화에 따른 UI 업데이트 및 이벤트 위임 패턴 일부 적용 중
확장성과 유지보수 관점 개선 제안
- 이벤트 리스너 관리: 동적 DOM 요소에 대한 반복적인 이벤트 리스너 등록/제거 대신 이벤트 위임 패턴을 본격 적용해 메모리 누수와 성능 이슈 완화 가능
- 컴포넌트 분리 및 역할 명확화: 렌더링과 상태 업데이트, 이벤트 핸들링 기능을 컴포넌트 내에서 명확히 분리하면 유지보수와 테스트에 유리
- 라우터 매칭과 URL 관리: 경로 매칭 강화 및 URL 파라미터 처리를 모듈화해 향후 기능 확장 대비
- 네이밍과 폴더 구조 정교화: 컴포넌트 파일명 통일, 이벤트 핸들러 위치 재검토 및 중첩 폴더 깊이 조절 등이 도움이 됨
종합적으로 현재 구조는 실무에서 충분히 활용 가능한 형태이며, 소규모에서 중간 규모 SPA에 적합합니다. 다만, 팀 협업과 프로젝트 확장 시 위 제안들을 바탕으로 리팩토링 해 나가면 더욱 견고한 아키텍처가 될 것입니다.## 1. CartModal.js 이벤트 리스너 관리
현재 setupCartModal에서 렌더링 후 기존 리스너를 제거(removeEventListener)하고 다시 등록하는 패턴을 사용 중이신데, 기본적으로는 메모리 누수를 방지하는 좋은 습관입니다. 그러나 실제로 매번 동일한 리스너를 제거하고 다시 추가하는 것은 비용이 있고, 특히 이벤트 대상이 많을 경우 성능에 영향을 줄 수 있습니다.
더 효율적인 방법은 이벤트 위임(event delegation) 방식을 적극 활용하는 것입니다. 즉, 변경이 잦은 하위 요소 각각에 리스너를 붙이지 않고, 상위 컨테이너 한 곳에 이벤트 리스너를 달아놓고 이벤트 버블링을 통해 실제 이벤트 타겟을 판별하여 처리하는 방법입니다. 이렇게 하면 리스너 중복 등록이나 관리가 훨씬 간단해지고, 메모리 사용도 최적화됩니다.
isSetup 플래그를 활용해 setupCartModal이 중복 실행되지 않도록 한 것은 적절한 패턴이며, 이벤트 위임과 결합할 경우 더욱 견고해질 수 있습니다.
2. 이벤트 리스너 Cleanup 로직
SPA 구조에서 페이지 전환 없이 상태나 화면을 변경하는 경우, 메모리 누수나 이벤트 중복 문제가 발생하지 않도록 이벤트 리스너를 명확히 정리(cleanup)하는 것이 베스트 프랙티스입니다. 특히 다음 경우에 cleanup이 필요합니다:
- 컴포넌트가 라이프사이클이 존재하는 프레임워크(React 등)처럼 생성/제거를 반복하는 경우
- 라우터 변경에 의해 같은 컴포넌트가 재생성되어 이벤트가 중복 등록되는 경우
현재 프로젝트처럼 컴포넌트가 주로 수동 렌더링으로 관리된다면, 이벤트 리스너를 router.subscribe 구독과 함께 등록하고, 이전 구독을 해제하는 패턴으로 관리할 수 있습니다. 예를 들어,
let cleanup = () => {};
router.subscribe(() => {
cleanup();
cleanup = bindEventHandlers();
});이처럼 구독 해제 함수를 항상 반환하고 관리하면 메모리 누수와 중복 실행 문제를 막을 수 있습니다.
만약 앱 규모가 커지거나 복잡해지면 이벤트 관리 라이브러리를 쓰거나, 프레임워크 도입도 고려할 옵션입니다.
3. 디렉토리 구조와 모듈 분리
현재 src/ 아래 api, components, events, pages, router, store, utils 등의 기능 구분은 매우 일반적이고 협업에서도 익숙한 구조입니다. 아래 참고하세요:
- events 폴더 위치: 이벤트 핸들러를
events/에 모으는 것도 가능하지만, 관련 컴포넌트나 페이지와 밀접하게 연관되는 이벤트라면 해당 컴포넌트 혹은 페이지 폴더 내에 두는 것도 유지보수에 유리합니다. 대형 프로젝트라면features/폴더 단위(또는 컴포넌트별)로 이벤트 관리하는 게 좋습니다. - router/enhancers 중첩: enhancer별로 라우터 확장 기능을 분리하는 구조도 모듈성과 관심사 분리에 좋습니다.
- 컴포넌트 그룹화:
components/를 그냥 공통 컴포넌트 모음으로 둘 수도 있지만, 페이지 별(HomePage/,DetailPage/,Cart/)로 폴더를 나눠 관련 컴포넌트를 묶는 게 명확한 대형 프로젝트에서는 추천됩니다. 이 경우 컴포넌트 재사용 범위를 고려해 공용 컴포넌트는common/폴더 등으로 별도 분리하면 좋습니다.
요약하면, 지금 구조는 학습과 작은 팀에 적합하며, 확장 시 위와 같이 재구성하거나 혼합해서 사용하는 것이 일반적입니다.
4. 네이밍 컨벤션
-
함수명 prefix:
setup*,handle*,update*등 직관적 기능 기반 prefix는 실무에서 널리 사용됩니다. 일관성 있게 사용하는 것이 중요합니다. -
함수명 명확성:
ensureRendered()같은 이름은 기능이 불명확할 수 있어, 보통renderCartModal()혹은updateCartModalUI()같은 명확한 네이밍이 선호됩니다. -
파일명:
- 이벤트 파일명에 복수형(
homepageEvents.js) 사용도 흔하지만,EventHandlers.js또는EventManager.js같이 좀 더 기능적으로 네이밍하는 방식도 있습니다. - 컴포넌트 파일명은 PascalCase (
CartModal.js)가 더 표준적이며, React 등 대부분 프레임워크와 일관됩니다.
- 이벤트 파일명에 복수형(
-
지향점:
- 네이밍 컨벤션은 팀/프로젝트 기준에 따라 다르므로, 사전에 컨벤션 문서를 만들고 이를 코드 리뷰에서 공유 및 점검하는 것이 이상적입니다.
- 리뷰 시 네이밍 불일치는 "의미가 모호하거나 혼란을 줄 수 있는 부분"을 구체적으로 지적하고, 더 명확한 대안을 함께 제시하는 방식이 효과적입니다.
5. 컨벤션 관리 방식
- 경험상 컨벤션은 초기 문서화(README, Wiki, 별도 컨벤션 가이드)를 기본으로 하며, 린트(ESLint, Prettier 등)를 통해 자동화하는 게 매우 효과적입니다.
- 코드 리뷰에서 컨벤션 위반은 가능한 자동화 도구에 맡기고, 공유된 규칙에서 벗어난 부분에 대해 가볍게 피드백 하는 형태입니다.
- 새 규칙 도입 시 예시 코드를 첨부하거나, 린트 룰을 추가해 적용 사례를 명확히 제시하는 방식을 선호합니다.
- 초기에는 개인 프로젝트 기준 컨벤션을 참고하여 최소한의 규칙부터 시작해서
차근차근 팀에 맞게 발전시키는 과정이 자연스럽습니다.
| <span class="text-lg font-bold text-gray-900">총 금액</span> | ||
| <span id="cart-modal-total-price" class="text-xl font-bold text-blue-600">${totalPrice.toLocaleString()}원</span> | ||
| </div> | ||
| <!-- 액션 버튼들 --> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1. CartModal의 이벤트 리스너 관리
setupCartModal에서 동적 생성 요소에 대해 기존 리스너 제거 후 재등록하는 방식을 사용하고 있습니다.
- 현재 방식은 메모리 누수를 어느 정도 방지할 수 있으나, DOM에 많은 요소가 있을 경우 불필요한
removeEventListener/addEventListener호출이 반복되어 성능 저하 우려가 있습니다. - 더 효율적인 방법으로는 '이벤트 위임(event delegation)' 패턴 사용을 권장합니다. 상위 컨테이너(예:
#cart-modal)에 이벤트를 한 번만 바인딩하고, 이벤트 버블링을 활용해 이벤트 대상 요소를 판별하는 방식입니다. isSetup플래그를 통한 중복 설정 방지는 적절하나, SPA에서 컴포넌트가 자주 리렌더링 되거나 언마운트/마운트 시 이벤트 구독 정리가 필요할 수 있어 보완해야 합니다.
| <div class="text-gray-400 mb-4"> | ||
| <svg class="mx-auto h-12 w-12" fill="none" stroke="currentColor" viewBox="0 0 24 24"> | ||
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 3h2l.4 2M7 13h10l4-8H5.4m2.6 8L6 2H3m4 11v6a1 1 0 001 1h1a1 1 0 001-1v-6M13 13v6a1 1 0 001 1h1a1 1 0 001-1v-6"></path> | ||
| </svg> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2. CartModal 초기 렌더링 및 업데이트 로직 분리
렌더링 로직과 상태 업데이트를 한 함수에서 처리하는 구조인데, 이로 인해 함수가 복잡하고 유지보수가 어려워질 수 있습니다.
- 상태 변경과 DOM 렌더링을 별도의 함수로 분리하면 테스트 및 확장이 용이해집니다.
- 예를 들어, 상태 변화시 변경할 부분(체크박스 상태, 총 금액 표시 등)을 업데이트하는 함수와 전체 UI를 다시 그리는 함수로 구분할 수 있습니다.
| let state = { | ||
| homepage: createHomepageState(), | ||
| cart: loadCartFromStorage(), | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
3. 상태 관리 - 불변성 및 저장소 일관성 유지
- 상태 변경 시 객체를 불변하게 다루고 있음은 좋은 패턴입니다.
- 다만
updateCart나updateHomepage함수 내에서 복잡한 상태 변경 시 최소한의 변화를 감지하고 최소한으로 상태를 변경하는 최적화가 가능합니다. - 이 컴포넌트는 전체 상태를 한 군데서 관리하고 있어, 추후 기능 확장 시 상태 분리 혹은 컴포넌트별 별도 모듈화 고려해야합니다.
|
|
||
| if (loading !== undefined) { | ||
| sentinel.dataset.loading = loading ? "true" : "false"; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
4. 이벤트 핸들러 내 비동기 로직 처리
handleProductsLoadMore는 비동기 API 호출과 상태 업데이트가 섞여 있습니다.- Promise의 에러 처리를 로그만 하는 방식이기 때문에 개선 여지가 있습니다.
- 에러 발생 시 사용자에게 명확한 UI 에러 상태와 재시도 기능 제공에 주의를 기울일 필요가 있습니다.
| const html = await Promise.resolve(viewFactory(context)); | ||
|
|
||
| target.innerHTML = html; | ||
| this.notify(context); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
5. Router 매칭 알고리즘 한계 및 발전 가능성
- 현재 경로 매칭 시 파라미터만 부분 처리하며, 복잡한 경로나 와일드카드 지원은 없습니다.
- 향후 라우터 확장이나 다이나믹 세그먼트 지원이 필요하면 외부 경로 매칭 라이브러리 사용 또는 매칭 기능 확장이 권장됩니다.
- 라우터 내 URL 조작 시
getBasePath로직에서 환경 변수 활용은 적절하나, 배포 환경이 다양해질 경우 이 부분을 더 유연하게 개선할 수 있습니다.
| const toastConfig = { | ||
| success: { | ||
| bgColor: "bg-green-600", | ||
| icon: `<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
7. Toast 컴포넌트 디자인과 동작 분리
- Toast 타입별 설정값 및 렌더링을 객체로 분리해 관리하는 점은 좋은 설계입니다.
- 다만 반복적으로 id
toast-close-btn를 여러 컴포넌트에 사용하는 것은 DOM 내 중복 id 문제가 생길 수 있어,
클래스명이나 data-attribute 사용이 더 적절합니다. - 자동 사라지는 기능과 수동 닫기 기능이 명확히 분리되어 잘 동작하는지 확인이 필요합니다.
| @@ -0,0 +1,155 @@ | |||
| const renderRelatedProduct = ({ productId, title, image, lprice }) => { | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
8. 파일명 오타 및 표기 일관성
- 파일명이
ProductDetali.js로 오타가 있습니다.ProductDetail.js가 올바른 명칭입니다. - 실제 파일명과 export된 컴포넌트를 일치시키는 것이 팀 협업 시 헷갈림 방지 및 자동 완성에 유리합니다.
| @@ -0,0 +1,32 @@ | |||
| // src/utils/eventBus.js | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
9. EventBus 구현 및 확장성
- 단순 이벤트 버스 구현이 잘 되어 있어 느슨한 결합 구조를 잘 지원하고 있습니다.
- 다만 잠재적인 메모리 누수를 막기 위해 이벤트 리스너를 적절히 제거하는 것이 매우 중요합니다.
- 만약 이벤트 체인이 복잡해지면 독립적인 Pub/Sub 라이브러리 도입도 고려할 수 있습니다.
| }); | ||
| } | ||
| } | ||
| import { createRouter } from "./router/Router.js"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
10. 진입점(main.js) 코드 구조 및 비동기 흐름
- 라우터 생성과 이벤트 등록, 상태 초기화가 잘 분리되어 있으며 순서도 명확합니다.
enableMocking()호출 시 import 동적 분리와 서비스워커 URL 명시가 좋은 모던 방식입니다.- 다만 라우터와 컴포넌트 간의 의존성을 더 느슨하게 분리하거나,
코드 스플리팅을 활용하면 초기 로딩 속도 개선이 가능합니다.
| @@ -0,0 +1,69 @@ | |||
| import { getCartState, subscribe } from "../store/appStore.js"; | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
11. Header 컴포넌트 및 상태 구독 방식
setupHeader에서 상태 변경 시 배지 업데이트 구독을 관리하는 점이 매우 좋습니다.- 다만, 현재 구독 해제(cleanup) 함수가 없어 만약 라우터 재생성이나 페이지 전환 시 이벤트 중복 등록 가능성이 있습니다.
- 향후에는 이벤트 및 상태 구독 관리를 위한 명시적 cleanup 패턴 적용을 권장합니다.
과제 체크포인트
배포 링크
https://1lmean.github.io/front_7th_chapter2-1/
기본과제
상품목록
상품 목록 로딩
상품 목록 조회
한 페이지에 보여질 상품 수 선택
상품 정렬 기능
무한 스크롤 페이지네이션
상품을 장바구니에 담기
상품 검색
카테고리 선택
카테고리 네비게이션
현재 상품 수 표시
장바구니
장바구니 모달
장바구니 수량 조절
장바구니 삭제
장바구니 선택 삭제
장바구니 전체 선택
장바구니 비우기
상품 상세
상품 클릭시 상세 페이지 이동
/product/{productId}형태로 변경된다상품 상세 페이지 기능
상품 상세 - 장바구니 담기
관련 상품 기능
상품 상세 페이지 내 네비게이션
사용자 피드백 시스템
토스트 메시지
심화과제
SPA 네비게이션 및 URL 관리
페이지 이동
상품 목록 - URL 쿼리 반영
상품 목록 - 새로고침 시 상태 유지
장바구니 - 새로고침 시 데이터 유지
상품 상세 - URL에 ID 반영
/product/{productId})상품 상세 - 새로고침시 유지
404 페이지
AI로 한 번 더 구현하기
과제 셀프회고
과제 의도와는 다르게, AI를 너무나 적극 활용한 것 같아 아쉽습니다. 주제가 주제이니만큼 심도 깊게 공부해가며 과제를 하고 싶었으나 결국에는 시간이 모자라 ... 완료하지 못하였습니다.
기술적 성장
커스텀 SPA 라우터 구현: React Router나 Vue Router 같은 라이브러리 없이 순수 JavaScript로 SPA 라우터를 직접 구현했습니다. History API와 URL 파싱, 경로 매칭 로직을 구현하면서 라우팅의 동작 원리를 깊이 이해할 수 있었습니다.
옵저버 패턴을 활용한 상태 관리: 전역 상태 관리를 위한 간단한 스토어를 구현했습니다. 옵저버 패턴을 사용하여 상태 변경 시 구독자들에게 자동으로 알림을 보내는 메커니즘을 구현했습니다. 이 과정에서 React의 상태 관리 개념과 유사한 패턴을 구현하려고 했는데, 잘 된건지는 모르겠습니다.
IntersectionObserver API: 무한 스크롤을 구현하면서 IntersectionObserver API를 처음 사용해봤습니다. 기존의 scroll 이벤트 리스너 대신 더 효율적인 방법으로 뷰포트 교차를 감지할 수 있다는 것을 배웠습니다.
URL 쿼리 파라미터와 상태 동기화: 검색어, 카테고리, 정렬 조건 등을 URL 쿼리 파라미터로 관리하면서, 새로고침 후에도 상태를 복원할 수 있도록 구현했습니다. 이 과정에서 URLSearchParams API를 활용하는 방법을 학습했습니다.
이벤트 기반 아키텍처: EventBus를 구현하여 컴포넌트 간 느슨한 결합을 유지했습니다. 이벤트 기반 통신을 통해 라우터, 상태 관리, UI 컴포넌트 간의 의존성을 줄일 수 있었습니다.
Enhancer 패턴: 라우터의 기능을 확장하기 위해 enhancer 패턴을 사용했습니다. 라우터에 새로운 기능을 추가할 때 기존 코드를 수정하지 않고도 확장할 수 있는 구조를 만들어보았습니다.
자랑하고 싶은 코드
appStore.js의 상태 관리 구조: 단순하면서도 확장 가능한 상태 관리 구조를 만들었습니다.
updateHomepage,updateCart함수를 통해 상태 업데이트를 일관되게 처리하고, 옵저버 패턴을 통해 자동으로 UI를 업데이트하도록 구현했습니다.URL 상태 동기화: 검색, 필터, 정렬 등의 상태를 URL 쿼리 파라미터로 관리하여 브라우저의 뒤로가기/앞으로가기와 새로고침 시에도 상태가 유지되도록 구현했습니다.
개선이 필요하다고 생각하는 코드
이벤트 리스너 정리:
homepageEvents.js나CartModal.js에서 이벤트 리스너를 등록할 때, cleanup 함수를 제대로 호출하지 않는 부분이 있습니다. 메모리 누수를 방지하기 위해 이벤트 리스너 정리 로직을 더 체계적으로 관리해야 합니다.에러 처리: API 호출 실패 시 에러 처리가 일관되지 않습니다. 에러 타입에 따라 다른 처리를 하거나, 전역 에러 핸들러를 추가하는 것이 좋을 것 같습니다.
타입 안정성: TypeScript를 사용하지 않아 타입 에러를 런타임에 발견하게 됩니다. 객체의 속성에 접근할 때 옵셔널 체이닝을 많이 사용하지만, 더 명확한 타입 정의가 필요합니다.
컴포넌트 구조: 일부 컴포넌트에서 HTML 문자열을 직접 생성하는 부분이 많은데, 이를 더 모듈화하고 재사용 가능한 구조로 개선할 수 있을 것 같습니다.
학습 효과 분석
가장 큰 배움이 있었던 부분: SPA 라우터를 직접 구현하면서 라우팅의 동작 원리를 깊이 이해할 수 있었습니다. 또한 URL과 상태를 동기화하는 방법을 학습하면서, 사용자 경험을 개선하는 방법을 배울 수 있었습니다.
추가 학습이 필요한 영역:
실무 적용 가능성: 이번 과제에서 구현한 패턴들은 실무에서도 적용 가능합니다. 특히 커스텀 라우터 구현 경험은 프레임워크 없이 순수 JavaScript로 웹 애플리케이션을 구축할 때 유용할 것입니다. 또한 옵저버 패턴을 활용한 상태 관리는 작은 규모의 프로젝트에서 상태 관리 라이브러리 없이도 충분히 사용할 수 있습니다.
과제 피드백
과제에서 모호하거나 애매했던 부분:
과제에서 좋았던 부분:
AI 활용 경험 공유하기
사용한 AI 도구: Cursor
프롬프트를 작성한 과정:
AI가 일을 더 잘 하게 만든 방법:
내가 작성한 코드와 비교하기:
리뷰 받고 싶은 내용
1. CartModal.js의 이벤트 리스너 관리
setupCartModal()함수에서 동적으로 생성되는 요소들에 대해 이벤트 리스너를 재바인딩하고 있습니다.removeEventListener를 호출한 후addEventListener를 호출하는 패턴을 사용했습니다.ensureRendered()함수 내에서 매번 기존 리스너를 제거하고 새로 등록합니다.isSetup플래그를 사용하여 한 번만 설정되도록 했는데, 이 패턴이 적절한지 확인하고 싶습니다.2. 이벤트 리스너 cleanup 로직
여러 컴포넌트에서 이벤트 리스너를 등록하지만, 명시적인 cleanup 함수를 반환하지 않는 경우가 있습니다.
setupCartModal,setupHeader등에서 라우터를 구독하지만, cleanup 함수를 반환하지 않습니다.3. 디렉토리 구조와 모듈 분리
현재 프로젝트 구조는 다음과 같습니다:
components,pages,events등으로 구분했습니다.events/폴더에 이벤트 핸들러를 모아둔 것이 적절한지, 아니면 각 컴포넌트나 페이지와 함께 두는 것이 나은지 조언해 주실 수 있을까요? 또한router/enhancers/같은 중첩 구조가 적절한지도 확인하고 싶습니다. 사실components/같은 경우에도 현업에서는 페이지 별로 디렉토리를 나눴었는데, 예를 들어components/HomePage/,components/DetailPage/,components/Cart/같은 식으로 페이지별로 그룹화하는 것이 맞는지 궁금합니다.4. 네이밍 컨벤션
같은 맥락으로 코드베이스 전반에 걸쳐 함수명, 변수명, 파일명을 일관되게 사용하려고 노력했지만, 실제로 실무에서 사용하는 네이밍 컨벤션과 비교했을 때 개선할 점이 있는지 확인하고 싶습니다. 또한 언급한 네이밍 컨벤션들(함수명 prefix, 파일명 케이스, 복수형 사용 등)이 실무에서 표준화된 규칙인지, 아니면 팀이나 프로젝트에 따라 달라지는 취향 차이인지 궁금합니다. 코드 리뷰 시 네이밍 컨벤션 불일치를 어떻게 지적하고 개선하는지도 궁금합니다.
setup*,handle*,update*같은 prefix를 사용하는 것이 일반적인지, 그리고 일관성 있게 사용하고 있는지 확인하고 싶습니다.ensureRendered()같은 함수명이 직관적인지, 아니면renderCartModal()같은 이름이 더 나은지 궁금합니다.homepageEvents.js처럼 복수형을 사용하는 것이 적절한지,homepageEvent.js나homepageEventHandler.js같은 이름이 더 나은지 조언해 주실 수 있을까요?CartModal.js처럼 PascalCase로 하는 것이 일반적인지, 아니면cartModal.js처럼 camelCase가 나은지도 궁금합니다.4팀 코드리뷰
제 모든 경력과 인생을 통틀어 코드리뷰 경험이 전무해서 팀원들 코드를 보며 어떤 리뷰를 해줄 수 있을지에 대해서도 조금 많이 막막한데요 ...
어쩌면 제일 기본적인 것들이 궁금합니다.
현재 구조가 api, components, pages, router, store처럼 기능 단위로 나뉘어 있는데, 라우터·스토어·이벤트 같은 공통 로직을 더 세분화하거나 레이어 기준으로 묶는 게 나을지 궁금해요.
예를 들어 router/enhancers처럼 서브 폴더를 둔 방식이 일관성 있는지, 혹은 더 단순화하는 게 좋을지 검토 부탁드립니다.
혼자 일할 때는 보편적인 네이밍 규칙을 알 수 없어서 지피티한테 변수 혹은 파일 네이밍을 자주 부탁하곤 했었는데, 팀 내에서 이런 것도 통일하여 사용하나요? 현재 제 코드에는 registe와 create, setup과 init, bind와 render 같은 비슷한 상황에서 사용되는 단어들이 혼재되어 있는데, 각 동사가 정확히 어떤 상황에서 어떤 단어로 쓰여야 하는지, 또는 하나로 통일하는지... 어떤 방식을 참조하여 채택하는지 궁금합니다.
이건 그냥 궁금한 건데요, 사전에 문서화된 컨벤션 파일을 두고 코드리뷰에서 지적하는지, 아니면 PR마다 케이스 바이 케이스로 논의하는지 경험을 듣고 싶어요.
새 규칙을 정할 때 ‘예시 코드’나 ‘린트 규칙 추가’ 중 무엇을 선호하는지도 알려주세요. (저는 ... 린트도 처음 써봐요 .........)