티스토리 뷰

Frontend/Vue

# NUXT JS

zoeful 2020. 7. 23. 14:47

안녕하세요!

최근에 팀원들을 상대로 NuxtJS에 대해 CodeLab을 했었는데 어찌나 떨리던지..
CodeLab했던 내용을 공유하고자 가지고 왔습니다.

 

내용은 크게 계기 > 특징 > 구조 > 후기로 구성되어질 예정입니다.

 

먼저, NuxtJS를 시작하게 된 계기 입니다.
회사에 입사해 팀장님 외 다른 팀원분들을 통해 meteor 교육을 받았지만 그 당시 제 실력이 미비해서 그런지 meteor를 이해하기에 녹록치 않은 때가 있었습니다. 그러던 중 한 블로그에서 vue라는 자바스크립트 프레임워크를 접하게 됩니다.

 

그나마 meteor보다 진입장벽이 낮게 느껴졌던 vue에 흥미를 느끼고 블로그에서 추천해준 서적도 구입을 합니다.
아마 이런 낮은 진입장벽 덕분에 vue가 2019년 가장 인기있는 자바스크립트 프레임워크가 된게 아닌가 싶습니다.
서적과 기타 블로그등을 참고하면서 vue에 깔짝거리던 중 팀장님께서 vue를 좀 더 쉽고 고퀄리티로 사용할 수 있는 프레임워크가 있다며 Nuxt의 존재를 알려주셨습니다.
NuxtJS가 Vue 응용 프로그램을 만들기위한 프레임워크이다 보니 실제로 사용하는데 무리가 없었고 가이드에서 시키는데로만 하면 금방 개발가능한 프로젝트 환경 및 서버가 셋팅되니 매우 편리하더라구요.
그때부터 제가 NuxtJS의 늪에 빠졌던것 같습니다.

 

그러면 이제 본론으로 들어가서 NuxtJS에는 어떤 특징이 있는지에 대해 살펴봅시다.

 

NuxtJS에는 크게 3가지 특징이 있습니다.
SSR을 이용한 SEO최적화, pre rendering, 코드분할.
이중 가장 중요한 특징이라고 할 수 있는 SSR을 이용한 SEO최적화 부분만 심도있게 설명하고 넘어가고자 합니다.
pre rendering, 코드분할이 궁금하신분들은 구글링을 통한 습득부탁드립니다..ㅎㅎ
SSR을 이용한 SEO최적화를 쉽게 풀어 설명하자면 SSR, 즉 서버 사이드 랜더링을 통해 SEO, Search Engine Optimization 검색엔진최적화를 가능케 한다는 말입니다. 이렇게 말하면 이해를... 하셨을까요~?
이걸 제대로 이해하시려면 SPA와 SSR의 차이가 무엇인지 각각의 장단점이 무엇인지를 알고 있어야 합니다.

 

SPA는 (Single Page Application의 줄임말) Client Side Rendering 방식으로 단 한번만 리소스(HTML, CSS, JavaScript)를 로딩하고,
그 후에는 데이터를 받아올때만 서버와 통신하는 방식입니다.
첫 요청시 딱 한페이지만 불러오고 페이지 이동시 기존 페이지의 내부를 수정해서 보여주는 방식인 겁니다.
초기 구동속도는 느리겠지만 페이지 이동시 필요한 리소스만 부분적으로 로딩하기 때문에 성능면에서 굉장히 뛰어납니다.

 

하지만 일반적인 SPA 앱을 검색 로봇 입장에서 보면 모든 페이지의 소스는 이와 같습니다.
로딩시점에서는 검색 엔진이 색인을 할 만한 콘텐츠가 존재하지 않는 것이죠. 검색봇 둥절 상황이 발생합니다.

 

이에 반해 SSR은 페이지를 이동할 때마다 새로운 페이지를 요청하고, 모든 탬플릿은 서버를 통해 렌더링되고, 서버에서 렌더링이 완료되면 완성된 페이지 형태로 응답하는 방식입니다.
초기 구동속도도 빠르고 완성된 페이지의 형태로 응답하기 때문에 SEO에 최적화 될 수 있지만 페이지 이동 시 서버 렌더링에 따른 부하 때문에 성능면에서는 조금 뒤쳐질 수 있다고 볼 수 있겠습니다.

 

