스프린트 회고를 진행하면서, 간단하게 코드를 훑어보는 일이 있었다.
나름 회사의 코드에 익숙해지고 스며들었다고 생각했는데
개성이 많은 코드의 예시로 소개가 되었다.
| 나의 코드 | CTO님과 다른 한 분의 코드 | |
|---|---|---|
| Tag | 시멘틱 태그 적용 | 작은 요소에만 태그 적용(p, img, button) |
| SCSS | BEM 방식 채택 | 인라인 방식, 공통 class의 경우에만 scss적용 |
| 반복문 | 한 속성에 의한 조건문 -> Switch | if - else if - else |
| 조건문 | 한 줄일 경우 중괄호 생략 | 한 줄이더라도 중괄호 생략하지 않음 |
시멘틱태그를 알게된 이후로 모든 태그들에 의미를 담고자
입사 전부터 각 구성 의미에 맞게 태그를 적용하려다 보니 습관이 되었다.
하지만 CTO님은 section 태그 대신 div를 그 외에는 p, img, button, h2등을 사용하셨고, 다른 한분은 대부분 div태그로 모든 것을 사용했다.
나 혼자만 시맨틱 태그를 적용하면 의미가 있을까하는 생각이 들었다.
CTO님과 다른 한 분은 대부분 인라인으로 style을 적용하고,
공통되는 스타일의 경우에만 scss파일을 만들어 적용했다.
나는 컴포넌트 파일에 인라인 css로 인해 기능이 명확하게 들어오지 않아,
BEM방식을 채택하여 모든 css를 scss파일로 적용했다.
이 방식에 문제가 됐었던 점은, 기존 같은 style로 적용되는 것들이 있었는데,
inline으로 css가 적용되어 있는 점과, 함부로 작성자의 코드를 건드리면 안될 것 같아
내가 작성한 부분들에만 컴포넌트화 시키거나 공통 class로 작성을 했다.
공통적으로 컴포넌트화나 공통 class로 중복코드를 제거할 점이 있다면
다른 사람 코드라도 함께 개선해나가야한다고 하셨다.
한 속성에 대해 복잡하지 않다면, If-else 문을 사용하고,
복잡한 경우에 대해서만 Switch를 사용하도록 예시를 들면서 설명해주셨다.
조건문에 대해서는 한 줄이더라도 중괄호를 생략하지 않도록 통일하기로 결정했다.
개성이 있는 코드에 대해 하나의 방식으로 통일시키지 않아도 되지만,
다른 사람의 코드를 보더라도 이해가 가도록 짜는 것이 중요하고,
중복 코드는 최대한 제거해나가며 빠르게 작업이 가능한 방식으로
작업하도록 얘기해주셨다.
며칠 전, 테오님의 협업을 잘하는 개발자를 다시 읽었었는데,
일을 하게 되면서 읽으니 또 다르게 와닿았다.
요즘들어 공을 들이고 클린 코드가 좋은 것이 아니라,
비즈니스의 변화에 맞춰 발빠르게 대처할 수 있는 코드 및 속도가 중요하다고 느끼고 있어,
개인적인 욕심으로 퀄리티 있는 코드와 유연하고 빠르게 작성하는 코드를
동시에 어떻게 잡을지 고민을 했었는데,
나만의 정답은 코드를 많이 짜보고, 경험을 많이 하는 것이라고 생각이 들었다.
지금은 비록 많이 모가 났더라도,
이렇게 계속 부딪히고 깎여나가며 최대한 경험을 쌓아가야겠다.
한 티켓에서 너무 오랜 시간이 걸린다.
그 이유를 생각해봤을 때, 한 티켓에서 너무 많은 일을 수행한다고 느꼈다.
왜냐하면 기타 오류사항이 생각나면 바로 해당 브랜치에서 작업해오고 있기 때문이다.
그러다보니 끝이 안보이는 작업이 되어,
하나의 PR에 무수한 커밋들이 쌓여 오래 걸리게 되었다.
컴포넌트에서 책임분리를 하던 것처럼 업무도 완벽히 분리하자.
내가 하고 있는 일을 나만 알고 있지말고, 티켓을 나눠 기록으로 남겨놓자.
위와 같이 한다면, 하나의 브랜치에서 작업했던 것들이 빠르게 머지되어,
충돌될 일도 많이 줄고, 팀원끼리의 싱크를 맞출 수 있을 것이다.
혹시 공통으로 쓰이는 곳들을 수정한다면 최대한 빠르게 PR을 올리자!!

