[개발일지] Vue.js로 하는 스프린트 회고

김선종·2022년 3월 7일
0

들어가기전에

상당히 오랜만에, 약 3개월만에 글을 업로드하는데, 그동안 굉장히 바빴다.
운좋게 인턴을 시작하기도 했고, 복학을 슬슬 준비하기도 하고, 무엇보다 피키팜일로 굉장히 바빠졌다.
그 와중에 설날 즈음에서 새로운 기능을 도입했는데, 5일만에 설계에서 배포까지 완료한 아주 지옥의 스케쥴을 회고해보면서 어떻게 빠르게 달렸는지를 다시한번 떠올려보려 한다.

쉴새없이 달리자

1월 초였던가,,, 설날을 준비하면서 새로이 "선물하기" 기능을 추가하자는 얘기가 솔솔 들어왔다. 사실 주문하기 시스템은 개발을 한번도 안해본 초기에 작성해둔 코드에 요구사항에 의해 새로운 코드를 덧붙이는 식으로 붙여나가다 보니... 가독성은 물론이고 버그 찾기도 더럽게 어렵고... 근데 거기에 새로운 기능까지 추가하자니 이거 머리가 참 아팠다. 과연 이거 가능한 일인가...

본격 삽질과 고생의 시작

레거시 코드는 독입니다

결제에 새로운 코드를 집어넣자니 사실 중요한건 클라이언트단의 코드보단 서버사이드의 코드였다. 결제 시스템의 코드는 상당히 더럽고 복잡한 상태인데,,,

  • 개발 극초기에 작성한 코드다. 우선 기능의 동작을 최우선으로 고려한 다음 리팩토링은 다음으로 미뤘다.
  • 결국 이 기술부채는 해결되지 않은 채, 새로운 요구사항에 따라 덧붙이기식의 코드가 남발했다.
  • 중복되는 로직을 각 함수에 모두 일일히 붙여넣는... 아주 최악의 코드들이 넘쳐났다.

그리하여 새로운 기능 개발에 앞서 기존의 코드부터 리팩토링하고 가는것이 우선이라 생각이 들었다.

최적화를 위한 멀고도 험한 길

현재 피키팜의 결제 시스템은 주문 정보를 생성 -> 갱신 -> 검증 하는 3개의 단계를 거친다.
그러니 그 말은 곧 함수가 3개가 만들어지는 것 인데, 주문 모델 객체에 대해 정보를 업데이트하고, 유효성을 검증하는 등의 코드가 상당히 많은 부분에 대해 중복되어 있었다.

주문 시스템의 프로세스를 정리하고, 중복되는 로직을 통합해서 하나의 함수로 묶기 시작했다.


이런 식으로 Django의 모델 클래스 메서드를 통해 기존 views에 파편화되어 있던 특정 로직들을 모델로 위임함으로서, 조금 더 각 모델의 역할을 명확히 정의할 수 있게 되었다.

신뢰성 있는 어플리케이션을 위한 고민

이번 프로젝트에 있어, 나는 전체 프로젝트의 총괄을 맡음과 동시에 프론트엔드를 총괄하여 담당하였다.
기존 결제하기 페이지의 프론트엔드(라고 하기도 뭐할정도로 조잡했었다. 난 그래서 개인적으로 "프론트엔드"라는 단어가 굉장히 낯간지럽다. 클라이언트 사이드라고 말하는편)는 이런식으로 동작했었다.

  1. 초기에 페이지를 로드할 때, 서버에서 가져온 상품과 가격 정보를 보여주고,
  2. 무언가 사용자의 액션으로 인해 데이터의 변경이 필요하면 querySelector()를 통해 DOM에 직접 접근해서 값을 바꾼다.

JS를 잘 몰랐던 시절엔 저게 최선인줄 알았더만, SPA에 대해 조금만 공부해도 2번같은 방식이 얼마나 충격적일정도로 무식한 행동이었는지 깨달았던 경험이 있다. 다만 결제 페이지를 바꾸는건 큰 리팩토링이니 감히 손을 못댔었는데, 이번에 새로운 페이지 개발 수요에 맞춰 아예 결제 페이지를 프레임워크를 적용해서 개발하기로 결심한다.

그래서 프레임워크를 썼다.

결론부터 말하자면, 이 프로젝트의 클라이언트 사이드에는 Vue.js가 사용되었다.

리액트를 사용하는게 좋지 않나 생각했지만, Django 기반의 전형적 정적 웹 형태인 피키팜은 webpack, babel의 사용이 거의 필수인 리액트 생태계 특성상 빠르게 빌드 파이프라인을 구축할 시간도, (개발할 시점의)나의 node 생태계에 대한 이해도도 매우 부족했다.

그래서 대안으로 생각한것이 webComponent였다. 컴포넌트 단위의 개발에 이미 익숙하고, 리액트의 생명주기 메서드의 기반이 되는 메서드들이 많았기 때문에 괜찮다고 생각했는데, 프레임워크가 아닌 바닐라인 특성상, 데이터의 갱신이 자동으로 리렌더링으로 이어지도록 하는 방법에 대해 빠르게 답이 나오지 않았다.

그때 마침, 인턴을 진행하던 회사에서 Vue.js를 이용한 프로젝트를 주셨는데, 정적 웹에 CDN으로 Vue를 불러와 빠르게 SPA를 개발할 것을 지시하였다. 기존의 리액트를 기초를 갓 뗀 정도의 이해도를 가지고 뷰의 공식 문서를 이해하는데는 처음 3일이 고비였고, 튜토리얼을 차분한 마음으로 따라하다 보니, 뷰의 특징으로 뽑히는 낮은 러닝커브가 어떤 의미였는지 바로 와닿게 되던 것이었다. 그래서 다음의 이유로 vue를 다음 프로젝트에 도입하기로 마음먹었다.

  • 뷰의 directive를 사용해 기존 HTML에 바로 Vue를 적용할 수 있다는 점
  • CDN을 사용한 개발이 크게 어렵지 않았다는 점
  • 무엇보다 나같은 초보자에게도 공식문서 정독 5일만에 해볼만하다고 생각하게 만드는 난이도

