평범한 3년차 개발자의 회고글

HyunHo Lee·2024년 12월 16일
57

회고

목록 보기
3/3
post-thumbnail

개발자가 된 이유

나는 학점을 잘 받는거에 집중하는 평범한 대학생이었다. 컴퓨터 관련 학과를 전공했어도, 취업의 길은 다양했기에 개발자만을 꿈꾸지 않았다. 그렇게 시간은 어느새 4학년 1학기가 끝나가고 있었고, 곧이어 개발자를 목표로 삼은 계기를 마주하게 된다.

4학년의 마지막 학기를 인턴으로 대신할 수 있는 제도가 있었다. 인정해주는 학점 자체체는 적었지만, 1학년때부터 성실하게 학점을 꽉꽉 채워 들어서 인턴에 도전해볼 수 있었다. 평소에 재밌게 공부했던 전공 중 하나인 개발 분야로 지원했고, 서류 및 면접 전형 끝에 풀스택 개발자로 합류하게 되었다.

회사에서 실제 업무를 맡기지는 않았지만, 여러가지 미션들을 수행하며 발표하는 것이 업무였다. 실무를 접해본다는 생각으로 최선을 다했다. 그 결과 채용 전환 오퍼가 왔지만, 더 체계적으로 웹 개발을 준비해보고 싶다는 생각에 다음을 기약했다.

이후로는 프론트엔드 개발에 몰두하게 된다. 백엔드에도 흥미가 있었지만, 프론트엔드 개발은 취미생활 하는것 만큼 시간이 잘갔다. 백엔드가 없으면 서비스가 없고, 프론트엔드가 없으면 서비스를 이용할 수 있는 유저가 없다는 말이 있다. 유저가 사용하기 쉬운 UI/UX를 구성하기 위해 기획 및 디자인과 소통하고, 유저에게 더 좋은 경험을 선사하기위해 최적화를 하며, 백엔드 개발자와 합을 맞춰나가는 과정이 즐거웠던 것 같다.

처음에는 혼자 이것저것 만들어 보기도 하고, 협업을 해보고 싶어서 팀 프로젝트에 참여도 했다. 지식이 부족한거 같으면 T짜 공부법을 위해 여러 아티클이나 개발 서적을 읽었고, 나중에는 웹 개발에 대해 가장 기본적인 부분 부터 기초를 탄탄하게 다져보자는 마음에 부트캠프도 참여했다.

본격적으로 실무를 하기 위한 준비가 되었다고 생각한 시점부터, 여러 회사에 지원하기 시작했고, 스타트업에서 6개월동안 근무하다가 현재 회사에 합류했다. 그렇게 이 팀에 합류한지도 벌써 2년이란 시간이 흘렀다. 1년이 되는 시점에서 작성했던 평범한 주니어 개발자의 회고글에 이어서, 오늘은 두 번째 회고글을 소개해보겠다.


새로운 목표

우리 서비스의 비지니스 도메인은 MMP, CDP, CRM 등의 이름으로 불린다. 처음에는 이 단어들이 낯설게 느껴졌다. 심지어 내부에서 사용하는 세세한 용어들은 더 어려웠고, 기능도 많았으며 복잡했다. 입사했을 당시에는 적응하는데 어려움을 겪었지만, 유지보수 및 다양한 기능들을 붙이며 적응하고, 여러 방면에서 성장하기 위해 노력하며 이겨냈다.

그렇게 1년이라는 시간이 흐르고, '신규 프로젝트'가 팀의 목표로 부상했다. 기존 서비스에서는 많은 비지니스 도메인을 포함하고 있어, 도메인간 경계가 모호해지는 현상이 있었기 때문이다. 우리는 신규 프로젝트를 이용하여 비지니스 도메인들을 명확하게 분리하기로 결정했다. 이로인해 각각의 비지니스 도메인 성격에 맞게 고도화할 수 있고, 유저에게 더욱 편안한 UI/UX를 제공할 수 있다.

리더분들이 규모가 큰 프로덕트를 처음부터 설계해볼 수 있다는 것은 행운일 수 있다고 말했다. 나도 이 말을 어느정도 공감했다. 보통 회사에 입사하면, 이미 만들어져 있는 프로젝트에 합류하는 경우가 많다. 이것은 신규 입사자가 시도해볼 수 있는게 한정적이라는 의미이기도 하다. 또한, 새로운 서비스를 만들더라도 규모가 작거나 유저의 수가 적다면, 큰 규모의 서비스에서 경험할 수 있는 여러 상황들을 마주치지 못할 수 있다. 이 모든 것들을 경험해볼 수 있다는 사실은 큰 기대가 되었다.

