2명의 프론트엔드, 2명의 백엔드로 구성된 팀 Surfers를 팀장이자 프론트엔드 개발자로써 이끌며 2주간 진행했던 코드스테이츠 프로젝트가 우여곡절 끝에 끝났다. 결과물을 완벽하게 구현하지는 못했지만, 애초에 기획했던 모든 것을 2주 안에 완성할 수 있다고는 크게 기대하지 않았다. Bare Minimum으로 잡았던 목표들은 모두 구현에 성공했고, Advanced 목표로 잡았던 몇몇 기능들까지 구현할 수 있었기에 2주동안 진행한 프로젝트 치고는 굉장히 성공한 프로젝트라고 생각한다.
우리의 퍼스트 프로젝트 주제는 소설 릴레이 플랫폼 Surf였다. 좋은 소설 아이디어가 있는데 소설을 연재하기에 시간이 없는 사람은 소설 전체를 본인이 작성하는 대신 시놉시스와 1화만 업로드하고, 소설 쓰기에 참여해보고 싶은 사용자들이 한 명씩 릴레이에 참여해 한 화씩 완성해나가며 최종으로 완성된 하나의 소설을 만들어낼 수 있는 기회를 제공하는 플랫폼이다.
아래는 Surf의 메인 페이지와 소설 참여 페이지를 보여준다. 인피니티 스크롤 기능도 지원하며, 소설 참여의 경우 한 소설을 다수의 사람이 동시에 참여하지 못하도록 코드상으로 막아놓았다.
2주간의 프로젝트를 어떤 주제로 진행할지는 굉장히 빨리 정해졌다. 처음 팀 미팅을 할 때 아이디어를 선정하기 위해 생각나는 아무 아이디어나 말해보는 브레인스토밍 시간을 가졌다. 나를 포함한 모든 팀원분들이 많은 아이디어를 제시해 주셨는데, 그 중 나와 함께 프론트엔드 개발을 진행한 강한결 팀원께서 이미 이전부터 아이디어를 정리해두신 '소설 릴레이 플랫폼'의 호응이 가장 좋았기에 일사천리로 주제가 정해졌다.
프로젝트에 주어진 시간이 단 2주밖에 안됬기 때문에 기획 부분을 빠르게 완료해야 했다. 팀 룰을 후딱 정하고, 어떤 기능들을 구현할지 정리했다. 그리고 프로젝트에 들어갈 기능들이 어떤 플로우로 구동되는지를 플로우 차트로 정리했다. 내가 만들었지만 굉장히 조잡하다...
와이어프레임과 프로토타입 설계를 끝마치고 전반적인 UI 디자인을 해야 했는데, 내가 원래 디자인을 하던 사람이 아닐 뿐더러 프로젝트 진행 환경이 윈도우와 우분투인지라 UI 디자인을 어떤 툴로 진행해야할지 고민이었다. 프로젝트 기간이 짧아 새로운 디자인 툴을 익히기에도 부담스러웠다.
다행히도 팀원분들 중 김도움님과 강한결님이 'Sketch'라는 툴을 사용해 본 경험이 있으셔서 전반적인 UI 디자인을 진행해주셨고 이를 제플린으로 공유해주셔서, 디자인을 생각보다 빠르게 완성할 수 있었다. 처음부터 반응형 웹을 목표로 했기 때문에, 디자인도 다음과 같이 PC, 타블렛, 모바일 세 가지 화면을 기준으로 따로 진행했다.
내가 이번 프로젝트에서 프론트엔드로 구현한 모든 것을 서술하면 글이 너무 길어지므로, 대표적인 것들 몇 개만 소개하고자 한다.
먼저, 유저 관련 로직을 Redux로 구현했다. 사실 상태를 관리해야 하는 모든 부분에 Redux를 사용했으면 가장 좋았겠지만, 이 프로젝트를 시작할 때만 하더라도 Redux를 이론적으로는 알았으나 실제 프로젝트에 적용해 본 경험은 없었다. 유저 인증도 쿠키-세션 기반으로 간단하게 처리했으므로, 유저 상태 관리에만 간단하게 Redux를 도입해보고 파이널 프로젝트에서 본격적으로 Redux를 사용해보고자 결정했다.
유저 로그인이나 로그아웃, 그리고 유저 정보 조회는 필연적으로 비동기 함수 호출이 필요하기 때문에, 비동기 상태 관리를 위해 Redux Thunk 미들웨어를 사용했다. 그리고 리덕스를 사용할 때에는 기능 별로 파일을 쉽게 관리하기 위해 액션과 리듀서를 하나의 파일에서 정의하는 ducks 패턴을 사용했다.
메인 페이지 이외에도 많은 부분들을 구현했지만, 메인 페이지에서 특별히 언급하고 싶은 부분들이 있어서 메인 페이지를 기준으로 설명하겠다. 이번 프로젝트에서 나는 '유저 인터렉션 컴포넌트'와 '반응형 웹 페이지'를 구현하는데 집중했다.
유저 인터렉션 컴포넌트란 사용자가 아무 동작을 하지 않아도 보이는 정적인 컴포넌트가 아니라, 실제로 클릭 등의 상호작용을 통해 사용자가 동적으로 제어할 수 있는 컴포넌트를 의미한다. 대표적으로 아래와 같이 메인 페이지에서 버튼을 눌러 카테고리를 선택하거나 필터링 기준을 선택할 수 있는 컴포넌트들을 구현하는데 집중했다.
컴포넌트를 유저 친화적으로 만들기 위해 많이 고민을 했는데, 대표적으로 버튼을 눌러 드롭다운을 열었을 때 굳이 버튼을 다시 한번 눌러서 끄는 것이 아니라 드롭다운 외부 공간을 클릭하면 자동으로 닫히도록 구현하는 등 많은 노력을 했다. 이는 로그인 / 회원가입 모달 창에서도 그대로 적용했다.
처음에 디자인 한 그대로 웹사이트를 구현하자니 너무 허전해서, 말 그래도 '살아 움직이는' 디자인을 웹 사이트에 적용한다면 사이트에 보다 동적인 느낌을 줄 수 있을 것이라 생각했다. 따라서 로그인 및 회원가입 모달 페이지에 움직이는 파도 효과를 넣어보기로 결정했다.
파도 효과를 내는 방법에는 여러 가지가 있지만, 주로 사용하는 파도 모양의 PNG 이미지를 활용해 파도를 구현하는 것보다 직접 수학적 공식을 사용해 Canvas 위에 점을 찍고 이를 연결시켜 파도를 구현하는 방법을 사용했다. 현재 모달창에 적용되어 있는 파도를 구현하기 위해 많은 시행착오가 있었고, 시간을 투자한 끝에 매우 적합한 파도를 구현할 수 있었다. 그리고 이 파도 효과가 데이터가 입력될 Form 영역을 침범하지 않도록 구현했다.
프로젝트를 처음에 기획했을 때부터 반응형 웹사이트 디자인을 생각하고 있었으며 이를 실천으로 옮겼다.
가장 대표적으로 반응형을 볼 수 있는 곳도 로그인 및 회원가입 모달창이다. PC 화면에서는 화면 가운데에 모달창이 보이도록 구현했고, 타블렛 크기의 화면에서는 오른쪽의 햄버거 메뉴로 열고 닫을 수 있도록 구현했다. 스마트폰 크기의 화면에서는 모달창을 전체 화면으로 로그인 및 회원가입 메뉴를 볼 수 있도록 구현하여, 스마트폰 환경에서도 유저 정보 입력이 원활하도록 구현했다.
2주 간 4명이서 하나의 프로젝트를 협업하며 진행하면서 실수했던 점도 많았고, 나 스스로가 팀장으로써 프로젝트를 이끌면서 미숙했던 부분들도 수두룩했다. 이러한 문제점들을 그냥 넘겨버리면 내일의 나도 오늘의 나와 똑같이 부족한 채로 남아있을 것이 분명하기에, 블로그에 공유함으로써 계속해서 되새길 수 있으면 한다.
본 프로젝트를 진행하면서 가장 큰 실책이자 가장 뼈져리게 느꼈던 것이 바로 '팀원 간 업무 내용 공유의 중요성'이었다. 우리 팀이 소통을 안했다는 의미가 아니다. 사실, 프로젝트를 진행하면서 팀 내에서 트러블이 발생했던 적은 전혀 없었으며, 오히려 다른 팀들보다 프로젝트 진행에 있어서 더 소통하고 더 화목하게 진행되었을 것이라고 확신할 수 있다.
(물론 내가 잘한게 아니라, 프로젝트가 매우 빡빡하게 진행되어 추석 연휴 때 하루도 못 쉬고 작업을 했음에도 불구하고 불평 한마디 하지 않으신 팀원분들 덕분이다)
문제가 있던 부분은 팀원 들 간에 각자 작업한 코드를 공유함에 있어 발생했다. 코드스테이츠에서는 프로젝트 진행 기간동안 매일 30분의 코드 머지(Merge) 시간과 1시간의 코드 리뷰(Review) 시간을 가지는 것을 권장한다.
하루의 개발을 마무리하는 저녁에는 각자 당일에 작성한 코드를 팀원들 모두가 이해할 수 있도록 공유하고, 하루의 개발을 시작하는 아침에는 전날 공유한 코드를 하나로 합치는 시간을 가지라는 것이었다. 매우 합리적으로 느껴졌기에 일정이 빠듯하지 않았던 1주차 때에는 최대한 코드 리뷰 및 코드 머지에 시간을 많이 들이고자 노력했고, 실제로 의도한 대로 잘 진행되는 듯 했다.
하지만, 본격적인 기능들을 실제 프로젝트에 적용하고 배포하기 시작한 2주차 때에는 각자의 기능 구현에 바빠 코드 리뷰에 큰 시간을 들이지 못했던 것 같다. 특히 2주차 초에 백엔드에서 HTTPS 관련 문제로 인해 로그인 API가 동작하지 않아 고생했었는데, 이 때에는 프론트인 나도 문제해결을 위해 잠시 백엔드에 합류하다보니 정신이 없어 코드 리뷰 시간을 챙기는 것을 깜빡했다. 그리고 깜빡한 채로 긴 시간이 흘러버렸다...
프로젝트가 후반으로 갈수록 코드도 길어지고 로직도 복잡해지기 때문에, 팀원 전체가 코드를 이해하는 것이 굉장히 중요하다. 따라서 프론트엔드의 경우에도 후반으로 갈 수록 코드 리뷰에 더욱 시간을 투자해서, 각자 작업한 프로젝트 코드가 동일한 코드 스타일과 동일한 로직을 가지도록 지속적인 리팩토링을 했어야 한다.
하지만 위에서 상기한 대로 충분한 코드 리뷰 시간을 가지지 못했고, 결과적으로 코드가 개판 5분전이 되어버렸다. 하나의 컴포넌트로 처리할 수 있는 부분인데 기능별로 작업을 나눠서 하다보니 중복되는 컴포넌트들이 생겨버렸고, 이러한 컴포넌트들이 쌓이고 쌓이면서 프로젝트 기간 내에 리팩토링을 도저히 할 수 없는 지경에 이르렀다. 아래 코드 구조를 보라. 절대 이렇게 많은 컴포넌트 구조가 필요한 프로젝트가 아니다.
물론 기능 시연에 있어서 코드가 어떻게 짜여져있냐는 아무 상관이 없지만, 장기적으로 봤을 때 얼마나 기능들을 컴포넌트 별로 분리해 '독립적인' 코드를 작성했는지가 프론트엔드 개발자의 실력을 가늠할 수 있는 척도가 된다고 생각한다.
다음 프로젝트 때에는 굳이 팀장이 아니더라도, 반드시 코드 리뷰에 충분한 시간을 가지고 매일 리팩토링을 진행해야 겠다고 다짐했다.
사실 깃을 사용하는게 아직도 어색하기는 하다. 하지만 그것이 깃 관리를 제대로 못한 것에 대한 면죄부가 되지는 못한다. 팀장으로써 프론트엔드 뿐만 아니라 백엔드의 깃 플로우가 정상적으로 관리되도록 지속적으로 체크 했어야 하는데, 백엔드는 물론이고 내가 담당한 프론트엔드도 제대로 관리하지 못했다는 사실에 아쉬움이 남는다.
(여기에서 체계적인 깃 관리란 단순히 커밋하고 머지하는 수준을 벗어나서, 각 작업들에 대한 이슈 카드를 만들고 칸반 보드를 활용하고 커밋 메시지를 기존에 합의한 형식대로 작성하는 것을 의미한다.)
당장 2주안에 무언가 보여줄 만한 결과물을 만들어내야 했기 때문에 기능 구현에 초점을 맞출 수 밖에 없었고, 이에 따라 자연스럽게 깃 브랜치 관리 등 깃 관련 작업들에 대한 우선순위가 낮아졌던 것은 사실이다. 또한, 당장 이러한 작은 규모의 프로젝트에서 깃 관리를 제대로 안했다고 해서 어떤 문제가 발생하는 것은 아니다. 팀원분들도 당장 프로젝트 기능 구현이 바빠 깃 관리는 전혀 고려하지 못하고 있었으며, 내가 팀장으로써 깃 관리를 강요하면 그로 인해 프로젝트의 생산성이 저하될 것이라고 판단했다. 따라서 팀원분들께 체계적인 깃 관리를 크게 강요하지는 못했다.
하지만 실제로 개발자로 취직했을 때 반드시 갖춰야 할 역량 중 하나가 바로 프로젝트 깃 버전관리이며, 여유가 있었던 없었던 상관 없이 프로젝트의 깃 관리에 따로 시간을 내서라도 신경을 썼어야 했다. 파이널 프로젝트 때에는 반드시 깃 관리에 더 신경을 써야겠다는 생각을 하게 되었다.
프로젝트를 처음 시작한 1주차에 기획을 시작했는데, 다행히도 팀원분들이 프로젝트를 위한 다양한 주제들을 이미 가지고 오셔서 주제 선정에는 크게 문제를 겪지 않았다. 그래서인지 다른 팀들보다 기획에 더 시간을 많이 투자할 수 있었다.
하지만 아무래도 개발 경험이 아직 미숙하다보니, 처음에 한 기획을 갈아엎어야 했던 적이 많았다. 프론트엔드는 이미 주제가 명확히 정해진 상태에서 프로토타입 작성과 디자인을 설계했기 때문에 초기 기획에서 크게 바뀐점은 없으나, 백엔드의 경우 특히 DB 스키마와 서버 API 구조들을 프로젝트가 진행됨에 따라 많은 부분을 고쳐야 했다.
프론트엔드도 마찬가지로, 본래 기획은 모바일 화면을 기준으로 한 디자인을 먼저 구현한 후에 데스크톱 디자인을 반응형으로 구현할 예정이었으나, 프로젝트가 진행됨에 따라 흐지부지된 점이 없지 않다.
따라서 기획을 상세히 짜는 것도 매우 중요하고, 그 기획을 최대한 지키도록 노력하는 것도 중요하다고 느낄 수 있었다. 다음 프로젝트에서는 기획할 때 최대한 많이 고민해보고, 실 구현시에는 기획을 최대한 따라가되 기획에서 변경될 사항이 있다면 즉시 팀원분들께 알려주는 식으로 진행해야겠다 라는 다짐을 했다.
2주. 짧다고 하면 짧고 길다고 하면 긴 시간이다. 프로젝트를 진행해보니 이 2주라는 시간이 턱없기 짧은 시간이라는 것을 깨달았다. 기획까지 포함하니 실제 개발에 투자할 수 있는 시간은 얼마 되지 않았다.
아무래도 숙련된 경력 개발자가 아니다보니 시간 안에 무언가 보여줄 만한 결과물을 만들어내려면 몇 가지를 포기해야 했다. 팀장으로써 '결과물'에 보다 집중하기 위해 '체계적인 깃 관리'를 포기했는데, 그렇게 올바른 선택은 아니였던 것 같다. 사실 코드상으로 함께 협업한 사람은 프론트엔드 한 명 뿐이었으므로 체계적으로 깃 관리를 해서 얻을 수 있는 이득이 적었던건 사실이지만, 나도 결국 아직 '배우는 입장'이니 매우 중요한 협업 툴인 Git의 중요도를 더 높였어야 하지 않았나 후회중이다.
지나간건 지나간 일이다. 나는 과거의 잘못을 계속해서 후회하는데 시간을 낭비하기 보다는, 교훈을 빠르게 챙기고 머릿속에서 털어버리는 사람이다. 이 교훈을 바탕으로 파이널 프로젝트를 잘 진행했으면 좋겠다. 물론 팀장은 다시는 안하고싶다. 쓴 소리를 잘 못하는 사람이라 팀원들의 중심을 잘 잡아주지 못하기 때문이다. 다음 프로젝트 때에는 팀원으로써 열심히 프로젝트에 이바지하고자 한다.