만족

[Nextjs] express 프로젝트에 Nextjs 추가하기 본문

[Nextjs] express 프로젝트에 Nextjs 추가하기

FrontEnd/Nextjs Satisfaction 2021. 8. 21. 20:02

기존의 expressjs프로젝트에 페이지 렌더링 기능이 필요해 Nextjs를 사용했다.

 

통신 구조

 

여기에서 Client가 3006포트로 요청을 하면, 

nextjs 프로젝트에서 리버스 프록싱을 통해 express 프로젝트에 관련 데이터를 요청하고 클라이언트에게 페이지를 반환한다.

 

클라이언트는 express(PORT 3002)와 직접 통신할 필요가 없다.

 

만약 클라이언트가 API 호출을 원한다면 아래와 같이 통신한다.

클라이언트가 api서버와 통신하길 원한다면, nextjs를 거치지 않고 express와 통신할 수 있다.

 

express프로젝트에 nextjs추가

yarn add react react-dom next
or
npm install react react-dom next

필요한 세 개의 모듈을 추가한다.

 

bin/www 수정

express프로젝트를 배포할 때, node bin/www 명령을 통해 www를 실행시킨다.

 

이 www는 서버를 생성하고 지정한 포트로 들어온 요청을 listening한다.

 

우선 bin폴더에 next-server.js 파일을 만든다.

const http = require("http");
const next = require("next");

const dev = process.env.NODE_ENV !== "production";
const nextApp = next({ dev });
const handle = nextApp.getRequestHandler();
const nextPort = "3006";

nextApp
  .prepare()
  .then(() => {
    http.createServer((req, res) => handle(req, res)).listen(nextPort);
  })
  .catch(e => {
    console.log("cannot prepare next", e);
  });

next-server.js는 3006포트에 들어온 요청을 처리할 수 있는 서버를 생성한다.

 

이제 www파일의 맨 마지막에 다음 코드를 추가한다.

 

//...

require('./next-server');

node bin/www 명령을 통해 express와 nextjs 프로젝트 서버를 동시에 생성할 수 있게 되었다.

 

pages추가

nextjs는 라우팅을 pages폴더 구조에 따라 진행한다.

 

만약 localhost:3006/home 으로 접속했을 때, nextjs는 /pages/home.js을 실행한다.

 

프로젝트 루트에 pages폴더를 추가하고, home.js를 만들자.

// /pages/home.js
import React from "react";

const Home = () => {
  return <div>HI</div>;
};

export default Home;

정상적으로 작동한다.

 

express와 통신

기존에 express에 만들어진 /routes 하위에 있는 엔드포인트들과 통신해 보자.

 

우선 테스트로 /routes/index.js를 만들고,

/pages/home.js가 그것을 호출해서 페이지를 렌더링할 것이다.(SSR)

 

// /routes/index.js

const express = require("express");
const router = express.Router();

router.get("/", function(req, res, next) {
  res.status(200).send({
    message: "im expressjs"
  });
});

module.exports = router;

 

이제 다시 /pages/home으로 돌아가서 리버스 프록싱을 이용해 express의 엔드포인트를 호출할 것이다.

 

import React from "react";
import axios from "axios";

const Home = ({ message }) => {
  return <div>{message}</div>;
};

export default Home;

export async function getServerSideProps({ query, req, res }) {
  const message = await axios
    .request({
      url: `http://localhost:3002/`,
      method: "GET"
    })
    .then(res => {
      return res.data.message;
    })
    .catch(e => e.message);

  return {
    props: { message }
  };
}

getServerSideProps에서는 페이지를 리턴하기 전 필요한 동작을 정의한다.

 

express서버와 통신하고, 그 결과를 Home의 props로 넘겨주는 동작을 정의한다.

(http통신을 위해 axios를 사용하였지만, 다른 라이브러리나 fetch를 사용해도 좋다)

 

정상적으로 동작한다.

 

배포

express프로젝트는 별도의 빌드 과정이 없이 npm run start 명령을 통해 배포할 수 있었다.

 

그러나 nextjs는 build를 요구한다.

 

따라서 package.json을 다음과 같이 수정한다.

//...
"script": {
  "start": "NODE_ENV=production node bin/www",
  //prestart를 통해 start명령 실행 전 next build를 실행시킨다
  "prestart": "next build",
  //...
},
//...

이제 서버에서 npm run start를 실행하면 배포가 완료된다.



Comments