본문으로 건너뛰기

개인 사이드 프로젝트 0.1ver 회고

· 약 8분

혼자 사이드 프로젝트를 진행할 때 마다 이런저런 이유로 항상 끝까지 진행하기가 힘들었다. 때문에 이번 프로젝트에서는 일단 완성하자는 마음가짐으로 빠르게 프로토타입을 만들게 되었는데, 그렇게 해서 만들어진 프로토타입에 대한 회고를 공유하려 한다. 사이드 프로젝트 깃허브 링크 🔗

예상 외의 개발 기간

"일단 만들자", "프로토타입" 이라는 말과 다르게, 시작과 끝의 기간만을 놓고 보면 약 8개월이라는 시간이 걸렸다.

환경적으로 사이드 프로젝트에 소홀해질 때가 있었는데, 먼저 회사 일이 바빠질 때였다. 회사 일에 집중해야 할 때에는 평일은 물론이고, 주말에도 회사 일을 할 때에도 있었다. 그렇다고 정말 시간이 없어서냐고 묻는다면 당연히 그렇지 않다. 하지만 회사 일에 지치다보면 퇴근 후에 노트북을 쳐다보기도 싫어지게 되고, 어려운 문제를 맞닥드려 개발이 막혔다거나, 단순 노동과 같이 개발하기 싫은 부분을 개발할 때라면 더욱 하기 싫어졌다.

개발적인 문제도 있었다. 무작정 도커를 구축하려다 실패하고, 결국 도커를 공부하고 구축하면서 많은 시간이 소요되기도 했고, ec2의 메모리 문제로 단순 빌드시간에 대한 시간소모도 상당했다. 물론 소요된 시간동안 많은 것을 배우긴 했지만, 그럼에도 조금 더 빨리 끝내고 점진적으로 버전업 시키는 방식으로 했었다면 이라는 아쉬움이 남는다.


잘 모르는 기술을 GPT로 사용할 수 있을까?

적어도 나는 그렇지 못했다. 어떻게 빌드만 하면 되겠지라는 마음으로 동작원리를 이해하지 않고 gpt에게 해줘, 해줘 만을 반복해서 시도하며 왜 안되지?를 반복했다. 하지만 계속해서 오류가 발생했고, 에러메시지를 보아도 어떻게 고쳐야 할지 몰랐다. 그렇게 한참 고생을 하고 나서야 도커를 공부하고 만들어야겠다는 생각이 들었다. docker가 어떻게 사용되는지, yaml 파일은 어떻게 만들어야 하는지, Dockerfile은 어떻게 만들어야 하는지, 이미지는 무엇이고 볼륨은 무엇인지 배우고 나서야 오류를 이해하고 해결할 수 있었다. 빨리 가려다 오히려 먼길을 돌아간 경험이었다. AI가 코드를 다 짜주는 세상이라고는 하지만, 기술에 대한 이해가 있어야만 그 기술을 사용할 수 있겠구나 싶었다.


어차피 해야 할 일이라면 일찍 끝내자

만약 개발 초기로 돌아갈 수 있다면 하고 싶은 일들이 있다. tailwindCSS 삭제, migration 추가, docker image로 배포.

매몰비용의 오류 tailwindCSS

해외 개발자들이 tailwindCSS를 많이 사용하는 것을 보고, 한번 쯤 시도해보고 싶었다. 문법에 어느정도 익숙해지니 빠른 사용이 가능했지만, 세부적인 디자인이나 상속을 할당할 때에는 코드가 지저분해지고 오히려 더 오래걸리는 느낌이 들었다. 결국 css와 styled-components와 혼용해서 사용하게 되었는데, 이럴거면 tailwindCSS를 지우는게 낫지 않나 라는 생각이 들었다. 하지만 지금까지 만든 코드들이 아까웠고, 조금만 더하면 완성인데.. 라는 마음으로 지워야할 코드들을 계속해서 만들어갔다. 지금 돌이켜보면 바꿔야겠다는 생각이 들었을 때 바로 바꿨으면 개발시간이 더 단축되었을 듯 하다.

