Brandi Internship - Part 3
코드 리뷰
처음 브랜디 인턴쉽 기간에는 매주 2번씩 코드 리뷰가 진행되었다. 각 팀에서 현재까지 구현된 내용과 코드들을 리뷰 받는 시간이었다. 프론트의 경우에는 코드를 어떻게 구성했는가 보다는 기능을 구현할 때 어떤 요소들을 고려했는지를 더 많이 질문 받았었다.
필터링된 값들을 쿼리스트링으로 붙이면 어떨까요?
피드백 받은 내용들은 대부분 사용자의 편의성에 관련된 내용들이었다. 예를 들면 페이지가 변경될 때, 페이지들의 구성이 동일하기 때문에 사이드 바에서 다른 페이지를 클릭해도 변경되었다는 것을 바로 알아차리기가 어려웠다. 그래서 페이지가 변경된다는 사실을 사용자가 알 수 있도록 페이지가 바뀌기 전에 로딩 창이 있으면 좋겠다는 피드백이 있었고, 피드백대로 로딩 페이지를 붙여 보았다. 그 결과 로딩 페이지 덕분에 페이지 변경 사실을 훨씬 쉽게 알아차릴 수 있었다.
또 다른 피드백 내용 중에는 vuex 파일을 전부 수정했던 피드백이 있었다. 사용자가 필터링 박스에서 특정 필터 값을 선택하고 검색 버튼을 누른 경우에 해당 필터 값들이 uri에 쿼리스트링으로 붙으면 좋겠다는 피드백이 있었다. 이유는 우선 vue나 react같은 spa 페이지 특성상 라우팅 처리는 실제 서버에 대한 요청이 아니라 js가 dom의 조작하는 트리거일 뿐이다. 때문에 새로 고침이나 뒤로가기를 한 경우에 쿼리스트링이 붙은 uri가 히스토리에 저장되지 않는다면 해당 상태 값들은 유지되지 않는다. 또한 단순히 쿼리스트링만 붙이면 되는 것이 아니고 쿼리스트링을 파싱해서 다시 상태 값으로 저장해 주어야 새로고침이나 뒤로 가기가 반영이 되었다. 문제는 이 로직의 처리가 10개의 컴포넌트를 그리는 일을 담당하는 lookup 컴포넌트에서 담당한다는 것이었다. 이게 문제가 되는 이유는 우선 페이지 마다 사용하는 필터 값이 다르고, 또 다 같다고 하더라도 모든 필터 상태 값을 lookup에서 vuex로 넘기도록 로직을 추가해야 한다.
vuex를 사용하기로 결정했을 때, 본래 동적으로 vuex 내부를 구성하도록 하려고 했지만 좋은 구성을 하기 위한 자료 부족 + 공부할 시간 부족 등등의 이유로 페이지 마다 하나의 vuex를 가지도록 만들었다. 문제는 필터 값 하나 하나 마다 getters, mutations, actions 함수가 추가되었기 때문에 상태값 개수 x 3 만큼의 코드가 생성되었고, 페이지간의 값이 동일한 경우도 있었는데 중복이 많이 발생하게 되었다. 중복은 그 자체로도 문제일 수도 있지만, 진짜 문제는 로직의 수정이 필요할 때, 중복된 코드 전부를 수정해야 하는 문제가 계속 발생했다. 결론적으로는 현재의 vuex 로직으로는 쿼리스트링을 uri에 추가하고 다시 상태 값으로 저장하는 로직을 만들수가 없었다. 뭔가 vuex 내부 로직을 추상화할 필요가 있었다.
getters를 currying으로 구성하기
나는 vuex를 각 페이지 별로 나누어서 구성했고 이를 위해 namespace를 이용한 모듈이라는 기능을 사용했다. 모듈을 사용한 경우 vuex에서 제공하는 helper 함수를 사용하면 vue에서 쉽게 특정 store만 사용할 수 있다. 특히 lookup에는 uri의 마지막 값에 따라서 textMap과 store가 매칭되도록 구성되어 있는데, 이렇게 하기 위해서는 uri 파싱이 먼저 일어나고 그 다음 특정 store와 매칭을 시켜야 한다. 문제는 uri를 파싱하는 타이밍과 store를 매칭하는 타이밍이 같다는 것이었는데, vue에서 undefined값으로 store를 찾게 되어서 계속 오류가 발생했다. 그러나 helper함수의 도움을 받으면 store와 매칭되는 타이밍을 지연시킬 수 있다.(선언 시에는 매칭이 되지 않고, 실행되었을 때 특정 store와 매칭된 getters, dispatch 반환하는 함수를 만들 수 있다.)
맨처음에는 getter가 반환하는 값은 값이기 때문에 추상화를 할 수 없다고 생각해서 상태 값마다, getters, mutations, actions를 만들었다. 그러나 추상화를 하기 위해 구글링을 한 결과 getters를 커링함수로 만들면 인자로 상태의 이름을 받아서 값을 반환하도록 만들 수 있었다. 즉 추상화가 가능해졌다. 추상화가 가능해졌을 뿐 아니라 코드의 길이도 훨씬 줄어들었다. 상태 값의 개수만큼 있었던 함수들이 단 하나의 함수로 줄었고, lookup에서도 추상화된 getters와 actions를 사용하면 되기 때문에 페이지 마다 필터값이 달라도 쿼리스트링 값을 읽고 저장할 수 있게 되었다. 아래의 코드를 보면 getters와 mutation이 인자를 받아서 값을 읽거나 바꾸기 때문에 상태값이 추가 되어도 변경될 필요가 없게 되었다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | export default { namespaced: true, ... getters: { getFilters(state) { return makeQs(state, state.dateValue); }, getValue: state => key => { return state[key]; } }, mutations: { setValue(state, { key, value }) { state[key] = value; }, reset(state) { const defaultTerm = 3; state.isLoading = false; state.selectFilter = ''; state.filterKeyword = ''; state.dateValue = 3; state.filterDateFrom = fromNow(defaultTerm); state.filterDateTo = new Date(); state.mdSeNo = []; state.filterOrder = 'NEW'; state.filterLimit = 50; state.page = 1; state.filteredResult = []; state.page_number = 0; state.total_order_number = 0; } }, ... | cs |
인턴쉽을 마치면서..
인턴쉽을 시작할 때는 부트캠프 때와 동일하게 클로닝 프로젝트를 맡게 된 것, react가 아니라 vue를 사용하게 된 것, 그리고 구현해야 할 페이지가 많았던 것 때문에 이런 저런 아쉬움들이 있었었다. 그러나 인턴쉽을 진행하면서 이전에 진행했던 클로닝 프로젝트보다 더 큰 규모의 사이트를 설계하면서 패턴을 찾아보고, vue의 장점을 경험해 보고, 피드백 과정에서 코드를 리팩토링하고, 문제를 해결해면서 배우게 된 것이 많았다. 특히 이전에는 기능을 구현하는 것 자체에 초점이 있었는데, 피드백을 받으면서 내가 만드는 사이트 혹은 기능이 사용하는 사용자 입장에서 편리한지, 사용자가 어떤 행동까지 할 것이라고 고려해 봤는지 등 사용자 편의성에 대한 고려를 처음 해보게 되었다.
다만 아쉬웠던 것은 “패턴은 제거되는 것이 아니라 발견되는 것”이라는 켄트 백 아저씨의 말처럼 나의 수준에서는 아직 낮은 수준에서의 패턴 찾기밖에 되지 않았고 vuex의 경우 중복이 존재했다. 그래서 코드가 수정되는 경우 다른 코드들도 수정을 해야하는 일이 발생했다. 또한 10개의 페이지를 그릴 때, 각 페이지에 대한 api를 만든 백엔드 팀원은 3명이었는데, 추상화된 vuex를 사용하기 위해서는 백엔드 팀원이 주는 response json의 형식이 동일해야 했다. 프로젝트 말미에 형식을 맞춰달라는 나의 요청에 백엔드 팀원들이 맞추어 주었지만, 미리 맞추지 못해서 네이밍이나 형식이 다소 부자연스러웠다. 앞으로는 이런 부분까지 미리 고려를 하면 좋을 것 같았다. (저의 요청을 들어준 지원, 해준, 용민님 감사합니다…) 마지막으로 webpack 설정에서 체이닝을 통해 간결하게 환경을 구성할 수 있으면 좋았을 것 같은데, 이렇게 하기 위해서는 많은 공부와 경험이 필요할 것 같다. vue-cli3보다 더 좋은 개발, 배포 환경을 구성하기 위해서는 상당히 많은 공부와 경험이 필요하기 때문에 왠만큼 수준이 오르기 전까지는 그냥 vue-cli3를 사용을 하는 것이 좋겠다는 생각을 하게 되었다.(Evan You도 vue-cli쓰라고 했다. 하하..)
저와 인턴쉽을 진행한 10명의 팀원들 모두 수고 많으셨습니다. 다들 앞으로도 빠이팅이에요 :)