화해팀 입사 3개월차, 프론트엔드 기술 기반 다지기

안녕하세요. 화해팀 입사 3개월차이자 프론트엔드 개발을 담당하고 있는 박제훈 입니다.


새로운 환경에 적응하며, 동시에 화해 개발팀이 일하는 방식을 배워나가고 있는데요. 화해팀 입사 후 3개월 간 제가 어떤 식으로 업무 목표를 설정하고 진행해 왔는지 또 그것이 프론트엔드 업무 환경 개선과 기술 기반을 다지는데 어떤 의미가 있었는지에 대해 소개해 드리고자 합니다. 

 

 

화해 개발팀과 플랫폼 그리고, 밴드                                                       

 

우선, 화해 개발팀은 프론트엔드, 안드로이드, iOS, 백엔드, 데브옵스, 정보 보안 6개의 플랫폼으로 구성되어 있어요. 

 

 

< 화해 개발팀과 밴드 구조>

 

 

그리고, 이와는 별개로 사용자 경험 및 서비스 품질 강화와 비즈니스 목표 달성을 위해 다양한 파트가 ‘밴드’라는 크로스 펑셔널팀(Cross-Functional Team)을 이뤄 함께 일하고 있습니다.  밴드에는 개발자를 비롯한 기획자, 디자이너 등 다양한 직무 담당자가 모여 함께 협업하고 있어요. 

 

이처럼 밴드에 소속되어 개발을 하면 각 밴드의 목표 달성에 있어 효율적인 장점이 있는 반면, 각자 여러 밴드로 나눠져서 개발을 진행하다 보니, 개발 내용을 공유한다고 해도 프론트엔드 플랫폼 관점의 협업 보다는 밴드의 목표 달성에 초점이 맞춰지는 경우가 많았어요. 그로 인해 프론트엔드 플랫폼 기술을 고도화 시켜나가는 부분은 상대적으로 아쉬움이 많을 수 밖에 없었습니다. 

 

그런데 최근 프론트엔드 플랫폼은 기술 기반 구조를 마련하기 위해 밴드로부터 전원 분리되어 별도의 플랫폼으로 일을 하게 되었어요. 그래서 그동안 아쉬웠던 부분을 보완해 나갈 수 있는 환경이 마련되었습니다. 

 

 

 

 

OKR로 업무 목표 설정 하기

 

화해팀은 전사 목표 달성 체계로 OKR(Objectives and Key Results)을 사용하고 있어요. 이를 통해 조직의 목표와 팀, 밴드의 목표를 align 시키고 있습니다. 화해팀에 입사하게 되면, OKR에 대한 설명과 함께 본인이 팀, 회사의 목표 달성에 기여할 수 있는 개인 OKR을 각자 자율적으로 설정하게 됩니다. 저는 OKR의 Objective를 ‘프론트엔드 기술을 지속적으로 성장시켜 나가는데 꼭 필요한 기반을 다지는 것’으로 설정했습니다. 제가 설정했던 OKR을 간략히 설명드리면 아래와 같습니다.

 

 

 

 

입사 초기에 작성했던 KR을 다시보니 두루뭉술하게 작성한 것 같아서 반성하게 되네요. 

 

이 당시 제가 의도한 것은 1. 공동 개발 환경 마련 2. git 전략 수립 및 javascript, typescript 컨벤션 정의 3.  lint 활성화 였습니다. 

 

 

 

 

Objective와 이를 달성하기 위한 KR(Key Result)

 

Obj 1. 프론트엔드 플랫폼 개발 환경에서 협업을 위한 기반을 마련한다.

KR 1. 1차 컨벤션 확립 및 컨벤션 문서 작성

KR 2. 컨벤션에 따른 lint 룰 정의

KR 3. pre-commit 단계에 lint룰 적용

 

목표인 Objective를 설정하고 나면, 이를 달성하기 위한 구체적인 지표이자 결과인 Key Result를 설정하게 됩니다. 프론트엔드 플랫폼은 모두가 Git을 사용하는 환경이지만,  Javascript 컨벤션 등을 밴드 내 환경에 맞춰서 사용하고 있었습니다. 그래서 밴드의 타 플랫폼 분들과 같이 사용하는 프로젝트의 경우에는 그 룰을 따라가되 프론트엔드 플랫폼 내에서만 작업하는 환경은 별도로 정의하고 사용하는 게 필요했습니다. 이를  위해 저는 우선 Git의 전체적인 사용 전략부터 제안했습니다. 

 

 