migration 및 백업 코드 구현

잘못된 코드를 restart: always로 작성해서 aws ec2 서버가 멈추는 경우가 잦았다. 그때마다 ec2를 종료하고 재생성하면서 목업데이터를 일일이 다시 작성해야만 했다. database를 백업하고 목업데이터를 복구할 수 있는 코드를 작성해놨더라면 개발시간이 훨씬 단축되었을 듯 하다.

docker image 배포

프로토타입에서는 ec2 환경에서 docker image를 빌드하고 띄우는 방식을 사용했다. 문제는 서버를 빌드할 때 간헐적으로 cpu 100%를 찍고 ec2가 멈춰버린다는 점이었다. 안그래도 prettier로 빌드하는 데에도 한참 걸리는데, 처음에는 무슨 문제인지 몰라 빌드가 될때까지 빌드하면서 시간을 낭비했다. 만약 이전으로 돌아간다면 아예 로컬에서 빌드하고 image만 올리는 방식으로 빌드시간을 단축시킬 수 있을 것 같다.


넓게 배운 지식

우여곡절이 많았지만, 서버개발과 배포까지 한번에 진행하면서 많은 걸 배웠다. 이번 회고에 적은 것 외에도 정말 많은 것을 배우고 겪고 망쳤는데, 그동안 배운 내용들을 시리즈로 조금씩 작성해볼까 한다. 그리고 이후에 조금 더 발전시킨 프로젝트로 또다른 배우고, 겪고, 망치는 내용을 공유할 예정이다 ^ㅡ^

입사 후 첫 프로젝트 리뉴얼 회고

· 약 9분

첫 회사에 입사해서 진행한 첫 프로젝트를 약 1년이 좀 넘은 후에 리뉴얼 작업을 진행하게 되었습니다. 리뉴얼 작업을 진행하면서 저도 꽤나 버전업이 되었구나 싶은 마음이 들어, 운영과정과 리뉴얼 과정에서 느꼈던 기술적인 과정과 회고를 공유하려 합니다.

기존 투표 커뮤니티 서비스

프로젝트를 한줄로 소개하자면, 투표에 참여하면 포인트를 주는 방식의 설문 커뮤니티 기능입니다. 처음 시작할 때에만 해도, 시범적 운영이었기 때문에 워드프레스 API를 사용해서 서버팀 공수를 최소화하여 진행했습니다. 기능은 다음과 같습니다.

  1. 앱 내에서 보여주는 웹뷰로 구현 및 웹앱 인터페이스 사용
  2. 투표 참여시 포인트를 지급하며, 투표 통계 표시
  3. 워드프레스 API를 사용한 댓글 및 댓글 좋아요 기능

운영 중 수정사항

부족한 개발실력으로 처음 만들었던 서비스다 보니, 이런저런 버그가 많았는데요. 때문에 운영 중 수정사항은 대체로 초기 버그해결이 주를 이뤘습니다.

간헐적으로 발생하는 흰화면 오류

개발환경이 아닐 때 간헐적으로 흰화면만 뜨는 문제가 있었습니다. 웹앱 인터페이스를 통해 가져온 데이터로 투표를 불러와야 하는데, 웹앱 인터페이스가 실행되기 전에 투표를 불러와서 생긴 오류였습니다. 존재하지 않는 객체를 참조하여 생긴** 자바스크립트 에러로 인해 렌더링이 중단되어** 흰화면만 보여줬던 것으로, 동기적으로 실행되게 하여 해결하였습니다.

웹앱 인터페이스 비동기 에러처리

비동기 콜백으로 동작하는 웹앱 인터페이스에서 오류가 났을 때, 에러를 처리하지 못하는 문제가 있었습니다. 문제의 원인은 try catch 구문이 callback에는 적용되지 않은 것을 몰라서 생겼던 오류였습니다.

