Java & Spring

React + Spring 통합 빌드 시 CSR(Client Side Routing) 문제

ju_young 2024. 5. 17. 16:08
728x90

build.gradle에 다음과 같이 node에 대한 build 설정을 추가해주면 빌드 시 react까지 같이 빌드한다.

plugins {  
    ...
    id "com.github.node-gradle.node" version "5.0.0"  
}

...

node {  
    nodeProjectDir = file("<frontend(react) directory path 입력>")  
    version = <node version 입력>  
    npmVersion = <npm version 입력>  
    download = true  
}  

//react build  
task npmBuild(type: NpmTask) {  
    args = ['run', "build"]  
}  

//static copy  
task copyFrontEnd(type: Copy) {  
    from "<빌드된 frontend(react)가 저장되는 directory(e.g. dist) path 입력>"  
    into 'build/resources/main/static/.'
}  

npmBuild.dependsOn npmInstall  
copyFrontEnd.dependsOn npmBuild  
compileJava.dependsOn copyFrontEnd

Spring Boot 애플리케이션을 실행하고 http://localhost:8080에 이동하면 react(프론트)에서 구현한 메인페이지가 화면에 표시된다.

문제 발생

react-router-dom의 Link 태그를 사용하여 oauth 로그인 URL을 지정해주었다.

<Link  
  to={`${API_URL}/oauth2/authorization/kakao`}  
  className="cursor-pointer shadow-md border border-green-brunswick p-2 rounded-full mr-1"  
>  
  <Kakao style="w-4 h-4" />  
</Link>

API_URL은 http://localhost:8080이 될 것이고 카카오 아이콘 버튼을 클릭하면 카카오 로그인 페이지로 이동하거나 로그인 요청이 될 것이라고 기대할 수 있다.

 

하지만 주소 창에 URL만 변경될 뿐 페이지 이동이 되지 않았다.

 

원인은 프론트엔드의 도메인 URL과 백엔드엔드의 도메인 URL이 일치하여 해당 URL이 백엔드에 요청되어야하는지 프론트엔드에 요청되어야하는지 혼동이 발생했다고 판단할 수 있었다.

해결 방법

  1. Link 태그의 reloadDocument를 적용하거나 a 태그를 사용해서 페이지를 새로고침
    • 페이지를 새로 불러오게되면서 state 또는 component들이 초기화된다는 문제가 발생
  2. 프론트엔드와 백엔드의 포트를 다르게 설정
    • 프론트엔드와 백엔드의 포트를 각각 다르게 설정함으로써 각 애플리케이션의 역할이 명확해짐
    • Proxy(Nginx)를 사용하여 Client Side Routing과 Server Side Routing 간의 간섭을 최소화

결과

통합 빌드를 적용하지 않고 프론트엔드와 백엔드 각각 따로 실행하며 포트를 다르게 설정하여 개발을 진행하고, AWS에 배포를 하게될 경우 프론트엔드는 S3에 정적 호스팅을 하도록 했다. 그리고 nginx에는 "/"는 프론트엔드로 라우팅, "/api/v1"은 백엔드로 라우팅하도록 설정해주었다.

...
location / {
    proxy_pass <S3 URL>
}

location /api/v1/ {
    proxy_pass <EC2(백엔드 서버) URL>
}
728x90