우리 팀은 새로운 프로젝트를 위해 많은 고민을 했다. 컨벤션부터 디자인 패턴이나 CI/CD 등 다양한 주제에 대해 토론하며, 프로젝트를 어떻게 구성할지 하나하나 결정했다. 지금 생각해보면, 최근 1년 동안은 새로운 것들을 많이 시도해볼 수 있었다. 이제 어떤 일들을 경험했는지 소개해보겠다.


디자인 시스템 (feat.디자인 토큰)

기존 서비스인 1.0 프로젝트에서는 디자인 시스템이 존재하지 않았다. 그 결과 거대해진 프로젝트를 유지보수 하는것이 점점 어려워졌다. 우리팀은 2.0 프로젝트에서 이와 같은 문제점을 해결하고 싶었고, 가장 먼저 구상했던 것이 디자인 토큰을 이용한 디자인 시스템이다.

일반적으로 이야기하는 디자인 시스템에서 한 단계 더 나아가, 스타일적인 요소를 디자인 토큰으로 관리하는 방법을 채택했다. 이 방식의 장점을 조금 과장해보면, 서비스의 전체적인 UI를 새로운 컨셉으로 변경하고 싶은 경우 디자이너가 토큰의 값만 변경하면 된다. 실제로는 당연히 개발자의 컨펌을 받지만, 더 유연하게 스타일을 변경 및 관리할 수 있다. 또한, 디자이너가 토큰을 관리하는 주체이기 때문에, 업무적으로 관심사의 분리가 되었다고 볼 수 있다.

처음에는 디자인 토큰을 모든 곳에 적용하는 것이 목표였다. 하지만 실제로 프로젝트에 적용하다 보니, 지나친 토큰 분류로 인해 복잡성이 증가했다. 특정 상황에서만 사용되는 UI까지 디자인 토큰으로 관리하는 것이 혼란을 가중시킨 것이다.

모든 곳에 디자인 토큰을 적용하는 것은 투자한 시간에 비해 비효율적이라는 사실을 깨달았다. 이후에 우리 팀은 레이아웃, 컴포넌트, 폰트, 그리드 시스템공통으로 사용하는 곳에서만 디자인 토큰을 통한 디자인 시스템을 관리하기로 결정했다. 이 주제가 관심있다면, 디자인 토큰으로 설계하는 디자인 시스템을 확인해보자.


Micro FrontEnd Architecture (feat.Monorepo)

우리 팀은 DX(개발 경험) 향상에도 집중했다. 갑자기 개발 경험을 향상시킨다고 하면, 와닿지 않을 수 있다. 그냥 쉽게, 개발하면서 불편했던 경험을 생각해보면 된다. 우리팀의 경우에는 모놀리식 프로젝트의 규모가 커지면서 발생하는 문제점들이 있었다.

  1. 아무리 디렉터리 구조를 잘 나누어도, 파일들이 많아 복잡해보임
  2. 특정 부분만 개발하더라도, 전체 프로젝트를 실행 해야함
  3. 특정 부분만 수정하더라도, 전체 프로젝트를 배포 해야함

이 상황들을 효과적으로 해결할 수 있는 방법은 MFA라는 결론에 도달했다. 마이크로 앱을 성격에 맞게 관심사 분리함으로써 프로젝트 구조에 가독성이 증가하고, 개발하고 싶은 부분에 연관된 마이크로앱들만 실행하며, 특정 마이크로앱만 배포도 가능하기 때문이다. 핫 모듈도 빠르게 돌기 때문에, 커다란 규모의 프로젝트 환경에서 개발한 사람들은 더욱 체감이 된다. MFA 구성 방식을 결정하는 과정들은 주도적으로 설계하는 MFA에서 만나볼 수 있다.

마이크로 프론트엔드가 모놀리식보다 좋다는 개념이 아니다.
우리의 서비스와 MFA의 궁합이 잘 맞는것 뿐이다.

해당 아키텍쳐 특성에 의해 발생하는 불편함도 있다. 마이크로 프론트엔드는 분산된 독립성을 강조하지만, 가끔은 통합 작업이 불가피한 경우가 있기 때문이다. 10개의 마이크로앱을 만들었다고 가정하자. 각 마이크로앱은 독립적인 개발 서버, 빌드 환경, 런타임 환경을 가진다. 하나의 마이크로앱은 하나의 SPA라고 봐도 무방하다. 만약 모놀리식 프로젝트처럼, 모든 마이크로앱이 연결되는 개발 서버를 동작시키고 싶은 경우 10개의 SPA를 실행해야 한다. 컴퓨터가 고통스러워하는 것을 볼 수 있다.

