코드 치기 전에 정할 것들
기획 단계가 마무리되고 이제 본격적으로 개발할 일만 남았다. 그리고 우리에게 미션이 떨어졌다. 일주일 안에 MVP 제작하여 발표하기가 그것이었다.
당시 걱정되는 점이 한 두 가지가 아니었다. 몇 가지 꼽아보자면,
- 팀원들 프로젝트 경험이 없거나 적은데 괜찮을까? (경력자 팀원 C 제외)
- 메타버스, 오디오, 공동 편집 에디터 모두 처음 도전하는 (어려워보이는) 기술인데 아무것도 모르는 우리가 괜찮을까?
- 거의 대부분(90% 이상) 처음 만져보는 스택인데 괜찮을까? (특히 나)
- (위 모든 난관을 극복하고) 한달이라는 시간 안에 퀄리티 있게 완성할 수 있을까?
내가 못해도 우리 팀 중 누군가는 할 수 있겠지라는 마음가짐밖엔 답이 없었다. 우리에겐 열심히 작성한 할일을 알려주는 기능 명세서가 있었고 갈 길이 구만리였다.
다짜고자 VS Code 켜고 코딩부터 하기 전에 몇 가지 짚고 넘어가고 싶은 사항들이 있었다. 다음과 같은 것들이었다.
- 누가 어떤 기능을 개발할 것인지 정하기
- 기술 스택 정하기
- 개발 환경 세팅하기
- 개발 컨벤션 정하기
- 개발 일정 수립하기
누가 어떤 기능을 개발할 것인가
아직 프론트/백엔드 롤을 확고히 정한 사람이 별로 없었고, 나 또한 당시에 어떤 것이 나에게 더 잘 맞는지 탐구하는 단계에 있었으므로 우리는 기능 별로 나눠 풀 스택을 경험해보자는 의견에 뜻을 모았다.
우리가 일주일 안에 개발하고자 하는 최소 기능은 아래와 같았다.
앞으로 일주일 안에 개발해야 하는 최소 기능
- 메타버스 - 맵 내 캐릭터 움직임 실시간 동기화
- 에디터 - 파이썬이 돌아가는 공동 편집 가능한 웹 에디터
관련 기능을 구현해본 사람이 아무도 없어서 모두의 눈에 모든 기능이 다 매력적으로 보였다. 그래서 뽑기로 정했다. 그 결과 나는 에디터 기능을 맡게 되었다.
기술 스택 정하기
우선 자바스크립트로 서버와 프론트를 통일시키기로 했다. 이는 조금이라도 우리 팀의 러닝 커브를 최소화하기 위한 지극히 현실적인 전략이었다. 팀원 A가 React 사용 경험이 있는 프론트엔드 경력자였고, 팀원 C도 자바스크립트 프로젝트 경험이 있었다.
그에 맞춰 서버도 express 프레임워크를 사용하기로 정했다. 당시 node.js를 제외한 선택지로는 파이썬 정도가 있었으나 굳이 파이썬을 선택할 이유는 없었다.(모두 제대로 된 파이썬 프로젝트 경험이 없었으며 알고리즘 문제를 풀며 익힌 정도였다. 나는 파이썬이 제일 손에 익은 언어였지만 현실적으로 추후 취업을 위해 자바스크립트 프로젝트를 하고 싶다는 바람이 있었다.) Java 경험이 있는 팀원은 아무도 없었고 Java는 공수가 많이 들어가겠다는 판단 하에 고려하지 않았다.
그런 와중 TypeScript를 도입하여 자바스크립트의 디버깅을 좀 쉽게 해보자!는 의견이 팀원 A로부터 제시되었다.
(자스도 낯선데 너까지?!!)
타입스크립트를 써본 팀원이 아무도 없었고(나 포함), 자바스크립트로도 제대로 된 개발을 해본 경험이 없던 나로서는 그 제안이 부담스러웠지만, 타입스크립트의 장점에 설득당했고 일반 자바스크립트로 작성해도 문제 없다는 말에 오케이했다. 그리고 실제로 프로젝트 당시에 타입스크립트를 제대로 사용할 여유가 없었던 건 사실이다. 그런데 추후 에디터 서버 코드 1차 리팩토링을 하면서 타입 정의와 타입스크립트 warning을 해결해나갔고, 그제서야 타입스크립트를 제대로 사용해본 셈이 되었다.
기본적인 백엔드와 프론트엔드 프레임워크를 정하고, 이외에 추가적인 스택을 정하는데 있어서 우리의 화두는 다음과 같은 것들이 있었다.
- 메타버스 맵을 어떻게 만들 것인가? (어떤 라이브러리를 사용할까?)
- 에디터를 어떻게 만들 것인가? (어떤 라이브러리를 사용할까?)
- 메타버스, 에디터의 실시간 통신 기능을 어떻게 구현할까?
- 데이터베이스는 언제 어떤 것을 사용할까?
- 오디오 기능은 어떻게 구현할까?
메타버스 라이브러리 정하기
이를 정하기 앞서 2D vs. 3D 의견이 갈렸다. 결국 2D로 정했다. 이유는 3D는 맵을 보다 크게 만들었을때 더 효과적일 같았고(우리는 강의실이라는 비교적 작은 공간만 사용할 것이었으므로), 리소스 문제가 생길 것 같다는 우려 때문이었다. 특히 에디터와 오디오 기능까지 들어갔을 때 감당이 될지 불확실했다.
2D 메타버스를 제작하기 위해서 거론되는 자바스크립트 라이브러리가 크게 두 가지 있는데 1) Phaser 2) Pixi.js가 그것이다. Phaser는 이 분야에서 가장 대중적인 라이브러리이다보니 커뮤니티가 잘 활성화되어 있었다. 또 레퍼런스 프로젝트를 찾기 그렇게 어렵지 않았고, 좀 더 사용하기 쉽다는 의견이 있었다. 한편 Pixi.js는 성능 측면에서 좀 더 좋다는 평가가 있었고 그러다보니 좀 더 그래픽이 복잡할 경우 사용하기 좋았다.
✅ Phaser로 결정했다. 완전히 새로운 라이브러리를 학습하는데 있어서 조금이나마 레퍼런스가 많으면 러닝 커브를 줄여줄 거고, 복잡한 그래픽을 사용하지 않을 예정이었기 때문이다.
에디터 라이브러리 정하기
검색 결과 CodeMirror와 Monaco로 좁혀졌다. 데모도 경험해보고 했지만 솔직히 내 눈에 두 라이브러리의 기능상 큰 차이점이 느껴지진 않았다. 둘 다 충분히 만족스러운 editing 기능을 제공하는 것처럼 보였다. 또 둘 다 자주 언급되는 라이브러리인 걸로 보아 참고할 만한 자료도 충분히 있을 법 했고.
✅ 결론적으로 CodeMirror로 결정하였다. 그 이유는 공식문서를 봤을 때 (둘 다 어려워 보이는 건 똑같았지만) CodeMirror의 공식문서가 훨씬 자세하고 구체적인 예시를 제공하고 있었다. 결정적으로 Monaco와 달리 CodeMirror의 공식문서에 “Collaborative Editing” 항목이 있었을 뿐만 아니라 CodeMirror 구현한 공동 작업 에디터 샘플을 보여주고 있었다. 와! 불가능할 줄로만 알았는데 가능한 거였다니… CodeMirror와 공동 작업 에디터라는 키워드로 자료가 꽤 있었고 도전할만 하겠다는 판단 때문이었다. (그리고 후에 눈물을 흘리게 되는데….)
실시간 통신 기능 구현
메타버스 맵 내에서 유저들의 모든 상호작용은 실시간으로 모든 사용자들에게 동기화되어야 했고, 에디터도 작업 내용이 실시간 동기화되어야 했다. 이 기능을 구현하기 위해 선택지가 두 개 있었다. 전통적인 웹소켓과 Socket.io.
✅ 우리는 Socket.io가 사용하기 간편하고 기존의 웹소켓에 추가적인 기능을 더 지원한다는 점이 끌렸기 때문에 Socket.io를 사용하기로 했다.
데이터베이스: SQL vs. NoSQL
DB 유형을 결정하는 일이 쉽지 않아서 고민을 좀 했다. 당시는 이런 스택을 정하고 아키텍쳐를 그리는 일이 내게는 정말 어려운 일이었기 때문에 더욱 그랬다.
(이때의 고민이 추후 DB 학습 동기부여가 되었다.)
사실 초반에는 코드와트가 데이터베이스를 사용할 일이 거의 없을 거라 예상했다. 기껏해야 유저 정보 뿐이었다. 그 이유는
- 알고리즘 문제는 서드파티 API 요청으로 해결할 생각이었다(백준 측에서 문제 저장을 금지하는 규정을 본 바 있었다.)
- 데이터베이스를 사용하는 핵심 기능(+옵션 기능)이 딱히 없었다.
✅ 어떻게 DB를 쓸 것인지 마땅히 정해지지 않은 우리의 상황에는 지금 당장 스키마를 정할 필요가 없고, 팀 모두 사용 경험이 있는 NoSQL 기반 MongoDB가 더 적합해보였다. SQL을 선택하면 새로운 학습 부담이 더해진다(= 개발 속도 저하)는 이유도 있었다.
지금에 와서 생각해보면 그때의 생각이 그렇게 틀리지 않았던 것 같다. 프로젝트 규모가 그렇게 크지 않다보니 SQL을 써서 드라마틱하게 유의미한 차이가 있었을 거라곤 생각이 들지 않는다. 초반의 계획과 다르게 알고리즘 문제를 우리의 DB에 직접 저장하는 일이 생겨났는데, 딱히 중복 데이터 관리가 필요하지도 않고 단순히 알고리즘 문제를 저장하고 빠르게 검색만 하면 됐다.
(하지만 지금 시점에서 SQL에 관해 어느 정도 학습하고 생각해보니 NoSQL로는 한계가 있다는 생각을 했다. 이는 코드와트 유저와 유저가 푼 문제에 관한 크로스플랫폼(백준, 리트코드 등) 통계를 제공하는 기능의 구상에서 비롯됐다. 이 기능은 유저 정보와 각종 플랫폼에서 해당 유저가 푼 문제 정보가 연결되어야 하므로 SQL로는 비교적 간단히 구현할 수 있을 거 같은데 NoSQL로는 데이터 관리가 번거롭겠다는 생각이 들었다.)
오디오 기능 구현
사실 이 단계에서 우리는 오디오 기능 스택에 관해 구체적으로 논하지는 않았다. 그 이유는 이때 당시 메타버스, 공동 작업 에디터에 이어 오디오 기능까지 우리가 구현할 수 있을지 의문이었기 때문이다! (어쩌면 우리 스스로를 과소평가 했나 싶기도 하다.)
다만 WebRTC를 사용하지 않을까 정도만 말이 오고 갔다. 참고 자료가 많기도 했고, 당시 우리 팀 말고도 WebRTC를 스택으로 선정한 팀이 많았는데 그 때문에 우리가 모르면 옆 팀 가서라도 물어볼 수 있다!는 이유에서였다. (그리고 실제로 상부상조 했다!)
없어서는 안 되는 최소 기능이 메타버스, 공동 작업 에디터였고 일주일 간 이를 구현해보면서 되나 안 되나를 빠르게 판단하고 일주일 후 오디오 기능에 관해 논해보자고 이 당시에는 결론이 났다. 그리고 이후 앞서 프론트 경력자라고 언급했던 팀원 C가 오디오 기능 개발을 맡게 되면서 해당 팀원이 스택을 결정하게 되었다.
아무튼 추후에 오디오 기능 구현이 확실시 되고 나서 팀원 C가 고민이 많았다. 이유는 WebRTC 오픈 소스 라이브러리가 많아서였다. 우선 우리가 기획한 음성채팅은 다자간 음성 통화가 가능한 보이스 룸의 형태였기 때문에, peer-to-peer보다는 SFU 방식을 사용하는 라이브러리가 높은 효율을 낼 거라고 판단되었다. 또한 빠른 개발속도를 내는 것이 목표였고 리액트와 node.js 환경에 적용 가능한 라이브러리여야 했다.
✅ 이러한 기준을 세우고 추리다 보니 SFU 라이브러리이자, 공식 문서가 자세하고 수많은 백엔드/프론트엔드 플랫폼을 지원하는 OpenVidu가 가장 적합하다는 결론이 나왔다.
개발 환경 세팅 & 컨벤션 정하기
gitflow workflow 전략 선택
부트캠프에 입소하기 전 약 3주 정도 여유 시간이 있었다. 뭘 공부하면 좋을까 고민하다가 GitHub을 어떻게 다루는지 궁금했고 협업을 위해서는 Git이 필수라는 얘길 듣고, 다른 건 몰라도 Git & GitHub 사용법은 익히고 가야겠다는 생각에 학습했었다. (※ 당시 학습한 내용 포스팅 ☞ Git & GitHub 다루기) 다시 되돌이켜봐도 그때 학습하길 참 잘했다고 생각하고 Git이란 툴은 정말 매력적이다.
당시 Gitflow 브랜치 전략을 책에서 소개하고 있었고 나는 그걸 관심있게 봤었는데, 누군가의 실수, 에러 등 어떤 상황에서도 최대한 메인 코드를 안정적으로 지킬 수 있게끔 마련된 영리한 시스템이라는 생각이 들었다. (과거 개발자들의 수많은 에러와 시행착오 끝에 정착된 산물같은 걸로 느껴졌다.)
부트캠프에 와서 Git을 처음 써본 팀원들도 있었고, 부트캠프에 와서 Git 사용법이 미숙해 코드를 날려먹은 친구들, Git 충돌 때문에 어쩌지 못하고 카톡으로 코드를 전달하는 사례까지 보았던 터라… 안정적인 한 달간의 프로젝트를 위해서 무조건 브랜치 전략을 팀원들에게 알려주고 사용하게 해야겠다는 생각이 들었다.
그래서 "Git 브랜치 전략 중 Gitflow Workflow란 것이 있더라"하고 간단한 설명을 하고 이를 사용하자고 주장했다. 소중한 우리 코드를 날려먹지 않고 충돌이 나도 멘탈 바스러지지 않고 안정적으로 개발할 수록 우린 시간을 버는 셈이라는 의견과 함께. 이를 포함해서 브랜치 사용에 관해 몇 가지 규칙을 정하자고 했다.
- Gitflow 기반 브랜치 전략 사용하되 팀 상황에 맞게 간소화;
main
,feat
,fix
,deploy
등 브랜치 사용- 되도록
main
에 바로 푸시하지 않는다. (문서 작업 같은 간단한 일 외에)- 강제 푸시 하지 않는다. ex)
git push -f
- 브랜치 작업 완료 시
main
의 코드를 내 브랜치로 먼저 병합하여 충돌 해결 및 테스트 한 후에main
푸시하기 (안전장치 강화)- PR은 자유롭게. (PR까지 필수 규칙으로 정해버리면 개발 속도가 너무 더뎌질 것 같아서)
(커밋 기록이 제일 많았던 3주차 186개의 커밋.)
팀원들은 긍정적으로 받아들였다. 그 때문인진 몰라도 지금까지 메인 브랜치에만 1100여개 커밋 기록이 있는데, 그러는 동안 열심히 작업한 누군가의 코드를 날렸다든가 충돌 해결에 문제가 생겨서 될 게 안된다든가 하는 사고 한 번 없이 개발할 수 있었다.
커밋 템플릿 맞추기
또 꼭 지키고 싶었던 게 커밋 템플릿이다. 커밋 메시지를 중구난방으로 작성해서 깔끔하지도 않고 알아보기 힘들었던 경험은 다들 있을 것이다. 게다가 다른 팀원들이랑 같이 작업하는 저장소라면 더욱 더. 기왕이면 영어 연습도 할 겸 영어로 커밋 메시지 템플릿과 커밋 규칙도 맞췄다. (개발자에게 가장 중요한 언어는 영어?)
실제로 우리가 사용한 커밋 템플릿.
# 작성할 때에는 키보드 i 누르기, 작성 완료하고 저장하려면 esc키를 누른 다음 :wq!를 입력하고 엔터 누르기
# <타입> : <제목> 형식으로 작성하며 제목은 최대 50글자, 대문자로 시작하는 동사원형으로 작성(영어인 경우)
# 제목을 아랫줄에 작성, 제목 끝에 마침표 금지, 무엇을 했는지 명확하게 작성
################
# 본문(추가 설명)을 아랫줄에 작성
################
# 꼬릿말(footer)을 아랫줄에 작성 (관련된 이슈 번호 등 추가)
################
# feat : 새로운 기능 추가
# fix : 버그 수정
# docs : 문서 수정
# test : 테스트 코드 추가
# refactor : 코드 리팩토링
# style : 코드 의미에 영향을 주지 않는 변경사항
# chore : 빌드 부분 혹은 패키지 매니저 수정사항
################
일단 형식이 갖춰지니 보기에 깔끔하고 이해하기 어렵지 않았다.
formatter 설정 맞추기
처음에는 이걸 맞춰야 하는 필요성을 몰랐었는데, 알게 된 계기가 있다.
핀토스를 하면서 같은 팀이었던 컴공과 친구가 C를 주 언어로 다루는 동료였는데, C lint 설정 파일을 공유할테니 맞추자고 제안했었다. 나도 포맷터를 사용하고 있어서 이상할 건 없었지만 이것도 팀원끼리 맞춰야하나 싶었다가, 커밋 changes 기록을 보고 납득했다. 서로 다른 포맷터가 각자 이미 포맷해놓은 파일을 다시 포맷팅하면서 의미 없는 변경 사항들이 죄다 커밋에 반영되어 보기 불편했다.
그러한 나의 경험을 공유하면서 그래서 우리도 lint 설정을 맞추자고 주장했고 prettier 설정을 다같이 맞췄다. (자바스크립트 인덴테이션 4칸 vs 2칸파로 나뉘었지만 4칸파가 패했다.)
개발 일정 수립하기
약 5주라는 이라는 기간 동안 무엇을 고려하여 어떻게 일정을 짜야 가장 최선일지 고민했다. 언제까지 무엇이 어떻게 되어있어야 하는지 경험이 없다보니 감을 잡기 어려웠다. 아무래도 경험자의 지식이 필요하다 판단해서 팀 멘토님께 조언을 구했고 대략적인 가이드라인을 얻을 수 있었다. 그에 따라 최종 발표일을 기점으로 거꾸로 날짜를 계산하면서 계획을 세웠다.
최종 발표 1주 전: 최종 완성 및 발표 준비
최종 발표 2주 전: 프로젝트 다듬기 + 퀄리티 높이기 + 디버깅
최종 발표 3주 전: 불타는 개발 2 + 핵심기능 완성 및 중간발표
최종 발표 4주 전: 불타는 개발 1
최종 발표 5주 전: 스택 학습 + MVP 개발
대략 이렇게 마일스톤을 세우고 구체적인 일정은 노션 타임라인을 이용했다. (협업 툴에 관해 잠시 말하자면 초반에 스타트업들이 Jira + Confluence를 많이 쓴다더라 우리도 한 번 사용해보자 했다가 Confluence 한글 에러, 마크다운 작성 불편함 등 전반적으로 노션보다 딱히 더 편한지 모르겠음의 이유로 일찌감치 갈아탔다.)
(최종발표 3~4주 전 앞만 보고 개발만 하던 때의 노션 타임라인)
과업을 표기하고 담당 팀원을 배정한다. 클릭하면 각자의 개발 노트도 확인 가능하다.
장점으로는 누가 어떤 일을 맡아서 하고 있는지 파악 가능하고 소통과 협업이 수월해진다는 점이다. 또 이때까진 무조건 돼야 해 or 이때까지 안 되면 플랜B로 가야해 등 토끼 굴에 빠지지 않게 도와주면서 동기부여의 역할도 된다. 그리고 무엇보다도 프로젝트를 수행하며 큰 노력을 들이지 않고(중요!) 기록을 남길 수 있다는 점이 좋았다. 지금처럼 내가 회고록을 작성하는데에 지대한 도움이 되기 때문이다.
회고하며
돌이켜보면 사소해보일지 몰라도 하나 하나 협의하며 정한 이런 규칙들 덕분에 한 달이라는 기간 동안 다른 팀들과 비교했을 때 안정적인 협업이 이루어졌다. 나는 모든 것을 시스템으로 통제할 순 없지만 좋은 시스템은 효율성과 안정성을 가져다 주기 때문에 진짜 중요한 것에 더 몰입할 수 있게끔 한다고 믿는다. 그리고 이번 경험을 통해 실제로 그 결과를 확인했다고 생각한다.
여튼 이제 정할 건 다 정했고, 다음 편부터는 진짜 본격적으로 코드치는 내용이 되겠다.
'크래프톤정글 > 프로젝트: 코드와트' 카테고리의 다른 글
코드와트 프로젝트 (1) 팀 빌딩 & 서비스 기획 (1) | 2023.06.02 |
---|