말씀드린것을 토대로 SPA와 SSR의 장단점을 정리해봤습니다.
NuxtJS가 SPA와 SSR이랑 무슨 상관이라고 왜 이렇게까지 정리를 하느냐,,
SPA의 장점과 SSR의 장점을 모두 이용하면 더 좋지 않을까 하는 생각하셨나요?

 

NuxtJS는 universal mode를 지원합니다.
universal은 Isomorphic application (server-side rendering + client-side rendering) 이라고 합니다.

 

처음 리퀘스트가 도착하면 서버사이드에서 일련의 과정을 거친 후 최초에 요청한 페이지에 한해서 렌더링 한 뒤 완성된 페이지를 클라이언트로 리스폰스 합니다.
그 이후에 페이지 이동은 페이지 갱신 없이 클라이언트에서 nuxt-link를 통해 필요한 리소스만 ajax통신으로 받아 렌더링 합니다.
첫 요청 후 페이지 이동은 클라이언트 사이드 렌더링을 하는겁니다.
이렇게 되면 SEO 최적화 뿐만 아니라 페이지 이동시에도 사용자에게 더 빠르고 자연스러운 사용자 경험을 제공할 수 있게 됩니다.
이렇게 SSR과 CSR의 장점을 모두 아우르고 있는 부분이 NuxtJS의 가장 중요한 특징중 하나가 되겠습니다.

 

다음 차례는 NuxtJS의 디렉토리 구조인데 이것도 모두 다 설명하기에는 양도 많고 탈도 많을꺼같아 몇가지 정리하고자 하는 부분만 추려 준비해봤습니다.

전에 회사에 신입분들께 Nuxt의 디렉토리 구조에 대해서 설명하려고 했던적이 있었는데, 그때 제대로 설명드리지 못했던 부분 중점적으로 정리를 하였습니다.

 

Nuxt를 구성하고 있는 기본적인 디렉토리 구조입니다.
이중 assets과 layout, store에 대해 알려드리도록 하겠습니다.
제가 에전에 디렉토리 구조 설명할때 왜 assets에 이미지를 넣어야하는지 왜 json파일을 assets에 넣어야하는지 그냥 넣으라그래서 넣고있다고 아주 개떡같이 설명했던 적이 있었습니다.
그 부분을 반성하며...
assets은 compiled 되지 않은 자산을 포함하는 디렉토리 입니다.
컴파일이란 개발자가 작성한 소스코드를 바이너리 코드로 변환하는 과정을 말하는데

 

compiled 되지 않은 자산에는 SASS 파일, 이미지 또는 글꼴등이 있습니다.
이렇게 컴파일 되지 않은 파일은 NuxtJS가 강력한 에셋 처리를 위해 기본적으로 webpack의 모듈디펜던시를 사용하여 처리하게 됩니다.
처리 과정에서, <img src="...">나 background: url(...), @import 같은 모든 에셋 URL은 모듈 디펜던시로 처리됩니다.
예를들어 CSS에서 url('~assets/image.png') 로 사용했다면 NuxtJS는 webpack의 모듈디펜던시를 통해 require('~assets/image.png')로 변환시키는 것입니다.
모듈디팬던시는 장기적인 캐싱 처리라는 이득을 볼 수 있도록 하고, 한계치보다 작은 용량의 파일을 base-64 데이터 URL로 인라인할 수 있는데 이는 작은 파일에 대한 HTTP 요청 수를 줄일 수 있게합니다.
그냥 넣으라그래서 넣는것이 아니라 모듈 디펜던시 처리를 통해 위와같은 이득을 취하기 위해서 이미지나 기타 파일들을 assets에 넣는 것이었습니다.
만약 모듈디펜던시 처리를 원치 않고 그냥 정적인 파일을 사용하고 싶다면( = Webpack으로 처리된 에셋을 사용하고 싶지 않다면),
static 폴더를 생성하고 그 안에 넣어 사용하면 됩니다.

 

