본문 바로가기
FE/Nuxt.js

Nuxt.js 란? (feat. SSR, CSR)

by Day0404 2021. 4. 9.
728x90
반응형

이미 나도 이 프레임워크로 개발을 진행하고 있는 상태이기 때문에 다시 정리도 하고, 기본적인 내용들을 상기하고, 글로 남겨두기 위해 작성하였다.

Nuxt.js 란?

Nuxt.js는 Vue.js 애플리케이션 개발을 보다 강력하고 사용하기 쉽게 만들어 주는 프레임워크이다.
개발자들은 조금 더 빠른 개발 속도를 위해 Vue.js를 빠르게 적용하는 방법을 고안했고, 이를 프레임워크로 만들었다.

 

Nuxt.js의 등장 배경

Nuxt.js 나 Next.js 같은 SSR Framework가 왜 등장했는가에 대해 짚고 넘어가기 위해서는 SPA와 CSR, SSR에 대한 차이를 명확히 짚고 넘어갈 필요가 있다.

SPA (Single Page Application)

SPA는 Web Application을 Single Page로 만든 애플리케이션을 의미한다.

wiki에서는

페이지를 불러오지 않고 현재의 페이지를 동적으로 다시 작성함으로써 사용자와 소통하는 웹 애플리케이션이나 웹사이트를 말한다. 이러한 접근은 연속되는 페이지들 간의 사용자 경험의 간섭을 막아주고 애플리케이션이 더 데스크톱 애플리케이션처럼 동작하도록 만들어준다.

라고 정의하고 있다.

한마디로 SPA는 최초 한 번 페이지 전체를 로딩한 후 데이터만 변경하여 사용할 수 있는 애플리케이션을 의미한다.

전통적인 웹 방식인 SSR은 SPA에 비해 성능이 뒤떨어졌다.

그 이유는 요청 시마다 서버로부터 리소스를 받아 해석하고 화면에 렌더링 하는 방식이기 때문이다.

이러한 점에 의해 SPA는 트래픽을 감소시키고 사용자에게 최적화된 환경을 제공할 수 있게 되었다.

서버는 단지 JSON 파일만 보내주는 역할을 하며
html을 그리는 역할은 클라이언트 측에서 자바스크립트가 수행하였다.
그리고 이것이 클라이언트 사이드 렌더링(Client-side rendering)이다

 

SPA 장점

  • 페이지의 동적 작성 > 변하지 않는 부분과 변하는 부분을 구분하여, 변하는 부분만 새롭게 그려주는 방식 > 쓸데없는 렌더링 비용 감소
  • 클라이언트 사이드 렌더링 > 템플릿 연산을 서버 측에서 클라이언트로 옮김
  • 컴포넌트 단위로 개발 용이

SPA 단점

  • 초기 load 속도가 늦음 > js, css파일들을 번들링 해서 받기 때문
  • SEO가 어려움 > 번들링 된 js를 검색 봇, 크롤러들이 데이터 수집에 어려움이 있음 (요즘에는 구글 봇이 SPA도 인식을 한다고 함)

위 와 같은 장단점이 있으나 현업에서는 위 단점들이 크리티컬 한 이슈일 수 있다. 서비스가 커질수록 초기 load에 대한 압박이 커지고, 마케팅 측면에서 SEO의 어려움은 큰 이슈이기도 하다. 번들링 된 js 스플리팅이나 prerendering을 통해서 어느 정도 해소할 수는 있지만 위 방법에도 한계는 존재하므로 충분히 고려되어야 할 부분이다.

CSR 장점

  • 트래픽 감소 - 필요한, 변경된 데이터만 받아오기 때문
  • UX - 새로고침이 발생하지 않아 사용자가 네이티브 앱과 비슷한 경험을 할 수 있다.

CSR 단점

  • SEO
  • 자바스크립트 위주로 돌아가는 프로젝트는 자바스크립트 엔진이 돌아가지 않으면 원하는 정보를 표시해주지 못함. 크롬에서 React 나 Vue로 만든 웹앱의 소스를 확인하면, 내용이 비어있다. 그렇기 때문에 검색엔진 크롤러가 데이터들을 제대로 수집하지 못한다. 우리의 갓구글의 검색엔진은 자바스크립트 엔진이 내장되어있다. 하지만 네이버, 다음 등의 검색엔진은 제대로 크롤링하지 못하기 때문에 서버사이드 렌더링을 따로 구현해야 한다.

SSR (Server Side Rendering)