KR 1. 1차 컨벤션 확립 및 컨벤션 문서 작성

  • Git strategy

git의 전체적인 사용에 대해 프론트엔드 플랫폼 동료들과 약 2주 정도 논의를 진행했습니다.

 

 

 

 

 

  • Git 환경 구성

Open source 기여 시 많이 사용하는 방법 중 하나인 Forking workflow를 팀원들에게 소개하였습니다. 간략하게 요약하자면, Upstream 이라 불리는 메인 저장소의 Develop, Master와 같은 작업 Branch는 오로지 Pull Request merge만을 통해 push가 가능하고, 각각의 Pull Request는 협업자들이 Upstream 을 Fork한 Origin 저장소의 Branch에서 보내는 방식입니다. 보통은 메인 저장소에 직접 Push 권한은 다 막아버리는 방식을 취하는데 현재는 적응 기간이라 작업 Branch를 제외한 Branch에 대한 푸시는 허용 가능하도록 설정하였습니다.

 

이 방식의 장점은 개인 작업용 Branch를 팀과 소통하지 않고도 Fork된 저장소에 자유롭게 만들어서 사용할 수 있고, PR만으로도 저장소에서 팀원간 소통이 가능하기 때문에 메인 저장소는 비교적 필요한 것들만 포함해 관리가 용이합니다. 그에 반해 개발/운영 Branch에 직접 Push 권한이 없어서 Git 사용시 다소 번거로울 수 있다는 단점이 있습니다.

 

기본 설정은 아래와 같이 합니다.

 

 

 

 

 

  • Git flow

기존에 밴드에서 사용하던 Git 전략도 Git flow를 사용하거나 이와 유사한 방식으로 사용했기 때문에 몇 번의 논의 끝에 Git flow를 그대로 사용하기로 했습니다.

 

  • PR & Commit message