사용자 경험을 해치는 로딩속도

네트워크 환경이 좋지 않을 때, 투표 페이지를 불러오는 데 약 2초 정도의 로딩이 발생하곤 했습니다. 원인은 웹앱 인터페이스 속도로, 로딩 스피너를 넣어 해결하였습니다.


리뉴얼된 투표 커뮤니티 서비스

좋지 않았던 개발퀄리티와 별개로, 해당 프로젝트는 성공하였고 약 1년 간 운영하게 되었습니다. 그동안 점점 새로운 기능이 필요하게 되었고, 워드프레스 API의 한계로 인해 리뉴얼 작업이 필요해졌습니다.

운좋게도 입사 후 첫 프로젝트를 리뉴얼하게 되는 기회를 얻게 되었는데요. 이번 투표 커뮤니티 서비스는 서버 뿐만 아니라 프론트엔드 팀원과 함께 팀을 이뤄 진행하였습니다. 추가된 기능은 다음과 같습니다.

  • 다문항 투표 및 페이지 분할 가능
  • 정답형 투표기능 및 정답에 따른 포인트 차등지급
  • 투표 생성 시 글자 크기 및 스타일 변경 가능
  • 댓글 공감기능 세분화 및 신고 기능

이전의 과오청산을 위한 작업들

이번 리뉴얼 프로젝트에서는 기존 프로젝트 경험을 토대로 여러 개발적인 기능을 추가했습니다.

먼저 자바스크립트 오류시 흰화면을 보여주지 않도록 에러페이지를 구현했습니다. 기존에는 자바스크립트 오류가 발생했을 때, 사용자는 흰 화면을 탈출할 방법이 없어 앱을 강제종료 해야만 했습니다. 이를 해결하기 위해 에러바운더리를 사용해서 예기치 못한 오류가 발생하더라도 사용자에게 에러페이지를 보여주어 오류상황을 탈출할 수 있도록 구현했습니다.

웹앱 인터페이스 캐싱을 통해 로딩시간을 최소화했습니다. 투표 커뮤니티 서비스에서 가장 많은 시간이 소요되던 것이 웹앱 인터페이스였는데요. 리액트쿼리의 캐싱을 사용해서 웹앱 인터페이스 시간을 최소화 했습니다. 추가로, 커스텀훅을 사용해서 웹앱 인터페이스에 의존하고 있는 API를 추상화하였습니다.


그리고 리뉴얼된 개발자로서의 모습

기능 외에도 많은 부분에서 스스로 성장했다고 느낀 부분이 있었는데요. 잦은 useEffect 사용과 지저분한 상태관리를 했던 기존 프로젝트와 달리, 적절한 컴포넌트 분리와 전역상태를 통해 비교적 깔끔한 코드 구현을 하게 되었습니다.

이런 저런 오류를 겪다보니 에러처리에 대해서도 더욱 신경쓰게 되었는데요. 버그가 생기지 않도록 최대한 작업해야 겠지만, 부족한 개발실력 때문인지 그렇지 못할 때가 무조건 생기더라구요. 때문에 에러가 발생했을 때의 조치를 위한 로깅작업이나 에러페이지에 대한 개발에도 집중하게 되었습니다.

가장 큰 부분은 태도의 변화였던 것 같습니다. 당장의 문제해결에 급급했던 입사 초창기의 모습은 항상 불만이 많았습니다. 회사에도 불만이 많았고, 저 자신에게도 불만이 많았죠. 하지만 그렇게 구현했던 프로젝트를 1년간 지켜보는 모습은 썩 좋지 않았습니다. 누군가 제가 짠 코드를 볼까봐 부끄러웠고, 제가 짠 코드로 인해 발생하는 버그를 보는 것은 더 힘들었죠.