SSR 은 Sever Side Rendering으로써 CSR의 반대가 되는 표현입니다. MPA(Multiple Page Application)들은 SSR 형태를 띠게 되고, SPA라는 개념이 나오기 전에는 대부분 MPA 방식을 사용하고 있었다고 볼 수 있다. SSR은 템플릿까지 모두 서버에서 처리되는 만큼 SEO에 매우 강력하고, 초기 로드 시간도 SPA보다 훨씬 유리한 측면을 가지고 있다. 하지만, 페이지의 동적 작성이 불가능하고, 서버 부하가 생기고, 컴포넌트 단위로 개발이 불가능했었다 라는 점이 단점이다.

SSR 장점

  • SEO
  • CSR에 비해 초기 로드 속도가 빠름

SSR 단점

  • SPA에 비해 서버 성능이 더 필요함 > 템플릿 렌더링 비용
  • 페이지 이동시 화면 깜빡임 및 중복된 렌더링 비용 발생 > 효율성에 대한 문제 > UX 문제로 이어질 수 있음
  • SPA에 비해 초기 load속도는 빠르지만, 매 페이지마다 템플릿에 대한 새로운 load가 필요함
  • 컴포넌트 단위 개발 어려움

Angular, React, Vue SPA 삼대장들이 출시되고 나서, SPA의 단점들을 극복하고자 많은 노력들이 있었지만, 정통 SSR(MPA) 방식의 장점들을 완벽하게 커버하기란 불가능하였고 이를 극복하기 위하여

Next.js(React 기반), Nuxt.js(Vue 기반) 등의 프레임워크가 등장하였다.

2021-04-05 기준

Nuxt.js Github star 35.5k

Next.js Github start 65.3K

Nuxt.js 개발자들이 소개하고 있는 Nuxt.js의 목표

  • Nuxt.js의 주요 범위는 클라이언트/서버 배포를 추상화하는 동안의 UI Rendering이다.
  • Node.js 기반의 프로젝트 혹은 기본 프로젝트 베이스로 사용할 수 있을 만큼의 유연한 프레임워크를 만드는 것이다.
  • Nuxt.js는 Vue.js 애플리케이션 서버 렌더링을 보다 즐겁게 개발하는데 필요한 구성 요소들을 미리 설정한다.
  • nuxt generate라고 부르는 배포 옵션을 제공하고 Vue.js 애플리케이션을 정적으로 생성할 수 있다.

Nuxt.js 특징

  • Vue 파일 사용
  • 코드 분할 자동화
  • SSR을 통한 SEO
  • 비동기 데이터 기반의 강력한 라우팅 시스템
  • 정적 파일 전송
  • ES2015+ 지원
  • JS & CSS 코드 번들링 및 압축
  • <head> 요소 관리 (<title>, <meta>, 기타)
  • 전 처리기 지원 : SASS, LESS, Stylus 등
  • Pre-rendering
  • pages 폴더 기반의 자동 라우팅 설정
  • 웹팩을 비롯한 기타 설정

Nuxt.js 시작하기

yarn

yarn create nuxt-app <project-name>

 

npx

npx create-nuxt-app <project-name>

 

npm

npm init nuxt-app <project-name>

 

위 명령어로 실행하면 몇 가지 질문들이 나오게 되는데 프로젝트 환경에 맞게 설치하면 된다.

나는 npm을 통해 진행하였고, 사실 처음 npm init nuxt-app을 통해 프로젝트를 생성했을 때 그 뒤에 따라오는 프로젝트 설정들을 뭘 선택해야 하나 고민 많이 했었다.

 

Nuxt.js 디렉터리 구조

 

assets

  • css, image, font와 같은 리소스들을 포함한다.
  • url loader가 관리. nuxt 프로그램 내에서 절대 경로를 통해 에셋 파일에 접근 가능.
  • nuxt 2.0부터 물결표와 에셋 사이 슬래시 제거 가능.
  • 프로젝트 루트 디렉터리에 직접적으로 bundled. 따라서 /filename으로 접근 가능

components

애플리케이션에서 사용될 컴포넌트들을 포함하며 해당 경로에 위치된 컴포넌트들은 Nuxt.js의 비동기 데이터 함수인 asyncData 또는 fetch를 사용할 수 없다.

layouts

애플리케이션 전체에 대한 레이아웃을 포함한다. 기본으로 default.vue가 생성되어 있을 것이고 상황에 맞게 layout을 생성할 수 있다. 해당 디렉터리는 이름을 변경할 수 없다.

