Stack/Spring

[React / Spring 연동] IntelliJ 개발 환경 구축하기 (쉬움 + 자세한 설명)

7ingout 2023. 2. 16. 11:24

허접한 구상도

 

1. Spring Initializr에서 스프링 폴더 초기 생성

https://start.spring.io/

 

Dependencies에 Spring Web 추가 !!!

위와 같이 선택하고 GENERATE 누르면 압축파일이 만들어진다

 

2. 프로젝트 열기 ~

압축 해제 후 

클릭!

IntelliJ로 프로젝트가 열리면서 자동으로 빌드가 된다 !

spring Initializer에서 Dependencies에 Spring Web 추가를 했었다

= Spring Web에는 내장톰캣이 있다

= 톰캣을 따로 설치 안 해도 됨

= 서버를 따로 설치 안 해도 됨

= 실행만 누르면 localhost:8080에 뜬다는 말

 

그 증거는!

오른쪽에 Gradle 눌러서 저기 가보면 tomcat 있다 허허

 

3. back-end(Spring) 실행시켜 보기

나는 여기서 헤맸다 .. 

상단에 저 Run만 누르면 당연히 원래 나와야 하는 화면(밑의 사진)이 나올 줄 알았는데,

올바르게 실행된 화면

 

밑과 같은 화면이 나왔다 🙃

망한 화면

그 이유는 .. 스프링 똥멍청이가 찾기엔 어려웠다 (구글링해도 안 나옴)

스프링 하는 사람들이 보면 이걸 왜 몰라? 하는 정말 어이없는 그런 느낌이겠지

 

저 화면은 localhost:8080 서버가 실행 안 돼서 뜨는 화면이다

내장톰캣 있다 했으면서 왜 서버 실행이 자동으로 안되지 정말 큰 의문이었다

8080 검색을 해봤지만 눈을 씻고 찾아봐도 없었다

 

그 이유는 바로 ....

저!!! 애플리케이션 있는 저 파일(main/java/com/demogroup/demoweb)을 열고 Run을 누르면!! 

 

로컬 8080 서버가 잘 실행되는 것을 볼 수 있다 😭

 

굉장히 에러페이지 같지만 이렇게 떠야 맞는 거다 😀

 

4. 리액트 설치(front-end 작업)

밑의 Terminal을 열고 리액트 설치 !

cd src/main
npx create-react-app frontend

 

리액트 폴더가 생성된다 ~

 

리액트를 한번 실행시켜 보겠다

그전에,

cd frontend

생성한 frontend 폴더로 간 후 npm start로 실행한다!

 

npm start

익숙한 화면

 

5. cors 에러 방지

웹 개발하면서 한 번은 무조건 마주치는 cors 에러 ..

이를 방지하기 위해 Proxy 설정을 할 것이다

 

* cors 에러 마주치는 이유

원칙적으로 도메인이 서로 다른 것들끼리는 데이터를 주고받을 수 없게 되어있다

리액트 서버는 localhost:3000 도메인 사용

Spring 서버는 localhost:8080 도메인 사용

서로 다른 도메인을 사용하고 있으므로 에러 발생

 

해결방법은 간단하다!

리액트 폴더에 package.json에 밑을 입력

 

"proxy": "http://localhost:8080"

3030 도메인을 사용하는 리액트에서 나 이제 8080(스프링 서버 도메인) 허락한다 ~ 하는

구문 하나 추가하면 된다.

 

다른 방법 (http-proxy-middleware 설치해서 프록시 설정)도 있지만 이게 젤 간단하다

 

6. front-end에서 axios를 이용해 back-end 데이터 가져오기 !

⭐ 리액트 폴더인 frontend 폴더를 간 후 ⭐

npm install axios --save

axios 설치!

axios는 비동기 통신을 가능하게 해주는 아이

 

- 프론트엔드

리액트 폴더 내의 app.js(frontend/src)

// src/main/frontend/src/App.js

import React, {useEffect, useState} from 'react';
import axios from 'axios';

function App() {
   const [hello, setHello] = useState('')

    useEffect(() => {
        axios.get('/api/hello')
        .then(response => setHello(response.data))
        .catch(error => console.log(error))
    }, []);

    return (
        <div>
            백엔드에서 가져온 데이터 : {hello}
        </div>
    );
}

