Nest.js + Next.js 함께 쓰기

readbetweenthelines
6 min readApr 28, 2020

--

30분만 해보기

Nest 프로젝트에서는 Angular Universal SSR 을 사용할 수 있지만 React SSR 라이브러리인 Next.js 를 통합할 수 있도록 도와주는 nest-next 라이브러리가 있습니다. 이를 통해 Next와 Next 를 통합하는 설정 방법을 살펴봅니다.

프로젝트 생성

$ nest new with-nest-next-ssr && cd with-nest-next-ssr
$ code .

Next 와 nest-next 라이브러리 설치

$ npm install next react react-dom @types/react @types/react-dom nest-next // next page 디렉토리 생성
$ mkdir -p public pages pages/views

nest-next 라이브러리는 페이지뷰 렌더링시 Next 에 넘겨주는 역할을 합니다.

실행 스크립트 수정

// package.json
...
"build": "nest build -p tsconfig.server.json",
"start": "nest start -p tsconfig.server.json",
"start:dev": "nest start -p tsconfig.server.json --watch",
"start:debug": "nest start -p tsconfig.server.json --debug --watch",
...

타입스크립트 컴파일 설정 수정

$ rm -f tsconfig.build.json
// tsconfig.json
{
"compilerOptions": {
"experimentalDecorators": true,
"target": "esnext",
"module": "esnext",
"lib": [
"dom",
"dom.iterable",
"esnext",
],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"allowSyntheticDefaultImports": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"removeComments": false,
"preserveConstEnums": true,
"sourceMap": true,
},
"exclude": [
"node_modules",
"dist"
],
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx"
]
}
// tsconfig.server.json
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "commonjs",
"declaration": true,
"removeComments": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"target": "es2017",
"sourceMap": true,
"outDir": "./dist",
"baseUrl": "./",
},
"exclude": ["node_modules", "test", "dist", "**/*spec.ts"],
"include": ["src"]
}

앱 모듈에서 렌더링 설정

// src/app.module.ts
...
import Next from 'next';
import { RenderModule } from 'nest-next';
@Module({
imports: [
RenderModule.forRootAsync(Next({ dev: process.env.NODE_ENV !== 'production' })),
],
controllers: [AppController],
providers: [AppService],
})
...

앱 모듈 실행시 Next 가 실행되도록 설정합니다. (.next 디렉토리에 생성)

컨트롤러 작성

// src/app.controller.ts
...
import { Controller, Get, Render } from '@nestjs/common';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get()
@Render('Index')
public index() {
// Index.InitialProps 에 전달.
return {
title: 'Nest with Next',
};
}
...

응답할 렌더링 페이지를 설정하고 InitialProps 에 응답 데이터를 전달합니다.

페이지뷰 작성

// pages/views/Index.tsx
import React from 'react';
import { NextPageContext } from 'next';
import Head from 'next/head';
type IndexProps = {
query : {
title: string
}
}
export default function Index(props: IndexProps) {
const { title } = props.query;
return (
<>
<Head><title>{title}</title></Head>
<div>
타이틀은 {title} 입니다.
</div>
</>
)
}
Index.getInitialProps = async function (context: NextPageContext) {
const { query } = context;
return { query }
}

브라우져에서 타이틀 값을 확인해 봅니다.

꿀 잠자러 가야겠습니다.

참고

GitHub — kyle-mccarthy/nest-next: Render Module to add Nextjs support for Nestjs
Next + Nest: Working together — Real Dev Engineering — Medium Angular

--

--