middleware

애플리케이션에서 사용될 middleware를 포함한다. middleware는 페이지 또는 레이아웃이 렌더링 되기 전에 실행이 되며, middleware를 페이지나 레이아웃에 바인딩하였다면 해당 페이지나 레이아웃이 실행되기 전에 매번 실행된다.

module

Nuxt Module은 Nuxt 프레임워크의 핵심 기능을 확장하고 통합 및 추가할 수 있다. 사용자가 직접 모듈을 작성할 수 있다.

pages

실제 애플리케이션의 페이지 구성을 포함하며 해당 디렉터리의 구조에 따라 router가 자동으로 생성된다. 해당 디렉터리는 이름을 변경할 수 없다.

plugins

애플리케이션에 바인딩될 외부 혹은 내부 plugins를 포함한다. plugins는 애플리케이션이 인스턴스 화 되기 전에 실행하며 전역적으로 구성 요소를 등록하고 함수 또는 상수를 삽입할 수 있다.

static

해당 디렉터리는 정적인 파일들을 포함한다. 구성에 따라서 html, Javascript 파일도 포함시킬 수 있다. 해당 디렉터리는 이름을 변경할 수 없다.

  • 프로젝트 루트 디렉터리에 직접적으로 bundled 됨
  • /filename으로 접근 가능
  • full url로 접근하면 static file을 assets file과 똑같이 취급할 수 있음. 그 말은 이 static file을 url loader가 핸들링한다는 것임
  • 따라서 항상 static file은 /filename으로 접근해야 함.

store

애플리케이션에서 사용될 vuex store 파일들을 포함한다. 기본적으로 비활성화 상태이고 store 디렉터리에 index.js 파일을 작성하면 store가 활성화된다. 구성에 따라서 모듈 형태의 store를 형성할 수 있다. 해당 디렉터리는 이름을 변경할 수 없다.

 

Nuxt.js LifeCycle

참조 : https://ko.nuxtjs.org/docs/2.x/concepts/nuxt-lifecycle/

 

처음 리퀘스트가 도착하면 서버사이드에서 nuxtServeInit, middleware, validate(), asyncData(), fetch() 등의 과정을 거쳐서 렌더링 한 뒤 완성된 페이지를 리스폰스로 보낸다. 그 이후에 페이지 이동은 페이지 갱신 없이 클라이언트에서 nuxt-link(Vue router의 router-link)를 통해 필요한 리소스만 통신으로 받아서 렌더링 한다. 첫 요청 후 페이지 이동은 클라이언트 사이드 렌더링을 하는 것이다.

말 그대로 server-side rendring + client-side navigation 두 가지 모두 사용한다.

nuxtServerInit

nuxtServerInit이 Store에 정의되어 있으면 Nuxt.js 는 콘텍스트 (서버 측에서만 해당)를 사용해 호출해야 한다. 서버의 데이터를 클라이언트에게 직접 주고 싶을 때 유용.

  • nuxtServerInit은 vuex action 메서드
  • Nuxt 라이프 사이클에서 nuxtServerInit 메서드가 맨 처음에 호출
  • dispatch 메서드가 호출한 대부분의 action 메서드들은 두 개의 인자를 가진다. 첫 번째는 vuex의 context이고, 나머지 하나는 dispatch 메서드에 의해 전달된 값이다.
  • fetch나 asyncData처럼 context를 인자로 가짐
  • 따라서 nuxtServerInit은 두 개의 context를 가지고 있는데, 하나는 vuex context이고 나머지 하나는 nuxt context이다.

middleware

middleware는 미리 정의된 함수이며, middleware를 사용하면 페이지 또는 레이아웃을 랜더링 하기 전에 실행할 수 있는 사용자 정의 기능을 정의할 수 있다.

  • 특정 페이지나 전체 페이지에 적용 가능
  • 주로 로그인 체크, 유효성 검사 등에 활용
  • 하나의 middleware는 하나의 js 파일에 정의되어야 함

특정 페이지에서 middleware를 사용할 경우 해당 페이지에 property를 직접 작성

전체 페이지에서 middleware를 사용할 경우 nuxt.config.js 에서 router property를 추가하고 그 안에 작성