Vue와 함께 행복코딩의 시작

디렉티브는 물건이다

디렉티브란 아주 간단하게 말해서, HTML에 JS 표현식을 넣어 표현식의 값이 변경될 때 그 값을 DOM에 적용하는 것인데, 개인적으로 Vue의 러닝커브를 매우 낮추는 요인중에 하나라는 생각이 든다.

피키팜의 선물하기는 선물 받는 사람의 주소를 아는지에 대한 여부에 따라 입력창의 갯수가 달라진다.

번호만 알아요를 클릭하면 주소 란이 사라져야 하는데, 기존의 개발 방식을 유지했더라면 단순히 css의 display를 이용해 눈속임만 했을것이다. 하지만 v-if 디렉티브를 통해 주소입력 폼을 조금 더 효율적으로 관리할 수 있었다.

또한 여러명의 친구에게 보내고 싶을 때, 친구 더 추가하기 버튼을 클릭하여 선물을 받을 친구를 추가할 수 있다.

이 경우 원래 개발하던 방식이었다면, 저 추가되는 친구 부분의 전체 HTML 코드를 동적으로 기존의 HTML에 삽입하는,,, 아주 무식하기 그지없는 방식을 사용했었겠지만... v-for 디렉티브를 이용해, 친구 목록 배열에 새로운 엔트리를 추가하면, 뷰의 반응형 시스템에 의해 새로운 친구 row가 추가된다.

조금더 신뢰성 있는 상태 관리

사실 프레임워크를 도입한 가장 큰 이유중 하나는 상태관리 때문이다.
개별 친구의 수량을 조정하면 개별 친구에 대한 금액이 자동으로 계산되고, 주문 갯수도 계산되고, 총 금액마저 자동으로 계산된다. vue의 computed 속성을 이용하여 상태 변경에 맞춰 값이 자동으로 계산되니 여간 편한게 아니다.

computed: {
    numberOfFriend: function () {
        return this.friends.length;
    },
    sumOfQuantity: function () {
        // friend들의 quantity의 합계 구함
        return this.friends.reduce(
            (prev, next) => prev + (parseInt(next.quantity) || 1),
            0
        );
    },
    sumOfDeliveryFee: function () {
        return this.friends.reduce(
            (prev, next) => prev + parseInt(next.deliveryFee) || 0,
            0
        );
    },
    sumOfProductPrice: function () {
        return this.sumOfQuantity * this.productPrice;
    },
    orderTotalPrice: function () {
        return this.sumOfDeliveryFee + this.sumOfProductPrice;
    },
},

이런식으로, quantity만 바꾸면 다른 값들이 자동으로 계산된다.

이전엔 이걸 어떻게 처리했었냐면,,,

  1. 상품의 수량을 변경한다.
  2. 상품 가격의 DOM 요소를 가져와서, 수량*금액을 계산해 DOM의 내용을 바꾼다
  3. 전체 상품 총액의 가격의 DOM요소를 가져와서 바뀐 가격을 반영하여 DOM의 내용을 바꾼다...

불편

진짜 회고

뷰 짱짱맨

결국 Vue.js를 적용해서 불가능할것만 같았던 살인적인 계획에 맞춰 새로운 기능을 제때 배포할 수 있었다. 이 과정에서 Promise의 적용 등 더 깊은 내용에 대해서는 다음에 다뤄보고자 한다.

리액트와 비교해보면, 확실히 SPA 개발을 새롭게 시작하는 사람들에게는 리액트보단 뷰가 훨씬 쉽게 시작할 수 있을것이라 생각이 든다. node.js 환경에서의 빌드가 익숙하지 않은 사람이라면 더욱이 CDN 방식으로도 편하게 개발이 가능한 뷰가 어떨까 싶다. 특히 JSX나 hooks같은 개념은 러닝커브가 살짝 있을 수 밖에 없다고 생각이 들고, v-model 디렉티브 덕분에 인풋 처리가 매우 간단해진다는 점이 리액트 대비 엄청난 장점이라고 생각한다.

프론트엔드 진영에서 이제는 더 이상 무시할수 없는 정도의 존재감을 가질 정도로 성장한 svelte 또한 뷰와 문법이 상당히 비슷하다. 이러한 점에서도 뷰의 영향력이 점점 커질것 같다는 생각이 든다.

진짜 회고

프레임워크 아래 개발을 하다보니 상태관리를 이전보다는 조금더 제대로 할 수 있어서, 버그관리 측면에서 홀가분해진 기분이다. 다만 너무 급하게 개발을 하다 보니 놓친 몇몇 부분들이 있는데 꼭 리팩토링을 통해 적용해보고 싶은 것들이 있다.

  • Vuex 적용해서 Flux 패턴으로 상태 관리. 이미 인턴 프로젝트에서는 Vuex로 상태를 관리하는데 피키팜에서도 전역 상태관리를 통해 조금 더 가독성을 끌어올리고 싶은 마음이 있다.
  • 테스트 코드. vue-test-utilsJest 를 사용해 유닛 테스트에 대해 좀 공부했었는데, 얼른 적용해보고 싶다는 생각이 든다.
profile
개발자가 되고싶다 열심히하자

0개의 댓글