다음은 layouts에 대해 설명하도록 하겠습니다.
NuxtJS에서 layouts component는 vue-cli의 App.vue와 같습니다. 최상위 구성요소인 셈이죠.
이때 pages에서는 기본적으로 layouts에 default.vue를 사용합니다.
예를들어 layouts에 publish라는 파일을 만들어 h1의 색을 blue로 설정하고 pages에서 layout 프로퍼티로 publish를 사용하겠다고 선언하면 해당 레이아웃이 현재 페이지에 적용되는 것을 확인할 수 있습니다.
이렇게 layouts 디렉토리의 모든 파일은 페이지 컴포넌트의 layout 프로퍼티를 사용하여 접근가능한 사용자 정의 layout을 만들 수 있습니다.

 

마지막으로 store에 대해 말하고자 합니다.

store는 Vuex Store를 포함하는 저장소 디렉토리입니다.
Vuex Store란 클라이언트 환경에서 데이터 관리를 용이하게 만들어 줄 뿐아니라 데이터를 보관, 읽기, 쓰기, 서버 통신 등을 각 역할 별로 나눠 관리합니다.
Nuxt.js가 Vuex 구현하는 핵심 이유는, 저장소를 사용하여 상태( = 데이터 )를 관리하는 것은 모든 대형 애플리케이션에서 중요하기 때문입니다. NuxtJS는 Vuex를 사용할 수 있는 2가지 모드를 제공하는데 버전 3을 기점으로 클래식 모드는 지원하지 않는다고 하니 module모드만 설명하도록 하겠습니다.
Vuex Store는 Nuxt.js와 함께 제공되지만 기본적으로 비활성화되어 있습니다. 비활성화 되어있는 Vuex를 활성화 시키는 방법은 매우 간단한데 그냥 store폴더에 index.js파일을 만들고 작성하면 끝입니다.
NuxtJS는 똑똑해서 모듈모드라고 설정할 필요 없이 각 속성들(state, mutations, actions 등 )을 export해주면 알아서 모듈모드로 동작하게 됩니다.
그렇다면 store는 클라이언트 환경에서 어떻게 데이터 관리를 해주게 되는것일까요?
store에 작성한 state는 상태 (데이터)를 나타냅니다.
mutations은 쓰기(동기 처리)를 합니다.
actions은 액션(비동기 처리 > 쓰기 커밋)을 합니다.

 

우리가 흔히 mutation에 set~라고 작성하는 코드는 액션 메서드 내부에서 클라이언트에 작성한 commit을 실행시켜 mutation에서 해당 커밋과 같은 내용을 실행시킵니다. 그러면 이제 mutation은 state객체의 속성에 데이터를 보관시키는 구조로 돌아가게 되는 것이죠.
이를 통해 상태(데이터)관리가 가능하게 되는것입니다.

 

이번 발표를 준비하면서 저 스스로도 많이 공부가 됐습니다.
NuxtJS를 쓰면서 왜 NuxtJS를 쓰는지, NuxtJS가 어떻게 구동되는지 감으로만 알고 있는게 아니라
정확하게 이런 이유에서 이렇게 구동되고 있다는것을 알게 되었습니다.
개발을 하다보면 근본적인 개념들은 무시한채 내 현재 작업에 치중하여 그냥 이렇게 하면 이렇게 되니까 하는 경우가 많았는데, 스스로를 되돌아보는 시간도 되었구요.
몰랐던 개발용어들 또한 검색해보고 이해하면서 발전하는 시간이 되었던거 같습니다.
갓 입사한 저였으면 단순히 개발용어를 검색하고 읽어본다고 해당 용어를 습득 할 수 는 없었을꺼란 생각과 함께 많이 발전한 저를 느낄 수 도 있었습니다.

 

이상 첫번째 CodeLab브리핑을 끝마치겠습니다. 감사합니다 : )

'Frontend > Vue' 카테고리의 다른 글

# vueJS에서의 가상돔 (= virtual DOM)  (0) 2020.08.14
# VueJS 2.0  (0) 2019.10.31
댓글
공지사항