프로젝트

heroku로 React + json-sever 정적 웹 사이트 배포하기

minjaem 2023. 4. 15. 17:01

배포 순서

1. 폴더 구조 및 server 디렉토리 생성

1) 최상위에 Mock Api(json-server / json-server-auth)의 역할을 할 server 디렉토리를 생성한다.

2) 최상위에 db.json 이라는 파일을 만들어 db 역할을 할 데이터들을 json 형식으로 넣는다.

3) server 디렉토리로 이동해서 index.js 파일을 만들어 띄울 데이터 서버를 작성한다.

const jsonServer = require("json-server")
const auth = require("json-server-auth");
const path = require('path');

const app = jsonServer.create();
const router = jsonServer.router(path.resolve('./db.json'));
const middlewares = jsonServer.defaults({
  static: path.resolve('./build')
});
app.db = router.db;


app.use(
  jsonServer.rewriter({
    "/api/*": "/$1",
  })
);

app.use(middlewares)
app.use(auth);
app.use(router);

const port = process.env.PORT || 4001

app.listen(port, () => {
  console.log('sever is running')
});

2. 환경 변수 설정

 프론트엔드 서버의 endpoint가 localhost를 향하고 있다면, 로컬에서 서버를 계속 켜줘야 한다. 이를 방지하기 위해, 배포 환경에서는 배포 주소로 endpoint가 설정되어 있어야 한다.

 .env.development - .env.production 파일을 생성해서 설정해준다. 필자는 이때 배포 환경에서 endpoint는 '배포된 주소/api' 를 바라보게 작성했다. 예시는 아래와 같다.

// 예시 .env.production
REACT_APP_BASE_URL=https://natural-mood.herokuapp.com/api

3. pacakage.json scrpit 설정

 이제 최상위 폴더의 package.json을 아래와 같이 설정해 빌드와 배포를 위한 환경 구성을 해준다. 이때, 로컬 환경에서는 서버를 $ yarn start 명령어로 구동해주고, 클라이언트를 $ yarn start:dev 명령어로 구동시킨다.

 만약에, 정상적으로 작동하지 않는다면 에러 문구를 확인해보고 server를 찾을 수 없다는 에러가 발생하면 폴더 구조를 잘못 설정한 문제일 가능성이 높다. 폴더구조는 아래와 같이 구성되어 있어야 한다.

- server
    -- index.js
- package.js
- db.json
- src
-public
  {
      "scripts": {
        "start": "node server",
        "start:dev": "NODE_PATH=src react-scripts start",
        "build": "NODE_PATH=src react-scripts build",
        "test": "react-scripts test",
        "eject": "react-scripts eject",
        "heroku-postbuild": "NODE_PATH=src npm run build"
      }
  }

4. heroku 설치

 본인의 운영체제와 환경에 맞게 아래 링크를 통해 heroku CLI를 설치한다.

https://devcenter.heroku.com/articles/heroku-cli

5. heroku login

 heroku 홈페이지에서 회원가입을 하고, 로그인을 한다.

6. git 설정

1) git 설치 여부 확인 => 미 설치시

$ git init

2) 모든 변경사항 스테이징

$ git add .

3) 모든 스테이징 커멧

$ git commit -m "...."

7. heroku app 생성 (이때, app 네임은 도메인 네임에 포함된다.)

$ heroku create <app name>

8. devDependencies 설치 설정

$ heroku config:set NPM_CONFIG_PRODUCTION=false # devDependency

9. 이제 히로쿠에 올려보자!

$ git push heroku main(master) => 이때, main(master) branch로 이동해야 한다. 위치하는 branch name에 맞게 main/master 명령어로 작성하면 되고 다른 브랜치에서 배포하길 원할 경우에는 아래와 같은 명령어를 입력해준다.

$ git push heroku <branch name>:master(main)

 

부딪히고 해결한 나의 난관들...

1. 폴더구조 최상위 폴더 안에 server 디렉토리를 두어야 함

 처음에는 최상위 디렉토리에서 client와 server 디렉토리로 나누어서 각자 독립적으로 dependecy들을 관리했다. 배포 역시 독립적으로 할 수 있으리라 생각했지만, 오산이었다. 잘못된 폴더 구조에서 많은 에러들을 발견했다. 사실, 그 원인에는 정적 웹사이트를 어떻게 구성할 것이냐? json-server라는 fake api 서버를 어떻게 구동시킬 것이냐?에 대한 이해와 답을하지 못했다.

 heroku는 start scripts로 시작을 결정하기 때문에, package.json 구성에서 start scripts만 잘 작성하고, 서버를 띄울 index.js 파일만 잘 작성하면 정말 손쉽게 정적 웹사이트를 구성할 수 있다! 정말 간편하고 편리한 서비스다

Specifying a start script

To determine how to start your app, Heroku first looks for a Procfile. If no Procfile exists for a Node.js app, we will attempt to start a default web process via the start script in your package.json.

 

2. 에러처리

 에러는 친절하게 알려주기 때문에 에러 문구만 잘 읽는다면 충분한 원인 파악과 해결을 할 수 있었다. 예를 들어 빌드될 때 packagelock.json과 yarn.lock이 동시에 생겨서 dependency 문제가 발생할 우려가 있다든지, 폴더 구조가 잘못되어 start scripts 에서 파일을 찾지 못하는 에러였다.

 특히나, velopert 님의 글을 보면서 꽤나 손쉽게 배포하여 개인 프로젝트를 정적 웹사이트로 구현할 수 있었다.

 

참고)

https://redux-advanced.vlpt.us/3/09.html