react build한 파일들과 express에 연결하기

이태혁·2020년 6월 29일
4

의문의 시작: build/index.html을 실행해도 아무것도 안 나와요

상황: Create React App을 통해 프론트를 구현하고 npm run build를 통해 정적파일도 생성했다. 하지만 build/index.html 파일을 열면 새하얀 페이지만 나오고 아무것도 안나온다. expresss와 어떻게 합쳐야 할까?

1. 일단 build/index.html은 어떻게 열어볼 수 있을까?

  • index.html이 안 열리길래 처음에는 npm run build가 제대로 작동 안 된줄 알았다.

  • 그래서 npm run build를 엄청 여러번해봤는데도 결과는 똑같다.

  • 그러다가 우연히 npm run build 후에 다음과 같은 지시사항이 나오는것을 발견했다.

  • 똑같이 serve -s build를 쳐보았다.

    • 이 명령어가 안되면 server 패키지가 없어서 그럴 수 있다.
    • npm i -g serveserve를 먼저 깔아줘야 한다.
  • 따라해보니 Serving이라는 메세지와 함께 5000번 포트에서 제대로 작동한다.

일단 index.html파일(또한 build폴더안에 있떤 파일들)이 정상이라는 사실을 알아냈고 실행도 했지만 여기서 2가지 의문이 들었다.

2-1. 왜 index.html을 바로 열었을때는 실행이 안 됐을까?

2-2. express(nodejs 백엔드 프레임워크)와는 어떻게 연결해야 할까?

2-1. 왜 index.html을 바로 열었을때는 실행이 안 됐을까?

  • 거의 똑같은 질문을 Stack Overflow에서 찾아냈다. Stack Overflow 해당질문

  • 아직 이론적인 부분이 부족해서 제대로 이해했는지는 모르겠지만 정리해보자면

index.html을 바로 실행할 수 없다. 왜냐하면 그 파일은 static file server와 함께 있어야 하기 때문이다. 대부분의 React app들은 클라이언트 사이드 라우팅을 하므로 file://URL으로 실행할 수 없다.

  • file://은 local 컴퓨터에 있는 파일 위치의 경로를 말하는것 같다.(즉 로컬경로를 그대로 주면 실행이 안된다는 말인듯?)

배포 상황일때: (리액트 앱을 돌리기 위해서는 ) Nginx, Apache, Node와 같은 정적 파일들을 serving 할수 있는 서버를 사용하면 된다. 만약 리액트에서 클라이언트 사이드 라우팅을 구현했다면 index.html/로 들어온 요청이 아닌 /*로 들어온 요청에 응답할 수 있다.

개발 상황일때: pushstate-server를 사용하면 된다. 이것도 클라이언트 사이드 라우팅에 잘 작동한다. 이게 npm run build을 했을 때 나오는 지시사항에서 말하는것이다.

  • 아마 이게 serve -s build를 말하는 것 같다.

열심히 읽어봤는데 static server와 관련이 있는것 같긴한데 정확히 모르겠다. 다른것들을 뒤져봐도 아직 모르는 상태이다. 나중에 알게되면 업데이트 해야겠다. 이제 2번째 의문으로 넘어가자.

2-2. express(nodejs 백엔드 프레임워크)와는 어떻게 연결해야 할까?

이해는 나중으로 미루더라도 일단 Create React App에서 만든 결과물과 express를 연결해야만 한다. 여러 사이트들을 뒤져봤는데 제일 도움이 됐던 사이트를 추가한다.

둘다 비슷한 내용인것 같은데 express에서 build/index.html을 불러올때 static으로 설정해야한다.

  • 여기서 static을 app.use(express.static(path.join(__dirname, '../front/build'))) 이런 명령어로 설정해준다.
    • express를 배울 때 이것은 css, js, img파일같은 정적파일들을 어느 폴더에서든 경로설정 필요없이 접근할 수 있게 만들어주는 것이라 배웠다.
    • (추측) 아마 build/폴더안에 있는 내용물들을 index.html이 불러와야 하는데 경로가 static으로(어디서든 불러올수 있는 경로로) 설정되어 있어서 그냥 부르면 안된게 아닐까 싶다.

이제 해결한 방법을 말해보면

  1. 먼저 react쪽에서 npm run build를 통해 정적파일들 폴더인 build/ 폴더를 생성한다.(이미 생성했으면 생략)

  2. 익스프레스에서 제일 메인이 되는 app.js파일에
    app.use(express.static(path.join(__dirname, '../front/build')));
    요거 한줄 추가하기 (build폴더를 static으로 설정, 여기서 '../front/build'app.js에서 build/폴더로 가능 상대경로이다.)

  3. 그리고 리액트를 실행하고 싶은 라우터에서
    (라우터를 사용하지 않으면 app.js에 바로 해도 된다. )
    (나같은 경우는 index.js에서 했다. 다른 라우터에서 하고싶으면 그곳에서 해도 된다.)
    res.send(express.static(path.join(__dirname, '../../front/build/index.html')));

    요렇게 추가해준다.

  4. 그리고 npm run start등 express의 엔트리 파일을 실행시켜주면 잘 작동한다.

profile
back-end, cloud, docker, web의 관심이 있는 예비개발자입니다.

1개의 댓글

comment-user-thumbnail
2020년 11월 20일

안녕하세요. 맨 마지막 3번 코드 틀린 코드 아닌가요? 정상적으로 작동하시나요?

답글 달기