Next.js 개발 경험기

Lemonade Engineering
Lemonade engineering
9 min readFeb 15, 2021

Author: taehoon

Next.js란?

→ 많은 분 들이 아시다시피 SSR을 베이스로한 React Framework 이다.

하지만 SSR 과 SEO 빼면 사용할 이유가 없다. 라고 하시는 분들 , Next 를 아직 접해보지 않으신 분들이 참고하면 좋을듯 하다.

Next.js 를 알기전 , 만든 회사에 대해서도 알고 있으면 좋다.

Zeit → Vercel 으로 탈바꿈 함으로써 아이텐티티를 재 정립 할 수있는 계기가 되었다. 시리즈 A 투자를 받으며2,100 만 달러 를 확보 함으로써 Next의 탄력적인 성장을 기대할 수 있다.

실제로 Next.js는 2,3 개월 주기로 꾸준한 버전 업을 진행중이며 , 2018년 5버전부터 2020년 10버전까지 놀라운 속도의 버전업을 볼 수 있었다.

Vercel 이 가지고 있는 개발 서비스 철학에 대해서 알아보자.

  • zero-config
  • best developer experience

핵심은 생산성과 간편화라고 생각한다. vercel의 철학에 공감했으며 , front/back 구분 할 거없이 framework 가 관심을 받고 있다. react , vue / express , koa 등에서의 고민을 덜어주기 위한 Next / Nest framework 의 장점이 사람들을 움직이기에 충분 했다고 생각한다.

Vercel 를 통해 client / server / serverless 배포까지 모두를 경험 할 수있어서 이 부분은 참고해보면 좋을듯하다.

https://vercel.com/docs/introduction

서론이 길었고 , 본격적으로 내가 FCL에서 next.js 기반으로 웹 어플리케이션을 만들면서 느꼈던 장단점에 대해서 적어보겠다.

1.페이지 라우트에 기반한 파일 시스템

→ 다소 강압적인 파일 시스템은 나한테는 좋은 방면으로 작용되었다. Next를 만나기전 파일시스템 구조에 대해서 생각 하는 부분도 꽤나 큰 리소스가 들어갔다. 1차원적으로 파일시스템 기반을 잡아주니 , 이후에 파생되는 2,3차원의 구조는 조금 더 명확했다.

그 외의 장점들

page 내의 파일명을 토대로 url을 정해주는 이득도 있다.

  • 파일명을 기준으로 url setting
  • code spliting (route 별 자동 code spliting)
_app.js
_document.js
signin.js
components
|-- button
|-- header
|-- Desktop.js
|-- Mobile.js
|-- action / reducer
pages
|-- buy
|-- cart
|-- event
.....

→Next.js open source 에서도 이와 같은 형태를 가지고 있기때문에 코드를 파악하고 이해하는데도 명료 했다.

2.강력한 내장 지원 기능

Next 에서는 내장으로 지원되는 기능이 많다. 현업에서 사용해본 기술 과 경험을 토대로 작성해봤다.

  • Environment Variables

variables 로는 3가지 옵션이 있다. 서버 / 클라이언트 노출여부에 따라서도 variable를 정하면 된다.

.env.* 의 형태로 원하는 값 지정을 해줄 수 있고. jest 나 cypress 같은 test enviroments도 자동 체킹을 해준다. 이런 장점을 이용해 axios mocking / action creator test / e2e test 를 간편한 환경에서 할 수 있다.

NEXT_PUBLIC_ANALYTICS_ID=abcdefghijs // 브라우저 환경에 노출 NEXT_PUBLIC
//env.local
HOSTNAME=localhost // 오직 node 환경에서 노출
process.env.NODE_ENV === 'test' // test enviroment
  • next development mode / production build

Next.js 에서는 명확한 책임분할 원칙을 가지고 있다.

이와같이 dev/production 의 차이를 명확히 인지 할 수 있다.

dev server에서는 최대한의 속도와 생산성 , production 은 최적화와 효율성 의 원칙을 지켰다는 점을 느꼈다.

(typescript compile check 같은경우에는 내장지원 되면서 추가됐지만 , 속도의 이슈로 제거한 것으로 알고있다)

개인적으로 이 부분은 아쉽다.

No TypeScript error overlay in development after updating to 9.4 · Issue #12735 · vercel/next.js

ServerSideProps , getStaticProps , getInitalProps,

  • getInitalProps

-universal method 이다. serverside , next/router(client side) 두가지 모두 호출 될 가능성이 있기때문에

이 점에 유의해야한다.

(document에서는 getInitalProps 대신 getStaticProps나 getServerSideProps를 사용하기를 권장한다.)