이제는 부끄럽지 않은 코드를 작성하려 노력하다 보니 조금 더 성장한 것 같아 뿌듯하네요. 미래의 제가 지금의 코드를 보면 또 아쉬울 지는 몰라도, 적어도 부끄럽지는 않을 것 같아요. 이렇게 변화된 모습을 눈으로 볼 수 있다는 것이 개발자의 가장 큰 매력 중 하나가 아닐까 싶습니다. 1년 뒤에 제가 이 포스트를 보면 어떤 기분이 들지도 궁금하네요. 1년 뒤의 제가 부끄럽지 않게 계속 성장해야겠습니다.

2022년 회고

· 약 6분

나의 2022년은 79점

벌써 2022년이 끝났다. 원하는 것을 이뤘냐고 한다면 ‘그렇다’ 지만 그래서 만족하냐고 한다면 ‘아니다’ 이다.

만족할만한 기업에 취업도 했고, 만족스러운 곳에서 자취를 시작했다. 이전과 비교하면 개발실력도 조금은 나아진 것 같다. 갖기 전에는 그렇게 갈망하던 것들인데, 막상 갖고 나니 좀 더 좋은 것이 갖고 싶다. 나의 2022년에 점수를 매기자면 79점이 딱 어울린다. 못한것은 아니지만 잘하지도 않은.

2022년의 굵직한 이벤트를 꼽자면 역시 취업이다. 4월 안에 취업을 목표로 달렸지만 이런저런 실패들을 맛보며 8월에서야 취업을 했다. 예상 개발 기간은 생각한 것의 3배라는데, 2배정도면 겸허히 받아드릴 수 있다. 0년차 개발자로서 취준기간을 돌이켜보면 꼭 필요한 기간이었다고 생각한다. 취준기간은 힘들었지만, 4개월만에 취업했다면 분명히 개발하는 것에 많은 어려움을 겪었을 것이다. 어디가서 꿀리기 싫어서 공부했던 자바스크립트도, 남들이 좋다니까 배웠던 타입스크립트도, 취업을 위해 시작했던 팀프로젝트도, 개발하는 것에 큰 도움이 되어주고 있다.

여기까지만 보면 79점이라는 점수가 너무 짜다고 느껴지지만, 문제는 취업 이후였다. 취업전에는 스터디를 들어서라도 개발공부를 하겠다는 열정은 왕복 4시간 30분의 출퇴근길을 거치며 사그라져갔고, 왕복 100분 거리의 자취방을 얻고서는 예전처럼 타오르지 않았다. 그나마 요즘들어 열정이 다시 타오르기 시작해서 개발공부를 하고 있지만, 불태웠다고 느낄만큼 열심히 하지는 않는다. 조금 멍청한 소리같지만, 번아웃이 느껴질만큼 불타오르고 싶다.


2023년의 출사표

혼자서 나만의 서비스 개발환경 구축하기

Nginx와 AWS를 사용해서 마음대로 쓸 수 있는 개인 서버를 만들고 싶다. 물론 프론트개발자로서 firebase 같은 기술을 사용해서 쉽게 구현할수도 있겠지만, 지금 회사의 개발환경과 동일한 환경을 혼자서 구축해서 백엔드까지 볼 수 있는 넓은 시야를 갖고싶다. 회사에서도 간단한 내부서비스는 스스로 구축하고 싶기도 하고, 모바일 청첩장과 같이 주변사람들을 위한 나만의 서비스를 구현해서 선물하고 싶다.

꾸준한 알고리즘 공부

알고리즘 공부를 시작해야만 한다. 취업준비를 할 때에도 제일 하기싫었던 공부였던 터라 결국은 해야만 한다는 것을 알면서도 취업 후에는 쳐다도 보지 않았다. 하지만 이제는 해야만 한다. 스터디를 열어서라도 꾸준한 알고리즘 공부를 시작하고 싶다.

더 많은 사람 만나기