export default App;

 

- 백엔드

demoweb폴더 내에 Controller라는 패키지 생성

 

그 밑에 HelloWorldController란 이름의 클래스 파일 생성!


그럼 이런 모양이 된다

 

.HelloWorldController.java(com/demogroup/demoweb/Controller)

// src/main/java/com.demogroup.demoweb/Controller/HelloWorldController.java

package com.demogroup.demoweb.Controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController //Tip : @RestController = @Controller + @ResponseBody
public class HelloWorldController {

    @GetMapping("/api/hello")
    public String test() {
        return "Hello, world!";
    }
}

/api/hello 경로에 Hello, world 출력되게 ! (GepMapping 어노테이션 사용)

 

그럼 모든 준비 끝 ..

 

 

먼저 백엔드 데이터 잘 나오는지!

DemoWebApplication을 실행시켜 줍니다.

위의 방법처럼 상단에 있는 Run 버튼을 눌러도 되고

아래 그림처럼 밑의 Run을 눌러도 된다.

 

경로는 localhost:8080/api/hello

잘 만들어진 hello API

 

프론트 엔드(백엔드 데이터 잘 받아오는지 확인!)

Terminal에서 frontend로 경로 옮긴 후(cd frontend) npm start!!!

완벽

 

⭐ 백엔드 서버가 실행되고 있어야 데이터 잘 받아 옴 ⭐

 

7. 빌드하기(둘 다 실행시킬 필요 없이 서버만 키면 locahost:3030 프론트엔드 내용 같이 나오도록!)

= localhost:8080만 들어가면 내용 뜨도록

build.gradle 파일의 하단에

def frontendDir = "$projectDir/src/main/frontend"

sourceSets {
	main {
		resources { srcDirs = ["$projectDir/src/main/resources"]
		}
	}
}

processResources { dependsOn "copyReactBuildFiles" }

task installReact(type: Exec) {
	workingDir "$frontendDir"
	inputs.dir "$frontendDir"
	group = BasePlugin.BUILD_GROUP
	if (System.getProperty('os.name').toLowerCase(Locale.ROOT).contains('windows')) {
		commandLine "npm.cmd", "audit", "fix"
		commandLine 'npm.cmd', 'install' }
	else {
		commandLine "npm", "audit", "fix" commandLine 'npm', 'install'
	}
}

task buildReact(type: Exec) {
	dependsOn "installReact"
	workingDir "$frontendDir"
	inputs.dir "$frontendDir"
	group = BasePlugin.BUILD_GROUP
	if (System.getProperty('os.name').toLowerCase(Locale.ROOT).contains('windows')) {
		commandLine "npm.cmd", "run-script", "build"
	} else {
		commandLine "npm", "run-script", "build"
	}
}

task copyReactBuildFiles(type: Copy) {
	dependsOn "buildReact"
	from "$frontendDir/build"
	into "$projectDir/src/main/resources/static"
}

코드 추가 후 저장!!

 

위 코드 해석하면

SpringBoot (Back-End)와 React (Front-End)를 하나의 패키지로 만들자

SpringBoot 빌드될 때 React가 먼저 빌드되고,

결과물을 SpringBoot 빌드 결과물에 포함시킨다는 내용

 

터미널을 열고 프로젝트 가장 상위 디렉터리(demo-web)로 가서,

./gradlew build

명령어 실행 !

 

build/libs/demo-web 어쩌고 jar파일이 생성되었으면

빌드 성공이다!

 

서버 다시 run 시킨 후 localhost:8080만 들어가면

 

 

!!!!! 끝 !!!!!

 

최종 구조(?)

 

 

 

참고

https://velog.io/@sians0209/Spring-%EB%A6%AC%EC%95%A1%ED%8A%B8-%EC%8A%A4%ED%94%84%EB%A7%81-%EC%97%B0%EA%B2%B0

 

[Spring] 리액트 스프링 연결

리액트 스프링부트 localhost:8080으로 연결하기

velog.io

https://velog.io/@u-nij/Spring-Boot-React.js-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD-%EC%84%B8%ED%8C%85

 

Spring Boot + React.js 개발환경 연동하기

Spring Boot와 React.js를 연동해 개발환경을 만들고, 빌드해서 jar 파일로까지 만들어보는 과정입니다.

velog.io