﻿---
title: "홀로선 첫 번째 웹 프로젝트"
description: "입사하자마자 기존 개발자들과 바통터치하며 홀로 맡게 된 6개월간의 프론트엔드 프로젝트. 1차 마일스톤이 끝난 시점에 잘한 점과 아쉬웠던 점을 기록해본다."
pubDate: 2020-09-28
tags: [회고]
author: 류기혁
---

2020년 3월 부터 **약 6개월동안 웹 프로젝트를 진행**하였다. 입사를 하자마자, 우연히 **기존 개발자들과 바통터치**를 하게 되면서 프론트엔드 프로젝트의 설계 부터 세팅까지 맡게 되었다. 나름대로 주니어의 모습에서 벗어나고 있다고 생각하지만 **약 4년 7개월** 동안 **게임 개발자, 앱 개발자, 블록체인 서비스 개발자, 웹 개발자**로 탈바꿈을 하다 보니 특정 한 분야의 깊이가 부족했다. 천년만년 팀원 중에 날 리드 해줄 사수가 있다고 생각 했는데. 새삼 나의 경력에 무게를 느끼게 되었고, 두려움 속에 반년의 시간을 보냈다.

결론적으로 많은 성장을 했지만, 나의 부족함에 아쉬움 또한 많이 남았다. 하지만, 이 경험이 나를 성장 시키는 하나의 **성장통**이라고 생각 하고, 해당 프로젝트가 세상의 빛을 볼 수 있을지 아직 모르겠지만 짧은 경력 중에 **가장 애정이 많이 담긴 프로젝트**이기 때문에 1차 마일스톤이 종료 된 이 시점을 기억 하고 싶어 회고록을 작성해본다.

## 잘한 점

### (1) 과감한 프로젝트의 환경 변화

입사를 하고, 첫 째날은 여러 서류들을 제출하며 상황 파악을 했다. **`어떤 방식으로 개발이 진행되었고, 나의 역할이 무엇인지.`** 하지만 **대격변의 시기**였기 때문에 명확한 것은 아무것도 없었다. 한 가지 확실한 것은 어떤 프로젝트를 진행 하던 **기존의 프레임워크는 Vue**였고, **내가 경험한 것은 React**였다. 반 년이 지난 이후에도 난 Vue <-> React 의 장벽이 높지 않다고 생각 하지만, 난 조언을 구할 팀내 개발자가 없는 상태였기에 입사 둘 째날 부터 Vue와 React를 비교하였고, 프레임워크를 변경하고 싶다고 이야기를 했다.

감사하게도 나의 이야기를 모두 들어주셨고, 지옥의 프로젝트 환경설정을 진행하게 되었다.

**`책임의 무게`** 때문인지, **`나의 성격`** 때문인지 모르겠지만 입사 2일차에 예상 되는 문제를 단순 `구두 형식`이 아닌, 문서로 정리하여 설득하려 했던 시도가 잘한점으로 기억에 남는다.

*[이미지: Vue vs React 전환을 설득하기 위해 작성한 문서 — 커뮤니티·인력 시장 비교, 코드 변경 예시, Atomic Design/StoryBook 제안까지 담긴 목차 스크린샷. "그냥 팀원들이 더 잘할 수 있는 것을 쓰면 되는 것 같다."]*

### (2) 하루 하루를 정리하기

2200만원 신입 시절에 연봉 협상에서 증거자료를 제출하기 위해 하루 하루를 기록 했다. 그 것은 내게 너무나도 좋은 습관이 되었던 것 같다. 하루를 시작하게 될 때, 어제를 회상하지 않고 전 날의 **Daily 문서를 읽으면 딜레이 없이 하루를 시작할 수 있었다.** 과거에는 간단한 메시지로 팀에게 공유하거나, 개인적으로 텍스트 파일에 주요 내용만 정리 했던 것과 달리. 이번에는 조금 체계적(?)으로 관리 했던 것 같다.

날씨를 표기하기 위해, 출근시 항상 하늘을 보게 되었던 것 같다. 이 점이 무엇보다 기억에 남는다. Daily를 다시 열어볼 일은 흔치 않지만, 개인적으로 부끄럽지 않는 날이 되기 위해 하루하루 최선을 다했다고 생각한다.

Daily의 내용으로는 **`출-퇴근 시간`**, **`목표 업무`**, **`달성 업무`**, `느낀 점`이 있었다. `느낀 점`의 경우 **치명적이거나, 꼭 기억했으면 좋을 경우 별도의 파일로 분리하여 관리** 했다. 인간은 언제나 같은 실수를 반복하기 때문에 다음 프로젝트에서 이를 방지하기 위해 적었다.(적금형 회고랄까?)