‘집-회사-집’을 반복하다보니 만나는 사람만 만나게 되게 되더라. 프로그래머스 데브코스에서 소중한 인연들을 만났던 것 처럼, 여러 사람들을 만날 수 있는 일을 시작하고 싶다. 스터디도 좋고, 개발 동아리도 좋다. 더 좋은 사람이 되기 위해 더 좋은 사람들을 만나고 싶다.


고생했다 2022년, 고생해라 2023년

아무것도 안했는데 왜 2023년이야 싶었지만, 막상 돌이켜보니 생각보다 나쁘지 않게 살아왔던 것 같다. 꿈꾸던 기업에 취업했다거나 개발 고수가 되지는 못했지만, 적어도 2021년에 막연히 꿈꾸던 개발자의 삶을 모두 이뤄냈던 것처럼 2023년에도 지금 꿈꾸는 것들을 모두 이뤘으면 한다. 고생했다 2022년, 고생해라 2023년.

버그 해결 회고::명확한 근거와 코드의 흐름

· 약 9분

커뮤니티 기능을 개발하는 첫 프로젝트에서 댓글 수가 제대로 표기되지 않는 버그가 발생했다. 간단한 동기 비동기 문제였지만, 문제를 해결하면서 배운 점이 많아 남기는 회고

문제점

API 호출과 결과는 제대로 받아왔으나, DQ에 있는 모든 상태값이 렌더링이 되지 않은 상황. storage에 token값이 존재하지 않을 때 auth.api.ts에서 token을 불러오기 때문에 상황으로, 2가지 문제점이 존재한다.

먼저, initInvokeInterface()와 isLoading을 끝내는 getInitialData()가 비동기적으로 실행되어 initInvokeInterface()으로 토큰을 받아오기 전. getInitialData()가 먼저 실행되어 loading이 끝난 후 토큰을 불러오게 되는 것이다.

두번째 문제점은 getItem("token") === "undefined"일 때 에러를 반환하는 것이 동작하지 않는 것인데, getMyInfo()는 API가 아님에도 auth.api.ts 파일에 존재하여 혼란을 야기하고, 불필요한 API 에러처리를 받고 있는 것이다.

수정사항

getInitialData() 내부에 initInvokeInterface()을 넣고, 동기적으로 동작하게 하여 initInvokeInterface()이 끝나야만 setIsLoading(false);가 실행되도록 수정하였다.

또, getMyInfo()를 auth.api.ts가 아닌 utils 폴더의 getAuthData.ts로 분류하여 api와 혼동되지 않게 수정하였다.


버그 해결 일지

  • 댓글 수가 제대로 표기되지 않는 버그 수정 0으로 표시되며, 댓글 작성 혹은 삭제 시 +1, -1 적용되는 중.댓글이 안보이던 버그가 이곳에서 나타나는 것으로 추정..Recoil 값으로 나타내는 것인데, setCommentsNumberInfo이 적용되지 않아 생기는 문제로 추정.
    • useEffect시 setCommentsNumberInfo이 되지 않는 것으로 추정
    • useEffect
      1. CommentsNumberInfo에 주어지는 값을 useState로 설정하고, useEffect를 사용하여 state가 바뀔 때 CommentsNumberInfo를 바꾸도록 변경하였다.=> 해결되지 않음
      2. 댓글 API 사용을 최소화하기 위해 CommentsContainer에서 사용한 댓글 API를 recoil 전역상태값으로 저장하여 DqConetents에서 댓글api 대신 전역 상태를 사용하도록 변경하였다.=> 약 5분간 계속해서 테스트했으나 현재까지 이상없음 해결되지 않음
    • initInvokeInterface 가 수행되기 전 DqContents이 먼저 렌더링되어 생기는 문제로 추정
      1. initInvokeInterface 이후 getInitialData를 호출하도록 수정. => 20분 테스트한 결과, 댓글 수를 불러오지 못하는 에러는 발생하지 않았으나 흰화면이 나타나는 버그가 17분 쯤 발생
  • 흰 화면만 나타나는 버그 수정현재까지는 아이폰에서만 발생하고 있고, 데이터 사용시 더 자주 발생하는 오류로 추정되며, POST 정보까지는 불러오지만 댓글 갯수를 불러오는 시점에서 흰화면이 생긴다.
    • 댓글 API를 호출하다가 에러가 발생하여 생기는 문제로 추정
    • DailyQeustion에서 isLoading이 끝나지 않아
      만 보여지는 것으로 추정getInitialData 실패시 재시도하고, 3번 실패시 에러페이지 띄우도록 구현 해결되지 않음isLoading의 문제인지 확인하기 위해 로딩 이미지 임시구현 및 getInitialData에 try-catch 추가=> 여전히 해결되고있지 않으며, 로딩이미지가 보여지지 않음