다음은 styled components CSS when doing serverside example이다. getStaticProps로 대체가능

import Document from 'next/document';
import { ServerStyleSheet } from 'styled-components';
export default class MyDocument extends Document {
static async getInitialProps(ctx) {
const sheet = new ServerStyleSheet();
const originalRenderPage = ctx.renderPage;
try {
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (App) => (props) => sheet.collectStyles(<App {...props} />),
});
const initialProps = await Document.getInitialProps(ctx);
return {
...initialProps,
styles: (
<>
{initialProps.styles}
{sheet.getStyleElement()}
</>
),
};
} catch (error) {
console.error(error);
} finally {
sheet.seal();
}
}
}

Styled-components ServerStyleSheet이 스타일 시트 의 인스턴스를 생성한 뒤 .

이 스타일 시트 내부의 모든 구성 요소에있는 <App /> 의 모든 스타일을 검색한다

그런 다음 Html나중에 템플릿에 전달 된다.

_document.js = 사용자 지정 Document은 일반적으로 애플리케이션 <html>및 <body>태그 를 보강하는 데 사용된다.

sheets.collectStyles = 앱의 구성 요소에서 모든 스타일을 수집한다

sheets.getElement() = 스타일 태그를 생성하고 호출 된 props로 반환한다.

  • getStaticProps
  1. 매 유저의 요청마다 fetch할 필요가 없는 데이터를 가진 페이지를 렌더링 할때
  2. headless CMS로 부터 데이터가 올때
  3. 유저에 구애받지 않고 퍼블릭하게 캐시할 수 있는 데이터
  4. SEO 등의 이슈로 인해 빠르게 미리 렌더링 해야만 하는 페이지. getStaticProps는 HTML과 JSON파일을 모두 생성해 두기 때문에, 성능을 향상시키기 위해 CDN 캐시를 하기 쉽다.
  • getServerSideProps
  1. 각 요청마다 데이터를 가져옴
  2. getServerSideProps는 서버사이드에서만 실행되고, 절대로 브라우저에서 실행되지 않는다.
  3. getServerSideProps는 매 요청시 마다 실행되고, 그 결과에 따른 값을 props로 넘겨준 뒤 렌더링을 한다.
  4. next/link를 이용해서 클라이언트 사이드 페이지 트렌지션을 하더라도, getInitialProps와는 다르게 무조건 서버에서 실행된다.
  5. 당연히 page 에서만 실행할 수 있다.
export async function getServerSideProps(context) {
return {
props: {}, // will be passed to the page component as props
}
}

컨텍스트 하위 키.

  • params : 이전에 나온 내용과 동일
  • req : HTTP 요청 객체
  • res : HTTP 응답 개체
  • query : 쿼리 문자열

정적 생성과 serverside rendering의 차이점을 더 알고 싶다면 doc 를 참고 바란다.

3. 3rd party library

Framework 의 단점이라면 낮은 자율성과 높은 종속성이 떠오른다.

하지만 공식 document 에서 외부라이브러리를 적용할 예시를 쉽게 보여줬다는 점이 좋았다.

CSS-in-JS 방식만 해도 9개 라이브러리를 지원하며 , CSS-in-CSS

CSS(지원), SASS npm install sass (지원) , LESS(내장지원예정) 등 다양한 자유도를 가지고 있어 취향에 따라 선택하면 된다.

하지만 지원하지 않는 라이브러리 , 커스터마이징이 필요한 부분은 적용하기 매우 힘들었다.

4. 지속적인 발전

Next.js 기반 우리회사의 첫 서비스는 2020년 11월에 출시했다.(당시 next 버전 9.5)

벌써 10.0.5 버전이 나왔고 , 많은 기능들이 추가적으로 지원됐다.

이 두가지가 매력적이었다.

매번 고민해야하는 image compression 을 next 가 내장지원 기능으로 추가했다!

구글 크롬팀과의 합작을 통해 코드 스플리팅 , 코어 성능 향상 등을 하며 javascript bundle size 를 70퍼센트 이상 줄였다고 한다.

등 10가지가 넘는 기능이 나왔고 , 공식 document 에서 그 내용을 찾아 볼 수있다.

사용하기 전 현재 버전과 지원 버전을 정확히 인지하고 가야한다.

다음 기회가 된다면 SSG / image optimization / module.css / next.js analytics 등을 소개해 보고 싶다.

next 를 아직 사용해보지 않았다면 next document 를 정독해보고 사용해보길 적극 권장한다.

--

--

Lemonade Engineering
Lemonade engineering

레모네이드 개발팀 기술 블로그입니다. This is an engineering blog from Lemonade Engineering.