또 다른 어려움도 존재한다. 이 아키텍쳐를 선택함으로써 기본적인 환경 구성에도 많은 고민이 필요하다는 것이다. 스토리북으로 예시를 들어 보겠다. 초반에 나는 마이크로앱에 스토리북을 종속시켰다. 각각의 마이크로앱에서 개발하는 컴포넌트는 해당 마이크로앱의 스토리북에서 관리하겠다는 의미였다.

여기서 하나의 이슈가 생긴다. 공통 컴포넌트를 관리하는 마이크로앱이 있다고 가정하자. 이 마이크로앱의 컴포넌트인 TagA라는 마이크로앱의 StatusTag 컴포넌트에서 사용한다. 이제 A 마이크로앱의 스토리북에 StatusTag 컴포넌트를 등록하면 정상적으로 출력되지 않는 것을 볼 수 있다. 우리는 프로젝트의 MFA를 구성한 것이지, 스토리북에서는 해당 아키텍쳐가 고려되지 않았기 때문이다.

그래서 가장 먼저 했던 접근은 스토리북의 웹팩에서도 Federation을 구성하는 것이었다. 하지만 이 방법은 완벽하게 동작하지 않았으며, 관리의 복잡성도 증가했다. 다음 방법으로 마이크로앱에 종속된 스토리북에서 다른 마이크로앱의 컴포넌트들도 import 될 수 있는 구조를 설계했다.

정상적으로 동작하고 복잡성도 없었지만, 디자이너 및 기획자가 확인하기 불편하다는 문제점이 생겼다. 10개의 마이크로앱이 있다면, 스토리북의 배포 주소도 10개가 나오기 때문이다. 그래서 한 가지의 주소에서 모든 컴포넌트들을 확인할 수 있는 체계를 만드는 것으로 마무리를 지었다.

이렇게 간단한 스토리북 셋팅 조차도 여러 시도를 통해 구성되었다. MFA에서 원하는 형태를 얻기 위해서는 직접 다양한 방법으로 시도해보면서 해결해야 한다는 어려움이 있는 것이다. 가끔은 레퍼런스가 없어, 창작을 하는 경우도 있다. 이럼에도 불구하고 MFA를 선택한 것은, 잘 구성하기만 하면 장점이 명확하기 때문이다. 나중에는 1년이란 시간동안 진화한 MFA에 대해서도 다루어보겠다.


공통 컴포넌트

  • 체크리스트
    • MFA 고도화 및 셋팅
      • 유지보수 및 DX를 향상시키기 위한 고도화
      • 각각의 마이크로앱에서 사용하는 라우터 통합
      • 다른 마이크로앱의 타입 참조 구조
      • MSW와 테스트 셋팅 등등..
    • 배포 전략
      • CI/CD
      • 버전 전략
    • 공통 요소
      • 라우터 구조 및 네비게이션 가드
      • 모델 추출 구조
      • 로그인 로그아웃 구조
      • 컨벤션 문서화 등등...

이후에는 앞으로 해야할 목록에 대한 체크리스트를 만들었다. 당장 필요한 항목부터 리스트업 했음에도 초기 개발 특성상 할 일이 많았다. 그래도 다행인점은 나에게 든든한 동료들이 있었다. 바로 역할 분담을 했고, 각자 맡은 임무를 수행했다. 담당한 주제에 대해 결정이 필요한 부분이나 공유하고 싶은 정보들이 있는 경우에는 회의실에서 토론을 통해 해결했다.

주제 하나 하나가 모두 커다란 요소이기 때문에, 모든 항목에 대해 소개하기보다는 공통 요소에 대해 다루어보겠다. 공통 요소에는 헬퍼 함수, 컴포저블(리엑트로 치면 커스텀 훅), 레이아웃 컨테이너, 공통 컴포넌트 등 다양한 요소들이 있다. 그 중에서도 가장 기억에 남은 것을 뽑으라면 공통 컴포넌트 중에서 역할에 맞는 테이블과 데이트피커이다.

테이블 컴포넌트는 서버 혹은 클라이언트라는 역할에 맞게 설계하는것이 핵심이었다. 그 후에는 가장 기본적인 기능인 정렬 , 다중 정렬을 구현했다. 테이블에서 보고싶은 컬럼만 노출시킬 수 있는 기능인 컬럼 설정에서는 새로운 컬럼이 추가되거나 삭제된 경우 로컬스토리지를 어떤식으로 초기화를 해줄지와 내부 상태와 로컬스토리지 정보를 어떻게 싱크를 맞출지 고민하며 설계했었다. 지금은 테이블에 출력하는 데이터 타입에 맞는 필터링까지 제공하고 있다.