Commit 메시지는 그동안 큰 규칙 없이 JIRA의 스마트 커밋이나 그 외 자율적으로 쓰는것으로 보여 팀 내부에서 통일성 있게 사용하기 위해 Conventional commit(https://www.conventionalcommits.org/en/v1.0.0/)을 저희가 쓰기 편한 형식으로 고쳐서 사용하는 것을 제안했습니다.

 

 

 

 

1, 3줄 최대 글자수 제한인 50/72와 같은 룰은 팀원 분들이 익숙하게 쓰게 될 때까지 아직은 보류 상태이고, 대 오픈소스의 시대에 맞춰서 오픈소스 Contributor 준비 겸 메시지를 영문으로 작성하는 것을 제안하였으나, Type만 정확하게 쓰면 나머지 요약 한줄은 한글로 써도 되기 때문에 요약 부분은 자율적으로 쓰는 것으로 논의를 마쳤습니다. 그럼에도 불구하고 다들 영어로 잘 써주시고 계시네요 🙂

 

먼저 실제 저장소에 적용하기 전에 학습용으로 사용할 저장소를 만들고 여기에 위 메시지 규칙들을 적용해 보았습니다. 그리고 메시지에 대한 룰을 논의 하다보니 자연스럽게 Pull Request에 대한 논의도 같이 이루어졌습니다. 

 

PR은 아래와 같이 하도록 약속 하였습니다. 아직은 규칙을 만들어가는 중이기 때문에 조금은 유연하게 정의하였습니다.

 

 


하나의 PR은 되도록 하나의 JIRA 티켓 작업만 진행한다.

  1. PR은 티켓과의 연결이 필수는 아니지만, 되도록 하나의 목적을 가질 것을 권장한다.
  2. 하나의 PR에 여러 Commit이 포함될 경우 목적만을 명시한 한 개의 Commit으로 Squash하고,  Squash 되는 기존의 커밋들의 메시지는 Conventional Commit 룰을 따르지 않아도 상관없다. (즉 Commit이 여러 개일 경우,  메시지 작성에 제약이 없다.)
    Squash merge 시점의 메시지는 반드시 Conventional Commit 룰을 따른다.
  3. 하나의 PR에 한 개의 Commit이 있을경우 Rebase merge를 한다.

 

 

3번의 Squash Merge룰은 필수로 하였는데 이것은 Type을 Feat과 Fix 등의 목적으로 명시해서, Commit  메시지만 보고도 해당 Branch에서 작업된 내용이 어떤 작업인지 쉽게 파악하기 위함입니다. SemVer 관리 측면에서도 Commit  메시지만으로 Feature와 Fix가 분류가 되는 이점을 가져올 수 있습니다. 추가적인 자세한 내용은 JIRA 티켓 번호를 명시하기 때문에 [커밋은 요약, Squash 내용은 Description에, 상세한 내용은 티켓에]와 같은 룰을 적용하였습니다. 현재 티켓을 에픽과 태스크, 서브 태스크만을 사용하여 위 룰만으로 커버가 가능한데 스토리 등의 티켓과 연동 되는 경우는 PR룰을 조금 더 확장할 계획입니다. 그 결과 현재 아래와 같이 작업되는 내역을 PR단위로 한 줄씩 흐름에 따라 읽을 수 있도록 하였습니다.

 

 

 

 

마지막 컨벤션 문서 작성은 입사 초 컨벤션을 작성하게 될 것이라고 생각하고 KR에 포함시켰는데, 아래 후술할 Preset 모음으로 대체되어 기반 문서만 작성하다 홀딩되었습니다.

 

 

KR 2. 컨벤션에 따른 Lint 룰 정의

 

  • Convention

컨벤션은 그 룰만 잘 정의가 되어있다면 작업자들의 불필요한 의사소통을 줄여줄 수 있는 좋은 약속입니다. 이미 Lint 적용 및 자동화는 프로젝트 진행 준비 단계에서 필수 요소라 해도 과언이 아닐 정도로 기본 환경으로 많이 설정하고 있습니다.

 

Lint룰에 대해서 논의를 할때 프론트엔드 모든 팀원들이 정해진 Lint룰을 적용해 본 후, 만약 작업에 비효율이 생긴다면 그때 하나씩 없애는 것을 논의해 보기로 했습니다. Type Checking은 되도록 Typescript만을 사용하되 Nodejs를 사용하거나 하는 부분은 유동적으로 Javascript로 가져가기로 했습니다. 그래서 비교적 많이 쓰이는 Preset들을 조합하여 아래와 같이 사용하고 있습니다. 

 

 

 

 

KR 3. Pre-commit 단계에 Lint룰 적용

 

  • Lint with husky & Lint-staged

Prettier 는 Code Formatter입니다. Lint룰을 적용하면 적용가능한 부분은 자동으로 Formatting이 됩니다. Prettier 설정은 각각의 IDE에 맞는 Local Setting 작업을 하여 독립적으로 적용하고, 이미 많은 오픈 소스 프로젝트들이 기본적으로 사용하고 있는 Commit Hooking 라이브러리 Husky 를 이용하여 Commit 파일들의 Lint를 확인하는 방식을 적용했습니다.

 

필요한 NPM 패키지를 설치하고 아래 옵션만 Package.json 에 설정하면 됩니다. Prettier 및 Husky 공식 문서가 잘 되어있기도 하고 이미 많은 가이드가 있기에 저희가 설정한 방법만 기술하고 자세한 내용은 패스했습니다 🙂

 

 

 

 

아직 Lint에 대한 이야기가 많이 나오지 않고 있어서 Disable된 룰들이 몇 개 없습니다. 다음 작업으로는 Conventional Commit 메시지에  Lint 적용을  논의하고 있습니다.

 

 

  • Monorepo

이렇게 프론트엔드 개발 환경을 만들어 나가다 보니 OKR에 설정하지 않았던 것 중 필요한 부분이 생겼습니다. 제가 합류했던 시기에 우연히 두개의 신규 프로젝트가 동시에 시작되었는데 두 프로젝트 모두 기반 기술 스택이 매우 유사하게 사용되는 프로젝트들이었습니다.

 

이런 경우, 컴포넌트는 어떻게 분류할까요?
data fetching은 무엇으로 할까요? state 관리는 무엇으로 할까요?
테스트는 어떻게 할까요? 배포는 어떻게 할까요?

 

결국 진행 시점에 동시에 몇  개를 제외하고 거의 동일한 환경의 프로젝트 두 개가 다른 저장소에서 별도로 작업이 진행되었습니다. 그중 한 프로젝트는 이미 진행이 조금씩 되고 있던 프로젝트였는데 Monorepo로 Migration하도록 제안하였고(거의 새로 만들었습니다 TT), 제가 2개월이 되는 시점에 거의 안착된 것 같습니다.

Mono Repo로 구성을 제안했던 이유는 아래와 같습니다.

 

 

 

 

Service A와 Service B는 동일하게 React를 사용하기 때문에 거의 대부분의 코어 라이브러리가 유사하게 사용됩니다. A 개발자는 Service A의 Data Fetching 로직 때문에 관련 부분을 구현하려던 중이고, B개발자와 C 개발자는 Service B를 진행하는데 마찬가지로 동일한 Data Fetching 로직을 구현할 예정입니다. 이때 저희는 플랫폼 스탠드업 미팅에서 관련 이슈를 논의 합니다. 

 

A 개발자는 구현이 완료되었고 곧 개발자 B, C는 해당 부분을 구현할 예정입니다. 로직이 어느 정도 작성된 상태이고, 원하던 기능도 동일한 반면, 서비스는 각각 다른데요. 그렇다면, 복사를 해서 가져와야 할까요? 이 상황은 Monorepo로 구성하여 서로 공통 모듈은 참조해서 사용하면 쉽게 해결 가능합니다.

 

React와 Swr과 같은 특정한 프레임워크 혹은 라이브러리에 공통 로직이 존재할 때 기반 이슈에 대한 이해도를 높이고, 로직을 공유해서 공통적으로 사용한다면, 학습 측면이나 기술 내재화 측면에서도 이점이 있다고 생각했습니다. 관리적인 측면에서도 만약 메인 관리자가 한 명일지리도, 문제 발생시 다른 사람들의 서포트가 유연하게 가능하다고 판단되어 사용에 대해 적극적으로 제안하였습니다. 마침 프로젝트 환경 설정도 유사했고요. 기반 설정은 Lerna로 골격을 잡아주고 Yarn의 Workspace 기능을 활용하여 패키지 관리를 하는 방식을 활용하였습니다.

 

현재는 Component와 React-Hooks 두 가지 모두 사용하는 것을 고려 중인 상태이고 이후에 배포 및 버저닝 정책이 TODO 작업으로 남아있습니다.

 

 

Obj 2. 프론트엔드 플랫폼 개발시 사용되는 제네럴 컴포넌트 개념 확립

KR 1. 신규 프로젝트에서 사용하는 Component를 Design System으로 제안 및 storybook 환경 구축 및 배포한다.

KR 2. 제품 디자인팀에서 정의한 Design system을 적용하여 추가한다.

 

두 번째 Objective는 컴포넌트 개념 확립에 대한 것이었습니다. 이는 화해팀의 기존 OKR을 파악하던 중 디자인 팀에서 진행 중인 디자인 시스템 과제나 개발팀의 과제들을 보고 신규 프로젝트를 진행한다면 이번 기회에 팀원 분들과 개념적으로 정리하면 좋을것 같아서 진행해보았습니다. 개발 및 커뮤니케이션 효율성을 위해 컴포넌트 개발시 많이 사용하는 Storybook을 활용했고, 마침 이 부분에 대해 팀원 분들의 선행 학습이 되어 있는 상태라 순조롭게 진행되었습니다.

 

 

 

 

이 부분은 아직 Storybook 6.0 적용이나 mdx 활용 여부, Atomic design system에 대한 논의가 내부적으로 지속적으로 진행되고 있고 sketch, zeplin sdk를 이용한 SVG Icon component Auto Generating , Color Style Acss Auto Generating , Hygen을 활용한 컴포넌트 Code Generating 같은 자동화에 맡길 부분들은 지속적으로 스크립팅 작업 진행 중이라 조만간 다음에 조금 더 상세하게 다루고자 합니다.

 

 

화해 개발팀에 오시면, 이렇게 OKR을 기반으로 개인, 팀별 과제를 수행하며 그 과정에서 유의미한 결과물을 만들어 가실 수 있어요. 화해 개발팀 그 중에서도 프론트엔드 플랫폼은 보다 나은 기술 구현을 위해 앞서 말씀드린 것처럼 새롭게 기반을 다져가는 작업을 하고 있습니다. 저 역시 지난 3개월, 과제를 수행하고, 동료들과 협업하는 과정에서 개인과 팀 모두가 성장해 나가는 경험을 하고 있습니다. 다음에는 또 새로운 과제 실험과 기술을 소개해 드리도록 하겠습니다. 

 

감사합니다.

 

 


 

 

 

by nc nd