게으르지 않고, 꾸준했던 나의 168일에 박수를 보낸다.

*[이미지: 날씨 이모지와 주차 태그를 붙여 #167까지 매일 쌓아온 Daily 문서 목록 스크린샷]*

### (3) 작업 내역 관리

`개발자는 코드로 이야기 한다.`, `작업 기록은 커밋 메시지에.` 틀린 말은 아니지만, **프로젝트의 진행 상황을 비개발분들이 조금 더 쉽게 파악**할 수 있게 하는 것 또한, **개발자의 역할**이라고 생각한다. 매번 작업들이 머지 될 때 마다, 주요 항목들의 액션들을 gif로 만들었고, 기획서에는 나와있지 않았지만 나의 고민으로 생성 된 것들(검색 규칙, 기타 예외처리)을 정리 했다.

이런 작업들이 다른 분들에게 또, 프로젝트에 얼마나 도움이 되었는지는 사실 잘 모르겠지만, 난 앞으로도 나의 습관으로 가지고 가고 싶다.

*[이미지: 머지 시점마다 라우팅·페이지네이션·버그 제보 등을 항목별로 정리한 "FrontEnd 작업 업데이트 내역" 문서 스크린샷]*

## 아쉬웠던 점

### (1) 잦은 리팩토링

프로젝트 중에 '**난 지금 성장 했다.**'라는 느낌을 받은 순간이 최소 3번은 있었던 것 같다. 과거에 이해 되지 않아도 꾸역꾸역 공부한 것들이 비로소 이해 되는 소중한 경험 들이였는데. 사실 이것이 문제였던 것 같다. 과거에 설계하고 확정 지은 시스템들이 틀렸음을 깨닫고, '**늦기 전에 바꾸자.**'라는 생각 때문에 단순한 리팩토링이 아닌, 구조를 바꾸는 큰 일을 두 번 진행 했다. 이번 프로젝트는 UI업무와 그 외 업무가 확실히 나누어져서 큰 문제는 없었지만, 업무의 영역이 나누어져있지 않은 상황에서 이런 문제를 맞닥트릴 경우 어떻게 해야할까? 아마, 이번 프로젝트 처럼 자유롭게 변경하기는 힘들 것이다.

지식이란 것은 알면 알 수록 모르는 것이 많아지는 것 같다. 다음 프로젝트에서는 첫 걸음을 보다 더 신중히 내딛어야겠다. 내가 개발을 그만두기 전까지 내 코드가 마음에 드는 날이 올까..

### (2) 느슨한 코드 리뷰

**`Component에서 직접 연산 하지 않는다. Component에서는 Store의 변수만 바라본다. Atomic Design 방식을 사용하여, 컴포넌트 재사용성을 최대화 한다.`** 등 몇 가지의 규칙을 정했다. 하지만, 팀원이 작업을 하며 몇 가지 규칙들을 위반해도 '**내가 다음에 고쳐서 올리면 되니까.**'라는 생각을 했다. 하지만 시간이 지날 수록 규모는 점점 커지게 되고, **약 400여개의 파일**들이 쌓이게 되니 돌이킬 수 없게 되었다. '**혹시, 나의 리뷰가 상처가 되지 않을 까?', '연차도 얼마 되지 않고, 웹 경험도 얼마 없는 내가 주제 넘은 것은 아닐까?**'라는 안일한 마음가짐으로 나는 착하고 싫은 소리 하지 않는 팀원이 되었을 지 모르지만, 우리 프로젝트는 나의 마음가짐 때문에 확장성이 없는 프로젝트가 되어갔다.

방관과 방치는 좋은 사람이기 보다, 책임감이 없는 무능력한 사람이다.

### (3) 소탐대실(小貪大失)

MobX를 사용하던 중에 한 가지 문제가 발생했다. Provider를 통하여, Store들을 하위 컴포넌트에 전달하고, Inject를 통하여 어디서든 사용할 수 있었다. 하지만, 그렇게 될 경우 **`? (Optional chaining)`** **`! (Non-null assertion)`** 와 같은 연산자를 사용해야할 경우가 생기게 된다. 이런 상황을 방지하고자, 부모 컴포넌트 부터 props들을 직접 내리는 방식을 사용하기로 결정 했다.

하지만, Atomic Design 방식도 잘못 적용 된 상황에서 해당 방식은 **무의미한 노가다**가 되어버렸다. 부모 컴포넌트 부터 props를 직접 내리는 것은 꼭 나쁘고, 무의미한 행동은 아니라고 생각한다. 다만, 내가 강조하고 싶었던 '**코드의 직관성**'은 사라지고 '**코드의 복잡성**'만 늘어나 버렸다.

나의 실력과 경험에 비하여 **이상적인 설계만 주구장창 해놓으니, 한 번 방향이 틀어져버리니 대처를 할 수 없었다.** 현재 나의 능력에서 완벽한 설계와 구현 그리고 협업은 부족하다. 할 수 있는 만큼만 냉정히 생각하고, **대신 확장성을 고려하여 추후 유지보수에 공수가 덜 들어가는 방향**을 우선적으로 생각해야겠다.

좋은 설계는 '**이후 얼마나 쉽게 코드를 수정할 수 있는 가?**'에 가장 높은 배점이 있는 것 같다.

*[이미지: App → Page → ItemList → GameItem → Input으로 이어지는 컴포넌트 트리 다이어그램. "이정도 Depth는 우스운 상황이 되어버렸다."]*

### (4) 명확하지 않은 역할

Store를 설계할 때, 어떤 데이터를 어디에 저장해야할지 감이 잡히지 않았다. **GameStore라고 하면, 어디까지 Game관련 데이터**로 취급할 것인지. **UserStore에는 게임 관련 유저 정보**만 넣어야하는 지. 등 명확하지 않아, 어디에 저장해야할지 고민되기 시작했다.

이 후, **`User/Inventory, History, ...`** 등 세분화를 시키긴 했지만 데이터의 저장 위치를 선정하는 것은 명확하지 않고, 그저 나의 주관적인 느낌에서 결정 되었다.

**API를 사용해서 받아오는 데이터는 `--Store`에**, 페이지에서 사용할 **간단한 상태 값들은 `--PageStore`**

라는 규칙을 정해버리니, 간단한 컴포넌트에서도 바라보아야할 Store가 점점 많아졌고 규칙을 만든 나 조차도 데이터의 위치를 헤맬 수 밖에 없었다. 이 부분은 아직 명확한 해결법을 찾지 못했지만 너무 세분화 된 설계는 어쩌면 더 복잡한 스파게티를 만들 뿐인 것 같다.

'**인증이 필요한가**'에 따라 API Store(가공 되지 않은 데이터)들을 만들고 '**각 페이지마다 Store**'(가공된 데이터 + UI 상태)를 만드는 것이 그나마 지금 생각나는 방법이다.

### (5) Controller

부끄러운 이야기지만 프로젝트를 진행하는 동안 Controller에 대한 생각 조차 하지 못했다. 나의 Store 설계가 어떤 파장을 일으킬지 내다볼 지혜와 경험이 없었다. 그래서 아래와 같은 **극악의 핑퐁**이 연출되게 되었다. 사실 하나의 컴포넌트 안에서 여러 스토어의 변수를 바라보는 것은 문제 없다고 생각한다. 하지만, 하나의 동작에서 여러 스토어의 데이터를 set, get을 하다 보니 **하나의 컴포넌트 소스코드의 양이 불필요하게 많아지고 있었다.**

*[이미지: 한 페이지의 버튼·리스트 컴포넌트들이 GameStore, UserStore 등 여러 Store와 화살표로 어지럽게 얽힌 다이어그램. "진짜 아차하면 사이드 이펙트 터지는거야~"]*

마일스톤 1차 종료 직전, 일부 Page Controller들을 만들었다. 모든 로직들을 Controller로 이전 시키니 Page내의 코드 줄 수가 1000줄이 넘어가는 **코드를 반 이상 줄일 수 있었다.** 가장 큰 장점은 **로직들과 UI 컴포넌트 구성을 별도로 볼 수 있다는 점**이였다. 이것을 늦게 알게 된점, 일부만 적용한 점이 아쉬웠다.

## 프로젝트 1차 마일스톤을 마무리 하며..

짧지만 많은 성장을 했기에 기뻤고, 하루하루 성장 할 수록 내 부족함들이 점점 뚜렷하게 보이기 시작해서 슬펐다.

지금의 뼈대로 새롭게 태어나, 세상의 빛을 볼지. 그 때, 내가 프로젝트에 계속 참여할지 아직 알 수 없지만 처음이여서 완벽할 수는 없었지만 그렇기에 애정이 가득한 프로젝트였다.

어떤 프로젝트를 어떤 역할로 수행하게 되더라도, 이번 회고에서 느낀 점과 회고에 적지 않은 교훈들을 되새기며 지금의 성장을 굳혀야겠다.

---

> 이 글은 [티스토리 원문](https://ryublock.tistory.com/52)(2020-09-28 발행)을 옮겨온 것이다.