validate()

  • 사용자가 제출한 모든 데이터는 validate 되어야 함. nuxt는 이걸 메서드로 제공함.
  • Validate method는. vue 파일들의 exported object에 설치되어야 함.
  • 참고로 Validate method는 _id.vue 에 설치되어야 함.
  • Validate method는 3가지 property를 가진 object를 argument값으로 가짐 - params, query, store(vuex로 접근 가능)
  • validate method는 유효성 검사를 위해서 존재한다. 그러니까 뭐 바꾸려고 하지 말자.
  • 리턴 값으로 true, false를 가지며 true일 경우 _id.vue 파일은 정상적으로 로드되지만 false의 경우 미리 정의되어있는 에러 페이지로 이동한다.

asyncData() & fetch(context)

asyncData()와 fetch() 메서드의 경우 차이가 궁금해서 더 공부를 했었다.

그래서 이 글에서는 간단히만 다룰 예정이고 따로 포스팅을 할 예정이다.

Nuxt 2.12 버전 이후의 fetch 또한 변경된 점이 있기 때문에 따로 포스팅을 하는 게 낫다고 판단했다.

 

asyncData()

  • validate()처럼 asyncData 도 context를 parameter로 받음.
  • 자동으로 호출. 따라서 백엔드 데이터에서 초기 데이터를 가져올 수 있는 역할을 할 수 있음.
  • validate 메서드 이후에 호출되지만 vue는 렌더링 되지 않았기 때문에 this를 가지지 않는다. 다시 말해서 asyncData 메서드가 호출될 때 뷰 컴포넌트는 생성되지도 않은 상태. 결과적으로 asyncData의 this는 컴포넌트의 인스턴스 정보를 get 해주지 않는다.
  • asyncData 메서드는 반환하는 결과가 vue의 data와 merge 됨. 그래서 asyncData 메서드에서 반환한 속성을 템플릿에 직접 표시할 수 있음.

fetch()

만약 데이터를 vuex로 완전히 핸들링하고 싶으면 어떻게 초기값을 얻을 수 있을까? 뷰에서는 created 메서드(lifecycle)를 사용하면 된다. 그런데 넉스트에서는 fetch, nuxtServerInit 메서드 두 가지 옵션이 있음. 이 두 메서드 자동으로 호출되지만 실행 시점이 다름.

  • fetch 메서드는 pages 파일에 인스톨된다.
  • 미들웨어나 asyncData처럼, fetch 메서드는 context를 인자로 받는다.
  • Context.params and context.query는 URL에 전달한 fetch 메서드 접근 권한을 부여
  • 따라서 url을 통해 전달된 데이터를 기반으로 fetch 실행
  • 예를 들자면, URL에 ID를 전달할 수 있는데 fetch 메서드는 이 ID를 백엔드에 보내고 그에 맞게 데이터베이스를 조회할 수 있음 (물론 asyncData() 도 params를 받을 수 있기 때문에 NuxtLink :to="`/${parameter}`" 해서 보내면 params.parameter로 접근이 가능하다.. 처음 얕게 공부하다 보니 이런 점들 때문에 asyncData()와 fetch()에 대해 무슨 차이지? 하는 생각이 많았다.)
  • 이렇게 조회한 데이터는 Context.store.commit()을 사용해 vuex로 보냄. Context.store.commit()는 fetch 메서드가 vuex mutaion 메서드를 트리거할 수 있게 허용함. mutation 메서드는 vuex의 state 프로퍼티를 set 하는 메서드임.

 

Nuxt를 공부하다 보니 Next와는 무슨 차이점이 있지? 어떤 장점이 있는거지? 라는 생각을 하게 되어 찾아보다 글을 하나 발견하였다. (Next도 사용해보지 않은 주니어 개발자 입장에서는 꿀 같은 글이었다.ㅎㅎ)

Next, Nuxt, Nest 비교

 

Choosing the right Node.js Framework: Next, Nuxt, Nest?

A handy examination of the differences between three very popular server-side rendering frameworks.

nodesource.com

 

Nuxt에 대한 자료가 많이 부족하다 보니 이런 글 하나하나가 소중하게 느껴진다.ㅎㅎ

 

앞으로 Nuxt로 프로젝트를 진행하면서 하나씩 포스팅해야겠다.

 

반응형

'FE > Nuxt.js' 카테고리의 다른 글

Nuxt.js Toast Ui Editor 적용  (1) 2021.04.26
Nuxt.js routing 알아보기  (0) 2021.04.23
Nuxt.js asyncData vs Fetch  (0) 2021.04.16
Nuxt.js 에서 Props 사용하기  (0) 2021.04.15
Nuxt.js 에서 Vuex Store 사용하기  (0) 2021.04.15

댓글