[나와 닮은 못난이 농산물 똑닮안] 2. 36시간 내에 MVP 완성하기1
개요
비어 파티를 즐기고 우리에게 남은 시간은 3일 차 0AM부터 4일 차 12PM까지, 총 36시간이었다. 사실 발표 자료 제출 마감은 10시였는데, 발표가 오후 1시부터 진행되었기 때문에 그전까지 개발의 수정사항 반영시킬 수 있었다. (심사 전까지 배포만 하면 되니까~ 😙)
이때부터 프로젝트 주제를 구체화하기 위해 논의한 시간, 밥 먹고 커피 먹고 야식 먹은 시간, 취침 시간을 제외하면 정말 온전히 개발만 한 시간은 얼마 되지 않았던 것 같다. 하지만 "코드 작성 === 프로젝트하는 중"
이 아니기에 짧고 굵게 한 가지 일에 몰입했던 경험을 프론트엔드 개발 과정과 함께 이야기해 보려고 한다.
1. 주제 구체화 단계
명확한 기획이 완료되지 않은 상태에서 프론트엔드가 할 수 있는 일은 많지 않았다. 기술 스택을 정한 후 프로젝트를 세팅하고, 외부 API가 필요한 기능들을 추려 동작을 미리 테스트해 보는 것이 전부였다.
스택 정하기
프론트엔드의 경우 두 명의 팀원이 있어 협업이 필요했다. 따라서 기술 스택을 맞추는 것이 가장 중요했고 우리는 서로가 익숙한 react
를 채택했다. 사실 서비스의 기능을 생각하고 그에 알맞은 스택을 정하는 것이 좋겠지만, 기획도 디자인도 없는 단계부터 세팅에 들어가야 했기에 그리고 무엇보다 빠르게 개발할 수 있는 것이 우선이었기에, 스택을 정하는 데 있어 익숙함은 중요한 요소였다.
그리고 오류를 사전에 방지하고자 typescript
를 도입했으며, 스타일은 styled-components
를, 전역 상태 관리는 recoil
을 택했다. 다만, recoil
에 대해서는 둘 다 익숙함과는 거리가 멀었는데.. 내가 도입하자고 강력 주장했었다. 해커톤에 오기 전 혹시 몰라 몇몇 강의를 보며 기본 기능을 익혔는데, 세상에 redux
와는 비교도 안될 정도로 세팅이 간단했고 사용법도 너무 편리해서 이걸 왜 이제야 알았지?!라는 억울함이 있었다. 그래서 해커톤에서 recoil
을 무조건 써야겠다는 개인적인 욕심이 있었고, 빠른 작업에 용이할 것이라는 생각에 이를 어필해 봤는데 다행히 팀원 분이 수용해 주셨다!!
API 연동의 경우 기본적으로 axios
통신을 했다. react-query
도 도입해보고 싶었는데 필수적인 것이 아니었고, 사용하는데 익숙한 사람이 없었기에 추후 리팩토링 과정을 거치며 추가했다. (당시 적용을 시도했는데 실패하고 백로그로 넘겨버렸다)
카카오톡 공유 기능
이때까지 나온 서비스의 큰 흐름은 "뭔가 해서 -> 못난이 농산물 관련 결과 도출 "이었고, 그 결과를 공유하는 기능을 넣기로 했었다. 그래서 프로젝트 세팅을 완료하자마자 카카오 메시지 API에 대한 테스트를 시작했다.
그런데.. 몇 가지 문제가 발생했다.
P1. Kakao에 접근 불가
S1. 리액트에서 Kakao에 접근하려면 window.Kakao
로 접근해야 한다.
P2. 타입 에러 (window에는 Kakao라는 것이 없기 때문)
S2. (window as any).Kakao
와 같이 타입을 정의해야 한다.
React + Typescript
에서 카카오 API를 이용할 때는 위와 같은 설정이 필요하다는 것을 알게 되었다.
function KakaoShare() {
const onClickShareBtn = () => {
if (!(window as any).Kakao.isInitialized()) {
(window as any).Kakao.init(process.env.REACT_APP_KAKAO_JAVASCRIPT_KEY);
}
(window as any).Kakao.Share.sendCustom({
templateId: Number(process.env.REACT_APP_TEMPLATE_ID),
});
};
return (
<>
<div>카카오톡 공유하기</div>
<button onClick={onClickShareBtn}>공유하기</button>
</>
);
}
export default KakaoShare;
2. 레이아웃 개발 단계
몇 시간의 아이디어 회의 끝에 나온 최종 주제는 "몇 가지의 성향 테스트와 얼굴 인식을 기반으로 나와 닮은 농산물 캐릭터를 매칭시켜 결과를 도출하자"였다. 결론이 난 후 나는 4시간 정도 잠을 자고 왔고, 그 사이에 디자이너님이 대략적인 디자인 작업을 완료해 주셨다.
프론트엔드인 우리는 이를 화면에 옮기기 위해 아래와 같이 역할을 나누고 작업에 들어갔다.
1. 공통 컴포넌트 개발 (다른 FE 팀원)
2. 결과 페이지 레이아웃 작업 (나)
그런데.. 공통 컴포넌트가..!?
같은 작업을 여러 곳에서 할 수는 없으니까 공통 컴포넌트를 만드는 것은 당연했다. 너무나 당연하게 그래야 한다고 생각했기에 역할을 나누었을 때는 아무 문제가 없었다. 하지만 결과 페이지의 레이아웃을 잡아가면서 컴포넌트 작업을 기다리는 것이 오히려 작업 속도에 브레이크를 걸었고, 처음 만난 두 사람이 코딩 스타일을 맞춰가며 컴포넌트 하나를 만드는 데는 너무나 많은 커뮤니케이션 비용이 필요했다. (작업을 같이 해 본 사이라면 효율적일지도?)
개발 생산성이 떨어지는 느낌을 받았다. 페이지도 얼마 되지 않는데 이게 맞나 싶은 생각에..
Q. 저희 그냥 페이지별로 각자 할까요? (왜냐면 어쩌고 저쩌고..)
A. (끄덕끄덕 x 100)
그렇게 우리는 바로 반복이 되건 말건 쌩으로 페이지 작업을 시작했다. 이건 리팩토링하는 걸로! 미래의 나에게 모든 일을 맡기고 빠르게 레이아웃을 잡아갔다. 아래는 선택 페이지와 결과 페이지의 일부 디자인인데, 두 페이지 모두에서 쓰이는 Typography
혹은 Button
과 같은 것을 공통 컴포넌트로 빼지 않고 각자 페이지 내부에서 작업을 했다는 것이다.
공통 컴포넌트를 만들면서 작업하는 것은 하나의 방법론일 뿐이라는 것을 알게 되었다. 물론 개발하면서 중복을 최소화하는 것을 지향해야겠지만, 상황에 맞는 최선의 선택을 하는 것도 중요하다고 생각한다. 당시에는 시간적 요소가 우선되었고, 꼼꼼하고 깔끔하게 코드를 작성하는 것보다 일단 완성을 시키는 것이 중요했다. 물론 초기 디자인에서 약간의 수정이 생겼을 때, 엄청나게 많은 부분을 고쳐야 했던 일도 있었지만.. 그래서 후회도 했지만, 당시로서는 최선이었다고 생각한다.
당연한 것은 없다!