[Vue.js Style Guide 적용기]
이런저런 이유로 1년 가까이 블로그 활동을 접었다가 다시 시작합니다.
그동안 이직도 했고 개인적인 이유로 공부는 하면서도 그에대한 정리가 없었습니다. 이제 연말이 가까워지니 다시금 프론트엔드 개발자, 조직과 사회의 구성원으로서 삶(?!)을 정리해 보며 게을러진 저를 채찍질하기 위해서 운동과 블로그 활동을 재개하려 합니다.
물론 언제까지 포스팅 하려는 의지가 계속될지 모르겠지만... 다시 시작하는 의미로 게시물과 카테고리 정리를 하고나니 블로그가 너무 볼것이 없어 이번 프로젝트에서 코드 리팩토링을 하며 적용한 Vue.js 스타일 가이드에 대해 간단한 수행기를 포스팅합니다.
Angular와 다른 프레임워크, 언어와는 다르게 (자바스크립트 제외) Vue.js의 공식 사이트에서는 강력한 한글 지원을 확인할 수 있습니다. 비록 업데이트 되는 내용이 모두 반영되는 것은 아니지만 한국 개발자들에게는 무척이나 반가워 할 일입니다.
스타일 가이드는 혼자서 개발할 때에는 그렇게까지 중요한 부분이 아니라고 여겨질 수 있지만 프로젝트를 진행하며 볼륨이 커져갈 때에는 그 필요성이 절실하게 느껴질 때가 생깁니다.
서로가 작성한 코드의 가독성을 높이고 명시적인, 또는 암묵적인 룰을 지켜 운영과 유지보수를 제대로 수행하기 위해서 스타일 가이드를 준수하면 보다 수월하게 프로젝트를 진행할 수 있을 것입니다.
아직은 Vue.js 자체에서 강제하는 정도의 수준은 아니지만 밑의 문구를 보면 조만간 ESLint와 다른 자동화 프로세스를 걸쳐 스타일 가이드를 적용할 수 있는 팁을 제공할 예정이라고 하니 미리 그 내용에 대해 알아볼 필요가 있을것 같습니다.
Soon, we’ll also provide tips for enforcement. Sometimes you’ll simply have to be disciplined, but wherever possible, we’ll try to show you how to use ESLint and other automated processes to make enforcement simpler.
공식 사이트에서 제공하는 문서를 보면 Vue.js의 스타일 가이드는 4가지의 우선순위를 A, B, C, D의 레벨로 나눠 세부 규칙을 명시하고 있습니다.
A - 필수,
B - 강력 권고,
C - 권고,
D - 사용시 주의
(* 번역본이 있지만 최대한 원문을 번역하여 포스팅 합니다. 원문의 느낌이 개인차가 있기 때문이지 번역이 잘못된 것은 절대 아닙니다.)
공식 사이트의 스타일 가이드를 읽어내려 가던 중 습관처럼 사용했던 네이밍 규칙이 필수로 규정되어있어 조금 놀랐습니다. (다른 분들이 안그러셨다면 저의 게으름을 반성합니다.) 문서를 보면 명시 되어있지만 A 레벨의 오류 방지 차원에서 컴포넌트의 네이밍 규칙을 필수로 권하고 있습니다.
root App 컴포넌트를 제외하고 컴포넌트의 이름은 반드시 다수의 단어로 사용을 해야합니다.
이것은 해당 문서의 링크를 따라가보면 그 이유를 자세히 알수 있습니다. 요약하자면 현재, 그리고 앞으로 생성될 HTML 요소들의 이름이 단수의 단어로 규정 되었거나 규정되기 때문에 커스텀 엘리먼트인 컴포넌트의 이름을 다수의 단어로 강제하여 커스텀 엘리먼트와 네이티브 엘리먼트 사용 오류를 방지하기 위함 입니다.
쭈욱 읽어가다 보면 너무나 당연한 규칙들, 예를 들어 new 키워드를 사용한 Vue 인스턴스 생성이 아니라면 팩토리 함수를 사용하여 data를 사용해야한다는, 이미 너무나도 잘 알고있는 당연한 내용부터, 이런것도 있었는지 잘 모르던 내용까지, 여러가지 스타일 가이드 예제가 간단하지만 이해하기 쉽게 잘 설명되어 있습니다.
이 중에서, 스타일 가이드를 확인하고 적용하면서 처음 알게된 내용 세가지만 간단하게 정리하겠습니다. (다른 분들께 공유와 저의 망각을 위함 입니다...)
1. Props definitions
Parent에서 Child로 데이터를 넘겨줄 때 사용하는 pops는 단순히 item의 이름만 명시하여 사용하고 있었지만 프로토타이핑인 경우를 제외하고는 가능한 구체적으로, 해당 데이터의 타입(type)과 필수여부(required), 값 반환 혹은 검증에 필요한 함수 제공을 규정하고 있습니다.
위의 규칙은 필수이지만 성능 이슈나 향후 오류 방지의 효과를 기대하기 때문도 있지만 데이터의 타입이나 필수값, 기본값 등을 체크하여 자체적인 데이터 검증 등을 통해 해당 데이터를 이름만으로 추측하는 것이 아니라 사용 목적을 분명히 하기 위함으로 보입니다. (물론 뇌피셜입니다.) 추가적으로 해당 문서에서 설명이 조금 빠져있지만 props의 default 혹은 validator 사용을 찾아보시길 권합니다. (* 참조 링크)
2. Avoid v-if with v-for
Vue.js에서는 v-if 사용시 v-for와 함께 사용하는 것을 엄격히 금하고 있습니다. (물론 저는 사용했습니다...) 명시된 문서에는 두가지의 일반적인 예를 들어 각각의 경우 상황에 맞게 대체하여 코딩할 수 있는 예시를 제공합니다.
1. 리스트 안의 반복되는 아이템을 필터링하기 위해서 사용하였다면 해당 리스트 자체를 computed 프로퍼티로 계산하여 리스트를 반환하고 반복 아이템을 렌더링 한다.
2. 어떠한 조건을 충족하지 못할 때 리스트의 아이템 렌더링을 회피하기 위한 목적일 경우, v-if 문을 해당 리스트의 컨테이너 엘리먼트로 옮긴다.
이렇게 제시하는 이유는 해당 설명에 접힌채로 명시 돼 있습니다. 자세한 설명을 자세하지 않게 간단히 설명하자면 v-for가 v-if 문 보다 우선순위 우위에 있기 때문에 해당 조건문의 값이 변경이 되거나 그러하지 않은 경우에도 리스트 구문이 렌더링 될 때마다 v-for의 내부 함수가 실행되기 때문입니다.
이를 지키지 않으면 매번 연산되는 횟수(step)가 늘어나고, 곧 성능 저하로 이어지기 때문에 스타일 가이드 상의 무엇보다 더 엄격히 지켜져야 할 것입니다. 보다 자세한 설명은 스타일 가이드를 참조하시기 바랍니다.
3. v-if / v-else-if / v-else without key
이번 규칙은 '레벨 D'지만 많이들 그냥 넘어가는 부분이라 (물론, 그 '많이'에 제가 포함되어 있습니다.) 정리합니다. v-조건문 사용에 있어서 key 어트리뷰트는 필수는 아니지만 Vue.js에서 v-if문을 처리하는 방식 때문에 같은 요소(예를 들면 v-if와 v-else가 동일한 요소인, div 엘리먼트에 각각 명시되어 있는 경우)에서 v-조건문을 사용할 경우 key 어트리뷰트를 사용하여 두 엘리먼트를 key 값으로 분리할 것을 권고하고 있습니다.
By default, Vue updates the DOM as efficiently as possible. That means when switching between elements of the same type, it simply patches the existing element, rather than removing it and adding a new one in its place.
위에서 설명하듯 Vue.js는 DOM을 가능한 가장 효율적인 방법으로 업데이트하기 때문에 만약 v-조건문이 명시된 엘리먼트와 같은 엘리먼트가 이미 존재한다면 그것을 node 상에서 지우거나 새롭게 추가하는 것이 아니라 단순하게 패치(patch)하여 의도하지 않은 사이드 이펙트를 불러올 수 있습니다. 그러니 낮은 단계의 권고 수준이라도 v-조건문을 같은 엘리먼트에 사용할 때에는 주의를 기울여야 할 것입니다.
위의 세가지는 스타일 가이드를 적용하며 수정 하였던 많은 규칙들 중 저에게 중요한 부분이라 정리한 것이고 성능과 가독성을 위해서, 또는 향후 발생할 수 있는, 의도치 않는 오류를 피하기 위하여 반드시 스타일 가이드를 일독해 보시기를 권합니다.