우당탕탕 좌충우돌 프로젝트 경험기 1. 재사용성, 확장성, 일관성 그리고 구현 난이도

Plato·2022년 9월 9일
0

시리즈 소개

리액트 프로젝트를 진행하며, 맞닥뜨렸던 문제를, 어떻게 해결해갔는지 공유하는 시리즈 '우당탕탕 좌충우돌 프로젝트 이야기'의 첫 번째 이야기 '재사용성, 확장성, 일관성 그리고 구현 난이도', 시작해보자.

프로젝트의 시작

온라인 커뮤니티의 글을 통해, 백엔드 개발자 한 분과 함께 웹개발 프로젝트를 진행하기로 했다.
프로젝트의 주제는, 협업 도구인 'flow의 디자인과 기능을 구현하는 것'으로 결정했다. 그 후, 집에 돌아와, 개발을 시작했는데 정말 다양한 문제를 겪을 수 있었다.

처참한 재사용성

프로젝트 생성과 패키지 설치를 마친 뒤, 제일 먼저 시도했던 일은 헤더를 구현하는 일이었다. 헤더를 구현하며, 여러 컴포넌트를 만들기 시작했는데, 컴포넌트 내부 컨텐츠와 스타일링을 customize할 인터페이스(props)의 부재 그리고 높은 구체성이, 처참한 재사용성으로 이어지고 있었는데, 이를 해결해야 할지 고민했다. 재사용성의 확보가 꼭, 생산성의 증대로 이어지는 것만은 아니기 때문이다.

  1. 우선, 재사용성을 고려하면, 초기에 컴포넌트를 개발할 때 시간이 오래 걸리게 된다. 어떤 인터페이스를 가질 것인지, 어느 정도의 확장성과 customizability를 가질 것인지 그리고 어떤 방식으로 확장할 수 있도록 만들 것인지, 많은 부분을 고민해야지만, 재사용성이 뛰어난 컴포넌트를 개발할 수 있을거라 생각했다.

  2. 또한 필자의 경우, 프론트엔드 파트를 혼자 전담하게 돼서 해당 사항이 없었지만, 팀원이 있는 경우 컴포넌트를 프론트엔드 개발자 전원이 사용해야 하므로, 문서화도 시켜야 하며, 변경 사항이 있을 때마다 이를 문서에 반영해야 한다.

  3. 물론 이처럼 초기 구현이 오래 걸리고 복잡하더라도, 이후에 높은 생산성으로 이어진다면 충분히 진행할 가치가 있을 것이다. 하지만, 꼭 생산성의 증가로 이어지는 걸까? 그렇지는 않을거라 생각했다. 높은 재사용성이 높은 생산성으로 이어지기 위해서 필요한 조건이 있다. 컴포넌트로 분리하는 기준과, 인터페이스, 확장성, 확장 방법 그리고 customizability가 단순하고 일관되면서 동시에 다양한 사용 케이스를 커버할 수 있어야 한다.
    이것들이 일관되지 못 하다면, 컴포넌트의 수가 늘어나면서, 어떤 컴포넌트가 있고, 각 컴포넌트는 어떻게 사용하고, 어떤 props를 갖고, 어떻게 확장해야 하며, 어느 정도의 customizability를 갖는지, 하나하나 파악하고 숙지하는 것이 어려워질 수밖에 없다. 이것들을 제대로 숙지하지 못해서, 컴포넌트 코드를 들여다봐야 하고, 문서를 찾아서 읽어야 한다면, 그만큼 오히려 생산성이 떨어질 수밖에 없다.

이러한 이유로, 아래와 같이 일관된 customization 인터페이스와 확장 방법을 정하여, 재사용성을 확보하고 생산성을 높이고자 했다.

  1. 재사용 가능한 컴포넌트의 layout은, 컴포넌트가 존재하는 환경(상위 컴포넌트)이 정해야 한다.
    a. 크기는 width와 height 두 가지 props로만 결정한다. 하지만 두 가지 props 전부 다 사용하지 않아도 된다. 예시로 width와 height의 비율이 일정하다면, width만 props로 가져도 된다.
    b. 그 외의 layout은, className props를 통해, 클래스명을 부여함으로써 결정한다.

  2. 1번의 layout을 결정짓는 props를 제외하면, 어떠한 props도 갖지 않는다.

  3. props로 해결할 수 없다면, 확장을 통해 해결하거나 새 컴포넌트를 만든다. 만약 확장을 통해 해결한다면, 합성 컴포넌트 패턴을 사용한다.

물론 필자의 규칙이, 각 컴포넌트의 재사용 사례를 많이 제한할 것이 명백했지만, 일관되지 않고 복잡한 인터페이스는 오히려 생산성에 해가 되리라 생각했다. 위의 규칙을 최대한 지킴으로써, 컴포넌트가 일관되고 단순한 인터페이스(props), 확장성 그리고 확장 방법을 갖는, 행복한 상상을 했다.

단순하고 일관된 인터페이스가 초기 개발 난이도를 높이다

하지만 마이크 타이슨이 "누구나 그럴싸한 계획은 있다. 맞기 전 까지는 말이다"라 했던가... 나의 행복한 상상은, 무자비한 현실앞에 산산이 조각났다. 필자가 처음 한 생각이 꼭 틀린 생각은 아니었지만, 일관된 인터페이스를 위해 props를 과하게 제한한 것이 예상보다 더 독이 됐다. 커버해야 하는 사례가 많지 않고 서로 비슷하다면, 적은 수의 props를 추가함으로써, 아주 쉽게 재사용할 수 있다. 하지만, props를 과하게 제한하면서, props를 추가하여 쉽게 재사용하는 건 불가능했다. 한 예시로 아래의 사이드바 ui를 보자.

위 두 스크린샷은, 사이드바 ui의 일부분을 캡처한 스크린샷이다. 이 둘은 무척 유사하다. 그래서, 사이드바 컴포넌트를 합성 컴포넌트로 만들고, 서브 컴포넌트인 '사이드바 섹션'을 조합함으로써 각 페이지에 맞는 사이드바를 구현하고 싶었다. 하지만, 내가 정한 규칙 때문에, '사이드바 섹션'을 구현하는데 필요한 props를 추가할 수 없었다.

물론, 사이드바는 충분히 큰 컴포넌트이고, 이후에 기존의 props로 커버할 수 없는 사용 사례가 추가될 때마다, '사이드바 섹션'의 props를 더 추가하는 건 바람직하지 않기 때문에, 확장성 측면에서는 나의 방법이 옳았다고 생각한다. 이렇듯, 컴포넌트의 재사용성, 확장성, 인터페이스의 단순성과 일관성 그리고 기획/구현 난이도가 복잡하게 얽혀있어서, 하나를 챙기면, 다른 하나를 잃는 제로썸 게임을 한다는 느낌을 받았다.

props 규칙을 없애다

props를 제한하여 얻게되는 단순함과 일관성보다, 잃게되는 재사용성이 더 크다 생각하여, 결국에는 props를 제한하는 규칙 자체를 없애고, 자유롭게 props를 추가하며 개발을 진행하기로 결심했다.

마무리

다양한 사용 사례를 커버할 수 있으면서, 사용 방법이 직관적인 컴포넌트를 개발하는 건 결코 쉬운일이 아님을 뼈저리게 느낄 수 있었다. 1년 뒤 2년 뒤에는, 손쉽게 컴포넌트를 설계하고 구현하는 필자가 될 수 있길 기대하며, 이만 물러가보겠다.

0개의 댓글