회고

위 개발일지는 문제를 해결하면서 혼자 작성했던 기록이다. “추정” → 테스트 → 해결안됨 이 반복되고 있는데, 여기서 추정은 논리적인 근거를 갖고 한 것이 아닌, 문제가 생기는 부분을 보고 이것이 문제일 것이다! 라고 추정한 것이다.

부끄럽게도 내겐 익숙한 문제해결방법이었고, 이것이 잘못된 것인지 몰랐다. 하지만 이 방법에는 맹점이 아주 많은데, 일단 짚이는 것을 문제라고 확정짓고 해결하기 때문에 왜 그런 일이 발생한지를 명확히 알지못하고, 문제를 찾을 수 있다고 확신할 수 없다. 그냥 이리저리 시도해보며 운좋게 문제가 해결되기를 바랄 뿐이다.


위의 경우에도 API를 호출할 때 문제가 발생하고, 네트워크가 느렸을 때 문제가 더 자주 발생한다는 점 때문에 계속해서 API에 문제가 있을거라 추측한다. 그러나 이는 API를 호출하는 과정에서 문제가 있었던 것을 알고 보면 아주 말도안되는 추측인 것이다.

파트장님은 계속해서 이러한 해결방법이 잘못되었다고 강조하셨으며 내가 쓴 코드에 명확한 근거가 있어야하고, 코드의 흐름을 보면서 근거를 찾아야 한다고 하였다. 때문에 브레이크포인트와 로그를 찍어보며 어디서 문제가 발생하는지, 그리고 문제가 발생한 원인과 흐름을 찾아 해결해야한다고 하였다. 눈에 보이는 문제가 나타나는 API 혹은 라이브러리보며 '이게 왜안돼?' 하며 짜증내는 것이 아니라 논리적, 그리고 객관적으로 문제가 생길 수 있는 곳을 찾아 해결해야 한다는 것이다.


누군가 좋은 디버깅이 무엇이냐 하면 말할만큼 누구나 말하는 좋은 디버깅이고 개발방법이지만, 나는 전혀 지키고 있지 않았다. 하지만 확신을 갖고 차분히 문제를 파악하고 해결해나가는 과정이 개발 실력이자 개발 철학이 아닐까 싶다. 그리고 파트장님은 이런 개발 방법을 내게 심어주기 위해 API, 리코일 탓이라고 헛짚는 나에게 계속해서 왜 이것이 문제라고 생각하는지 명확한 근거를 가지고 자신을 설득시켜보라고 했던 것이다.

그리고 문제가 해결되었을 때, 다시 한번 자신의 코드에 명확한 근거를 가지고 개발하는 것이 중요하다는 것과, 쉽게 읽을 수 있는 플로우를 가진 개발을 할 수 있도록 노력해야 한다고 하셨다. 내가 하루아침에 완벽한 흐름을 갖는 코드를 짜고 디버깅을 할수는 없겠지만 그렇게 할 수 있도록 계속해서 노력하려한다. 많은 기술을 알고 쓰는 것보다 이런 개발철학을 확고히 한 사람이 잘하는 개발자가 아닐까? 그리고 이런 개발철학을 남에게 알려줄 수 있는 사람이면 더더욱.