6차 스프린트 기간: 24.09.20(금) ~ 24.10.04(금)
파트너 페이지에서 쓰이는 요소들에 같은 디자인, 비슷한 크기의 디자인 요소가 많았다.
하지만 어느 곳에 공통 class로 작업을 해야하나, 컴포넌트로 만들어야하나
감을 못 잡고 허우적거리면서 쓰고 지우고를 반복했다.
그러다 엑셀 버튼을 만들면서 조금씩 감이 잡혀나갔다.
공통 컴포넌트화 vs 공통 class 채택 방식
1. 우선 같은 디자인들에 대해 공통 class로 같은 디자인을 입힌다.
2. 크기나 상태에 의해 다른 것들에는 BEM-modifier를 통해 크기를 정의한다.
3. 비슷한 기능이 동작해야한다면, 이를 컴포넌트화 시킨다. (ex. 엑셀 다운 버튼)
디자인 시스템은 알고 있었지만, 프로덕트 시스템에 대해서는 잘 모르고 있었다.
그러다 feconf에서 바퀴 대신 로켓 만들기 세션을 들으며,
토스에서 어떻게 개발 효율성을 증대시키는지를 느끼고 배우게 되었다.
그러다 아래와 같이 비슷한 유형이 반복되는 디자인들을 발견했었다.
1. 필터판넬 관련
2. 목록관련
예전에는 어떤 기능의 컴포넌트든 간에 직접 구현하는 것을 좋아했는데,
회사에서는 빠른 개발 속도를 중요시해 antd 라이브러리를 사용했다.
이 점이 매우 아쉬웠지만, 지금와서 보니 엄청난 도움이 되었다.
antd에 있는 각 컴포넌트들이 어떤 입력 값을 요구하고,
버그가 있을 때 어떤 것이 문제인지 라이브러리를 뜯어가며 보니,
위의 디자인을 보고 data를 어떤 식으로 받아 프로덕트 시스템을 만들지 그려졌다.
곧바로 DataFilterPanel 컴포넌트등을 만들기 시작했고,
여러 페이지들에 대해 빠른 속도로 디자인을 적용할 수 있었다.
맛보기로 경험한 디자인 시스템과 프로덕트 시스템이였지만,
이러한 경험들이 쌓이다 보면, 퀄리티 높은 코드로 빠른 개발 속도라는 한 계단에
도달할 수 있을 것 같은 생각이 들었다.
더 많은 사람들의 코드와 경험을 들어보고 경험해야겠다고 느꼈다🙏
터득한 Point.
- 공통 컴포넌트화 시키는 나만의 과정
- 개발 효율성을 증대시킬 수 있는 한가지 경험
또 한가지 삽질을 했다.
괜한 오기로 대시보드 작업에서 미디어쿼리 없이 반응형 디자인을 적용하려다가
많은 시간을 잡아먹었다.
현재 나와 있는 모든 도구를 적절히 함께 사용하는 것이 능력이지,
한가지 도구로만 해결하려는 것은 고집에 불과하다는 사실을 알게되었다.
미디어쿼리로 적용하니 오랜 시간을 잡아먹었던 작업이 일사천리로 해결됐다.
도전은 좋지만 이상한 도전 하지 말자😅
우리 서비스에 입점해있는 파트너분들의 매출 통계를 볼 수 있도록 차트를 제공해야했다.
회사에 우리 어드민을 위한 차트는 ChartJS를 채택하고 있지만,
커스텀에 더 유연한 D3를 사용하고자 했다.
차트 작업은 처음이라 공부하는데 시간이 오래 걸릴것 같아,
작업에 들어가기전까지, 미리 집에서 D3에 대해 공부를 해갔다.
그리고 작업하기 직전에, CTO님께 어떻게 작업에 들어갈지 미리 말했다.
하지만 순서가 잘못됐음을 직감했다.
라이브러리 채택에 있어, 내가 하고 싶다고 마음대로 택했으면 안됐을 것 같았다.
역시나 반려하셨다.
이미 Chartjs를 사용하고 있기도 하고,
D3는 Chartjs에 비해 러닝커브가 있는데 나만 공부해서 끝낼게 아니였다.
왜냐면 그 코드는 나만 고칠 수 있게 되기 때문이다.
그 코드를 고치려면 D3를 습득하는데 시간을 써야하고, 결국 리소스가 사용된다는 것이다. (코드는 쓰는 순간 레거시....)
그리고 궁극적으로 우리가 구현하고자 하는 기능은 ChartJS로도 충분하다는 것이었다.
좋은 기능이 있다고 하여 그것을 무조건 사용하는 것이 아니라,
러닝커브와 오버스택을 고려하여 기술을 채택해야한다는 것을 깨달았다.
터득한 Point.
- 하나의 도구를 사용하는 것보다,
모든 도구를 적절히 활용하여 문제를 신속 정확하게 해결하자- 기술채택에 있어, 러닝커브와 오버스택을 고려하자. 좋은게 다가 아니다.
공지사항 ID 해당하는 공지사항과,
작성일 순서의 이전 공지사항 정보, 다음 공지사항 정보를 가져와야했다.
그래서 방법을 고심하다가 아래와 같은 방법을 생각했다.
- ID에 해당하는 공지사항을 가져온다.
- 공지사항의 생성일을 기준으로 필터하여 이전글을 가져온다.
- 공지사항의 생성일을 기준으로 필터하여 다음글을 가져온다.
이 방법을 구현하는데는 개별쿼리, 순차쿼리, 병렬쿼리를 사용하는 3가지 방법이 있었다.
개별쿼리로 구현하게 된다면, 네트워크 요청양이 많을 것이고,
순차쿼리로 구현하게 된다면, 개별쿼리와 마찬가지로 요청 시간이 필요에 비해 길것이고,
병렬쿼리로 구현하게 된다면, 메모리 사용량이 높아지는 단점이 있어,
우리의 상황에서는 어떤 것이 효율적일지 CTO님께 여쭤봤다.
"한 번의 요청으로 가져오면 되지 않나요? DB에 종속적이면 좋지 않아요.
현재 우리의 상황에 효율적인 방법은 index를 기준으로 한번에 찾는 방법일거에요"
그 말씀을 듣고나서, 내가 문제를 너무 단편적으로 바라봤다는 생각이 들었다.
그리고 DB에 종속적인 코드를 작성하지 말아야지라고 이전에 생각했음에도,
나도 모르게 또 쿼리로만 해결하려고만 했었다.
생각을 넓히고 그 중에서 우리의 상황에 맞는 방식을 생각하자!
공지사항의 url이 /notice/:noticeId로 되어 있어,
존재하지 않는 noticeId로 왔을 때 오류 페이지로 리다이렉트 시키고자했다.
때문에, 존재하지 않는 noticeId라면 서버에서 에러 문자코드를 내려주고,
클라이언트에서는 에러가 났을 때, 특정 에러 문자코드일 경우 리다이렉트 시키도록했다.
하지만 이것이 의도한대로 매끄럽게 작동하지 않았다.
tanstack-query에서 에러임에도 isError를 바로 감지하지 못했다.
그 이유는 오류가 났을 때, retry를 3번 다시 보내고 있어 그런 것임을 찾아냈다.
해당 문제에 대해 retry를 수정하는 방법도 있었지만,
하나의 문제를 해결하고자 다른 문제를 생성하는 듯한 방식이어서,
해당 api에 catch문을 통해 특정 에러코드일 경우 리다이렉트 시키는 방식으로 바꿨다.
터득한 Point.
- 개별쿼리, 순차쿼리, 병렬쿼리의 존재 유무와 사용처
- DB에 종속적이지 않은 코드 작성
- 하나의 문제를 해결하고자, 다른 문제를 만들지 말자!
어드민에서 바로 환불을 했을 경우에는 환불한 상품의 재고가 잘 올라갔지만,
유저-파트너-어드민의 환불 flow를 통해 환불한 상품의 경우 재고가 올라가지 않았다.
해당 문제를 해결하기 위해 아래의 방식을 통해 문제를 해결해나갔다.
- API - Admin의 유저 환불 PR 이전 이후의 코드를 비교했으나, 이상 없음 → Admin에서 환불 요청 상품에 이상이 있을 것으로 추측
- 클라이언트 - Admin 코드에서 유저가 환불했을 때의 로직들을 확인
- useEffect와 useMemo의 dependency가
antd의 Modal 컴포넌트를 Mount하는 시기에 의해 꼬이게 됨- 그래서 dependency에 open 변수 추가 -> 근데 바뀌지 않음 -> 공식문서 확인 -> 내가 알고 있는 지식이 맞는거 같은데 작동방식이 다르게 동작하나? -> 깃허브 useEffect 코드 확인
- 알고보니 추가한 dependency를 다른 useEffect에 추가했었음 → 정상 동작 확인
약간의 삽질이 있었지만, 때로는 100줄의 코드를 작성하는 것보다,
오류의 원인을 찾고 1줄의 코드를 수정하는 것이 오래걸릴때도 있다는 것을 깨달았다.
터득한 Point.
- 라이브러리를 사용할 때, 작동 방식을 알고 사용하면 도움이 된다.
- 100줄의 코드작성 보다, 1줄의 코드작성이 오래 걸릴 수 있다.