2023년이 벌써 이렇게 지나갔구나. 올 하반기에도 많은 일들이 있었다. 이번 글은 회사 개발 일 뿐만 아니라 다른 일들도 회고를 해볼까 한다.
개발
개발이라는 직업은 나에게 애증의 존재 같다. 좋기도 하고, 싫기도 한데, 다시 태어나면 또 개발자를 할 것 같다. 물론 다른 직업을 경험해보지 못해서 익숙한 것을 하고 싶은 마음도 있을 것이다. 그렇지만 하나의 주제를 탐구하고, 공부하고, 논리를 쌓는 행위가 나에게 잘 맞는 것 같다.
올 하반기 개발했던 것을 정리 해보겠다.
기디개 프로덕트팀 창설
하반기부터 기획팀, 디자인팀, 개발팀이 모인 프로덕트팀이 만들어졌다. 가장 큰 변화는 일주일에 한 번씩 기디개가 모여 정기 미팅을 가지고, 스프린트가 끝날 때 회고 미팅도 다같이 하게 된 점이다. 원래는 개발팀 내부에서만 했었는데, 기디개가 한꺼번에 모여서 하니 좀 더 회사의 방향성을 잘 이해할 수 있었고, 공통의 목표를 향해 기디개 팀원분들이 함께 나아갈 수 있어서 좋았다.
애자일 프로세스의 도입
기디개 팀이 생기면서 기존의 워터폴(Waterfall) 방식으로 진행했던 프로젝트를 애자일(Agile) 프로세스로 진행하게 되었다.
가장 큰 차이점은 워터폴은 기획이 정해진 상태로 개발자가 리뷰를 하면서 수정하는 방식이었다.
애자일은 애초에 완벽한 기획서는 없다는 전제하에 "공동의 이해"를 만들기 위해 기획자, 개발자, 디자이너가 함께 MVP(Minimum Viable Product) 를 정한다. 최소한의 기획, 개발, 디자인으로 최대한 빠르게, 최대한의 성과를 만들기 위해 노력한다. 이후 성과가 좋다면 2차, 3차까지 개발을 진행하고 성과가 좋지않다면 과감히 포기한다.
애자일 프로세스를 도입하기 위해 모든 팀원들이 "사용자 스토리 맵 만들기" 라는 책을 읽었다.
책을 읽고 썼던 글은 아래에 있다.
릴레이 특가 페이지를 개발할 때 애자일 프로세스로 개발했었다.
먼저 유입부터 구매하기 까지의 과정에 유저가 취하는 행동을 포스트잇으로 모두 적어본다.
적은 항목들을 보며 이야기를 나누고, 중요도도 나눠본다.
이후 MVP 로 꼭 필요한 것들을 추려내고, 2차, 3차 배포로 할만한 것들을 정한다.
이렇게 우선 순위를 정해 MVP를 먼저 개발했고
성과가 좋아서 2차, 3차도 추가 개발했다.
워터폴 대비 애자일 프로세스의 장단점은 어땠냐면,
장점
- 공통된 이해를 만들기 때문에 기획서를 작성하지 않아도 된다. 완벽한 기획서를 써야한다는 부담감이 없다.
- 기획 단계에 아이디어를 많이 제시할 수 있다. → 아이디어를 제시하는 과정이 재미있었다.
이 부분은 사람의 성향에 따라 좋을 수도, 아닐 수도 있다. 같은 동료 개발자 분은 오히려 힘들어 하셨다. - 기획, 디자인 의도를 기존 방식보다 더 잘 이해할 수 있다.
- 기디개가 많은 소통을 나누기 때문에 더 좋은 방향으로 프로젝트가 진행된다.
단점
- 2.5일 동안 회의가 진행되었는데 너무 힘들었다. 여기 회사에서 일했던 것 중에 가장 힘들 정도.
- 애자일 프로세스, 빠른 배포를 위해 MVP를 선정했지만 개발 양과 기간은 평소와 비슷했다. 큰 차이는 없었다.
이후 회사에서는 프로젝트의 특징에 따라 워터폴로 하기도 하고, 애자일 프로세스로 하기도 했었다.
팀적으로 좋은 시도였고, 개인적으로도 개발 프로세스 적인 측면에서 많이 배울 수 있었다.
스토리북 개발
우리 회사에도 스토리북을 꼭 도입하고 싶었다.
스토리북이란 UI 컴포넌트를 웹에서 볼 수 있게 하여 타팀과의 소통을 편하게 하고, 개발팀 내부에서도 컴포넌트 관리를 용이하게 할 수 있는 프레임워크이다.
스토리북의 장점
- 기존에 개발된 컴포넌트를 개발자가 쉽게 확인할 수 있다.
예를 들어, Modal 을 개발해야 한다고 했을 때 이 UI가 이미 개발되었는 지 확인하기가 어려울 수 있다. (일일이 검색해서 확인해야한다. 어떤 개발자가 컴포넌트명 이름을 특이하게 했을 경우 검색이 힘들 수 있다. 기존 서비스에서 쓰였던 UI 이더라도 자기 회사의 모든 서비스를 빠삭하게 아는 게 아니라면 개발했던 건지 알기가 힘들 수 있다.)
이럴 경우, 스토리북의 Modal 이 정리되어 있다면 금방 찾아서 이미 개발된 컴포넌트를 사용해 개발 시간을 단축할 수 있다. (찾는 시간 단축, 기존에 있었던 컴포넌트라서 새로 개발하지 않아도 되니 개발 시간 단축) - 웹으로 확인가능하기 때문에 실제로 보여지는 컴포넌트를 쉽게 확인할 수 있다.
예를 들어, Button 일 경우 Figma 로 확인했을 때와 달리 스토리북이 배포된 Chromatic 에서 버튼의 hover, disabled, css 등을 바로 확인할 수 있다. - 개발팀과 디자인팀 간의 소통을 원활히 할 수 있다.
예를 들어, 현재 개발된 Button 종류들을 스토리북으로 확인할 수 있다면 어디까지 개발되었고, 어떤 종류의 Button 은 개발되지 않았는 지 디자이너가 바로 확인할 수 있다. - 컴포넌트를 먼저 개발, 코드리뷰 한 후에 사용할 수 있다.
원래는 컴포넌트를 사용할 곳에다 컴포넌트를 구현해서 개발해야 하는데 (뭐 이렇게 해도 큰 상관은 없지만)
컴포넌트를 스토리로 먼저 만들어서 PR 올려 코드리뷰 받고, chromatic에 배포한 스토리를 개발자, 디자이너가 확인하게 할 수 있다.
이렇게 검증이 끝난 후에 컴포넌트를 사용해 개발할 수 있다. - 부수적인 효과로 디자인팀에서 UI 들을 정리하실 수 있다.
스토리북을 하게 되면서 디자인팀에서 만든 UI, 에셋, 아이콘, Typography, Button 등을 체계적으로 정리하는 계기가 되었다.
한줄 요약 해보자면, 소통을 편하게 하고, 컴포넌트의 체계를 더 단단히 잡을 수 있다.
설치 방법
스토리북을 기존 프로젝트에 도입하는 건 어렵진 않았다. 스토리북 공식 문서에 있는 대로 설치하면 되었다.
한 번은 브랜치에 스토리북 작업하다가, 다른 프로젝트의 개발이 급해 하고 왔더니 스토리북이 실행이 안되는 이슈가 있었다.
해결 방법을 찾기가 어려웠는데, 스토리북을 최신 버전으로 바꾸니 해결되었다.
CI/CD
CI/CD 적용하여 github actions 에서 PR의 target branch 가 develop 일 경우 chromatic 에 배포하도록 하였고, 해당 링크가 PR에 뜨게 하였다.
코드 리뷰를 받으면서 동시에 스토리도 리뷰를 받은 후에 merge 하기 위한 의도로 PR을 올렸을 때 chromatic에 배포하였다.
기존의 Legacy 컴포넌트들 스토리로 개발
처음에 우리의 문제는 어떤 컴포닌트가 개발되어있는지, 어떤 디자인으로 구현되어있는지 개발팀과 디자인팀이 서로 잘 모르고 있었다. 그래서 가장 기본적인 Button과 color의 기존 UI를 종류별로 정리했다. 그렇게 디자인팀에 보여드리니 '우리가 이런 UI도 있었군요?' '이 버튼은 디자인이 왜 이렇죠..?' 하는게 꽤 있었다.
Color, Layout 정리
color 와 layout 이 그때그때 필요할 때마다 정의해서 사용했던 것이 많있다 그래서 변수명의 규칙이 통일되어 있지 않았다. color와 layout 를 디자이너 분이 Figma 에 정리해주시고, 해당 내용을 개발 프로젝트에도 적용하였다.
layout의 경우 스토리북에도 설정할 수 있다. 위의 아이콘을 누르면 우리 웹에서 사용하는 레이아웃 규격을 적용해서 컴포넌트의 디자인을 스토리북에서 바로 확인할 수 있다.
Typography 컴포넌트 개발
기존에는 글자 관련 CSS를 적용할 때 일일이 하나씩 Figma 에 있는 값으로 넣어줬다. 그런데 디자인 팀에서는 이미 Typography 를 종류별로 사용하고 있었다. (ex: headline, title 등) 그래서 Typography 컴포넌트를 개발해 글자 CSS를 일일이 넣어주지 않아도 되어 개발 시간을 단축하게 되었다.
회사 코드라서 여기에 공개할 순 없겠지만 mui의 Typography 컴포넌트를 참고해 비슷하게 만들었다.
한계
개발 일정이 급하다보면 개발한 컴포넌트를 스토리로 만들지 못하는 경우가 생길 수 있다. 이 땐 일단 개발을 끝내고 배포한 이후에라도 스토리로 만들고 있다.
결론
공용 컴포넌트를 만든다면 다른 개발자를 위해 스토리를 만드는 것은 필수이지 않나 싶다. 아직 스토리북의 다양한 기능을 모두 활용하지 못하고 있는데, 여유가 된다면 좋은 기능들을 사용해보고 싶다.
테스트 코드 도입
우리 회사는 테스트 코드가 없었다. 회사의 매출에 관련된 일이 우선 순위가 높다보니 테스트 코드는 항상 뒷전이었다. 그러다가 여유가 생겨서 테스트 코드를 도입 해보게 되었다.
첫 설정부터 굉장히 힘들었다. 온갖 에러가 뿜어져 나왔다. 그 중 가장 힘들게 했던 에러가 있었는데
jest 가 외부 라이브러리를 import 못하는 에러였다. (정확한 에러명은 기억이 안남)
import한 컴포넌트 안에 ECMAScript 문법을 따르는 모듈이 있는 경우 테스트 에러가 발생하는 것이었다.
구글링 해보니 이를 해결하기 위해서는
"jest": {
"transformIgnorePatterns": [
"node_modules\/(?!axios)"
]
}
이런 식으로 .babelrc 파일에 추가해주면 된다고 한다.
그런데 이렇게 해봤는데 아무리 해봐도 안되고
구글링해서 나오는 방법들 모두 해결이 불가능했다.
그렇게 4일을 삽질한 결과 해결한 방법은 굉장히 허무했다.
.babelrc 가 아니라 babel.config.js 에 위의 내용을 추가하면 되는 것이었다. 세상에!
transformIgnorePatterns 이 제대로 동작하지 않는 것 같아서 transformIgnorePatterns doesn't work 라고 검색해서 찾은 방법이었다.
1차적으로 에러 로그를 검색해보고, 해결되지 않으면 추측이 되는 원인으로 검색해보면 해결할 수 있다는 것을 알게되었다.
jest 도입 못하나 걱정했는데 힘들게 해결했고 결국 테스트 코드 도입할 수 있었다.
관련된 글은 아래에 썼었다.
(사실 저번에 글 쓴 거 깜빡하고 여기에 다시 적었..)
도입한 테스트들
우리 회사 커머스 도메인에서 가장 중요한 구독과 결제 쪽에 가장 먼저 테스트 코드를 만들었다.
특히 실제로 구독/결제 가 되는지 확인하면 좋을 것 같아서 cypress로 e2e 테스트까지 추가했다.
github actions로 PR하면 테스트가 돌아가고 결과가 나오도록 하였다.
테스트 코드를 통해 얻을 수 있는 효과
솔직히 처음엔 테스트 코드 왜 만드나 싶었다.
1. 운영 환경에서 발생하는 버그를 예방하기가 힘들다.
2. api 통신을 하지 않고, api 통신이 성공적으로 된 가짜 결과(mock)를 이용하기 때문에 api 통신 테스트를 할 수 없다.
왜 jest 테스트 코드 만드나 싶었다.
테스트 코드 만들어야 한다고는 하는데 왜 만들어야 하는 지 알려주는 곳은 없었다.
그래서 직접 테스트 코드를 만들어봤는데, 테스크 코드의 장점을 알 수 있었다.
(역시 직접 해봐야 알 수 있다는 교훈을 얻었다.)
jest 테스트 코드를 만들어두면, 코드가 개발 중에 바뀌었을 때 기존 기능에 문제가 생겼는 지 확인할 수 있다.
예를 들어 A 프로젝트의 테스트 코드를 만들어 둔 상황이다.
기존 A 프로젝트의 기능을 일부는 그대로 사용하고, 일부는 추가 보완하는 A' 라는 프로젝트를 진행한다.
이 경우 A 프로젝트에서 만든 테스트 코드가 있다면
A' 를 개발했을 때 A 의 테스트 코드 기능들은 문제가 없음을 보장할 수 있다.
현실적으로 모든 기능 테스트가 힘든 스타트업이라면, QA 전문 팀이 없다면, 무조건 도입해야 하지 않을까.
현실
문제는 스타트업이라면 기능을 최대한 빠르게 개발하는 것이 우선이다. 회사가 먹고 살아야 하니.
그러다보니 테스트 코드는 항상 우선 순위가 낮아서 작성하지 못하는 경우가 많았다. (TDD는 주륵..)
여기보다 더 큰 대기업은 상황이 다를까? 궁금하다.
해결하기 힘들었던 오픈 소스의 버그를 해결
어느 금요일, QA를 마치고 금요일 배포는 지양하니 다음 주 월요일에 배포를 했다. 그런데 갑자기 form 관련하여 submit이 안되는 크리티컬한 버그가 운영 환경에서 제보되었다. 급하게 이전 코드로 돌려서 배포했다.
근데 왜 QA 에서 문제가 없었는데, 운영 환경에서 버그가 발생했는지 의문이었고
게다가 내 로컬에서 실행했을 때는 버그가 재현이 되지 않았다.
이런 황당한, 힘든 버그가 있었다.
1. 원인은 오픈 소스 버전 차이였다.
QA 때 문제가 없었고
해당 코드에서 변경이 없었기 때문에
회사 코드가 아닌 외부 라이브러리가 원인이라고 추정했다.
package.json 에서 버전을 바꿔가며 테스트 해보니
최신 minor 버전에서 문제가 발생했고, 이전 버전은 괜찮았다.
QA가 끝난 금요일은 이전 버전이었고, 주말 사이에 minor 업데이트가 일어나, 월요일에 배포한 이후부터 문제가 발생했던 것이었다.
minor 업데이트의 경우는 이전 버전에서 잘 돌아가는 코드를 그대로 사용해도 문제가 없어야 한다.
그런데 우리 코드는 오픈 소스에서 의도치 않았던 코드로 돌아가고 있었다.
오픈 소스에서 이 버그를 해결했고
우리의 코드가 오픈 소스 코드가 원하지 않는 형식으로 코드를 쓰는 바람에
minor 업데이트 이후 문제가 발생했다.
(깃헙 이슈에 들어가보니 같은 버전에 우리와 같은 문제를 만난 사람의 글도 있더라)
2. 내 로컬에서 실행했을 때와 운영 도메인에서 실행했을 때의 결과가 달랐던 이유는, 빌드 유무의 차이였다.
로컬에서 npm run dev 할 때는 문제가 발생하지 않았고
빌드 후 실행하니 문제가 발생했다.
즉 로컬에서 실행할 땐 최신 minor 버전이 아니라 이전 버전으로 실행되고
빌드 후 실행하면 최신 minor 버전으로 실행되는 것으로 추측할 수 있었다.
(왜 이런 이상한 결과가..?)
3. 이걸 방지하기 위해서는 결국엔 테스트 코드가 필요
이걸 해결하기 위해서는 jest 나 cypress(e2e) 테스트가 필요하다.
그런데 github actions 에서 PR 올리면 테스트 해주는 걸로 하면 안되고
merge 누르고 배포하기 직전에 테스트가 필요하다.
이게 없다면 오픈소스에 의해 언제 사고가 터질 지 모르는 문제가 있을 수 밖에... (제발)
렌더링 개선
Nextjs 를 도입하는 이유 중에 하나가 서버에서 생성한 페이지를 유저에게 미리 보여줘 UX를 향상시키는 것이다. 그런데 우리 회사에서 React에서 Nextjs 를 도입할 때 이 부분은 하지 못했다.
Nextjs 를 도입했던 이유가 마케팅 팀에서 meta tag를 심어달라는 것이었다. React만 쓰는 프로젝트에 Nextjs 추가하는 것은 꽤나 대작업이었고 (관련 글 링크: https://bsnn.tistory.com/131) 바쁜 개발 일정 중에 서버에서 생성한 페이지가 이상하게 보이는 것은 후순위로 미루게 되었다.
위의 gif 파일을 보면 새로고침 시 "탁주, 약청주... " 영역이 상단에 붙어있다가 아래로 내려온다.
서버에서 생성한 페이지가 먼저 보여지고, 클라이언트 렌더링 때 위에 영역이 렌더링 되기 때문에
이렇게 UI가 깜빡이는 것 같은 불편함이 있었다.
처음에는 서버에서 생성한 페이지가 잘못 보이는 이유가 외부 라이브러리 때문인 줄 알았다. 근데 해당 라이브러리를 제거하는 게 꽤 큰 작업이라 할 엄두를 못냈다. 그런데 이번에 여유가 생겨 살펴보니 외부 라이브러리 문제가 아니었다. 페이지가 pre render 될 때 어떤 useState 초기값이 false 였는데, 이 때문에 레이아웃 컴포넌트가 렌더링 되지 않는 것이 원인이었다.
const [isTest, setIsTest] = useState(typeof window === 'undefined');
...
return (
<>{isTest && <LayoutComponent />}</>
);
그래서 위와 같은 방식으로 해결했다.
배너와 같은 곳은 스켈레톤 UI를 적용했다. (on demand ISR 로 하면 미리 생성한 페이지에 배너를 보여줄 수도 있으나 우선 순위가 높지 않아 패스했다.)
그래서 해결한 최종 모습은 위와 같다.
그 외 프로젝트들
<개발 관련>
- 회사 어드민(관리도구)에 유저마다 권한을 설정할 수 있는 기능을 구현했다.
- tailwind css 도입 시도해보았으나, 적용시 기존에 사용하던 css 프레임워크와 충돌해 디자인이 크게 달라졌다. 이 부분은 큰 대작업이 될 것 같아 tailwind css 는 나중에 도입하기로 하였다.
- 특정 URL에 ?utm_source=xxxx 가 붙으면 해당 페이지에 있는 기능(ex: 필터)이 제대로 동작하지 않는 이슈가 있었다. 처음 기획 때 이 페이지에 utm_source 가 붙을 수 있다는 게 없어서 테스트를 못해봤기 때문이었다. 기획에 없더라도 URL 뒤에 ?utm_source 와 같은 query string이 붙는 경우도 항상 대비해야한다는 것을 알게되었다.
- react-hooks/exhausitve-deps rule 이 eslint 에 없는 걸 발견하여 추가하였다. 처음에 react만 쓰다가 nextjs 를 추가하는 과정에서 "next/core-web-vitals" 규칙을 추가하지 않은게 원인이었다. 그래서 지금까지 useEffect 가 의도치 않은 리렌더링이 되고 있었다. 근데 기존 코드들 고치는 게 만만치 않더라. 워낙에 많기도 하고, 추가해라는 거 다 추가했더니 버그가 발생하기도 했다. 새로 개발하는 코드는 문제 없게 하고, 기존 코드는 시간날 때 개선하기로 했다. 나중에 next/core-web-vitals 도 추가해야 하고.
- 상품이 infinite scroll 로 보여지는 곳을 스크롤 내려서 보다가 상품 상세 페이지로 이동. 뒤로가기 했을 때 이전에 보던 곳으로 스크롤 이동하는게 setTimeout 으로 이동하게 되어 있었다. 상품들 불러오는 api 응답이 늦을 경우 문제가 생길 수 있고, 기다리다가 내려가는게 체감되어 UX가 별로였다. async await 으로 바꿔 api 응답이 늦을 경우를 대비하고 훨씬 더 빠른 속도로 스크롤이 내려가 UX를 더 좋게 하였다. 누가 시켜서 한 일이 아닌 스스로 찾아서 개선했다.
- 술담화 안드로이드 앱이 출시되었다! 내가 앱을 개발한 건 아니고, 앱에 필요한 웹 기능들을 개발한 거였지만. 아이폰 앱까지 출시하게 되서 회사가 더 잘되면 좋겠다.
<소통 관련>
- 엑셀로 정리된 기획서에 필요한 내용이 없었던 일이 있었다. '이러이러한 게 필요하고, 이런 형식으로 작성해주시면 좋겠다.' 고 기획자분께 문의드렸다. 하나하나 물어보는 것보다 훨씬 효율적이었다. 내가 필요로 한 걸 기획자 분과 잘 소통하여 개발하는 것이 중요하구나 싶었다.
- 나는 기획적인 아이디어가 생기면 서슴지 않고 말하는 타입이었다. 그래서 기획자 분에게 이러이러한 거 기획하면 어떨까 물어봤다. 또한 기획에 대해서 질문도 많이 했었다. 이런 것들이 기획자분에게 부담이었다는 것을 나중에 알게된 일이 있었다. 부담을 드렸다는 게 죄송했고, 어느정도 선까지 물어봐야하는 걸까 많은 고민을 하였다.
기획의 큰 줄기에 대해서 반기를 드는, 이것보단 이게 더 좋지 않나요 라는 뉘앙스로 들리는 질문은 하지 않기로 했다. 그 기획이 나오게 된 배경에는 기획자 분이 많은 조사와 연구 끝에 나온 것이다. 그래서 기획에 대해 부정적으로 질문하지 않고, 왜 그렇게 했는 지 이유를 물어보기로 했다. 만약에 궁금증이 남아있다면 최대한 예의바르게 물어봐야 한다.
사이드 프로젝트
여름에 여행을 갔는데 강원랜드가 있길래 카지노에 다녀와봤다. 카드 카운팅을 핸드폰으로 할 수 있으면 좋겠고, 난이도가 쉬울 것 같아서 처음으로 혼자 사이드 프로젝트를 만들었다. 관련된 내용은 아래 글에 정리했다.
2024년에는 어떤 또 재밌는 일들이 있을까!
글이 길어져서 음악, 글쓰기, 여행 등에 대한 회고는 다음 글로 써보겠습니다~!
'dev' 카테고리의 다른 글
덕업일치 개발자로 EO planet 에 소개 되었어요 (1) | 2024.02.12 |
---|---|
개발자 신입 취직을 위한 상담 컨설팅 무료로 해드립니다 (0) | 2024.01.13 |
useEffect로 Race Condtions 해결하는 방법 (2) | 2023.11.22 |
useCallback 심도있게 살펴보기 (0) | 2023.11.09 |
useDeferredValue 는 언제, 어떻게 쓰는걸까? (0) | 2023.11.05 |
댓글