데이트 피커는 설계해본 경험이 없기도 했지만, 일반적인 데이트 피커보다 요구사항이 많고 복잡했다. 이 경험으로 요구 사항 문서를 작성하는것이 매우 중요하다는 것을 깨달았다. 컴포넌트를 설계하기 전에, 세세하게 분석하여 실제로 구현한다는 생각으로 요구 사항 문서를 작성해나가는 것이 효과적이었다. 처음부터 유지보수하기 좋은 코드와 효율적인 구조로 설계할 수 있고, 요구 사항 문서에 투자한 시간이 아깝지 않을 정도로 개발 시간을 아껴주기도 한다. 데이트 피커 주제는 이미 작성하던 글이 있어서, 추후에 새로운 글로 소개하겠다.

과거에는 컴포넌트 명확성 및 재사용성을 극대화하기 위해 단일 책임 원칙을 지킨다거나, 접근성과 표준 준수하여 키보드(Tab)와 스크린 리더를 고려한다거나, 조금이라도 효율적인 코드를 작성하기 위한 노력 등의 고민 위주로 했다. 이번에 공통 컴포넌트를 설계하면서, 한가지 더 중요한 사실을 깨달았다. 바로 동료 개발자가 사용하기 쉬운 컴포넌트를 만드는 것이다. 동료 개발자가 직관적으로 이해가 가능하여, 추가적인 학습 비용이 들지 않도록 하는 것이 좋다. 잘 설계된 공통 요소는 동료 개발자의 시간을 아껴준다. 그 결과 팀의 목표에 더 빠르게 도달할 수 있게해준다. 사용하기 쉬운 컴포넌트는 어떻게 만들까?

공통 요소에서 가장 중요한 것은 명확하고 직관적인 API를 제공해야 한다. 이름만 보고도 기능을 추측할 수 있도록 설계해야 한다. 예를 들어, size="large"는 누가봐도 컴포넌트의 크기를 결정하는 기능이라는 것을 알 수 있다. 또한, 일관된 패턴으로 설계해야 한다. A컴포넌트에서는 sizelarge인데, B컴포넌트에서는 big인 경우 혼란을 줄 수 있다. 이와 같이 일관성 없는 컴포넌트가 많아지면, 동료 개발자는 컴포넌트를 사용할때마다 size라는 간단한 기능을 사용하더라도 props값을 확인해야 할 것이다.

현재 화면에만 딱 맞게 만드는 것은 피하는게 좋다. 확장성을 고려하면서 설계하면, 기획 및 디자인에서 유사한 기능이 나오더라도 유연하게 대처하여 시간을 아낄 수 있다. 한 가지 주의할 점은 시간은 한정적이기 때문에 모든 확장성을 고려하면 안된다는 것이다. 확장성과 시간을 두고 줄타기가 필요하다.

이 외에도 에러 핸들링, 테스트, 스토리북은 통한 문서화 및 시나리오 구성도 중요한 요소이다.

확장성은 만들고자 하는 요소의 성격에 따라 범위가 상이하다. 나는 다양한 컴포넌트들을 만들어보고, 실제로 동료 개발자들과 여러 부분에서 사용하면서 받은 피드백으로 어느정도 감을 잡았다. 경험 외에도 솔리드 원칙에 대해서 더 고민해보거나 UI 라이브러리들의 문서 및 내부 코드들을 보는 것도 도움이 되었다.


마무리

위에서 소개한 작업들과 별개로, 유저들에게 제공할 서비스의 기능들을 만들어가고 있다. 2.0 프로젝트를 통해 새로운 기술들를 시도해보는 것도 좋았지만, 아예 처음부터 모든 기능들을 만들다 보니 어려웠던 비지니스 도메인의 디테일한 부분들을 이해할 수 있어서 매우 좋은 경험인 것 같다. 이제 곧 2.0 서비스를 고객들이 사용할 예정인데, 내년은 더 재미있고 힘든 해가 되지 않을까 싶다. 완성도 높은 프러덕트를 제공할 수 있도록 파이팅 해야겠다.

profile
함께 일하고 싶은 개발자가 되기 위해 달려나가고 있습니다.

5개의 댓글

comment-user-thumbnail
2024년 12월 25일

The most important thing about common elements is to provide a clear and intuitive API. It must be designed so that the function can be guessed just by looking Block Blast at the name. I am very interested in this issue of yours.

답글 달기
comment-user-thumbnail
2024년 12월 29일

수고 많으셨습니다!

답글 달기
comment-user-thumbnail
2025년 2월 13일

If you’re seeking companionship, Escort in Mahipalpur the options available are diverse and tailored to your needs. The experience is always smooth and enjoyable.

답글 달기
comment-user-thumbnail
2025년 2월 27일

cxzcxz

답글 달기