SpringBoot 3.0.12
Gradle
H2 2.1.214
SDK 17
IDE IntelliJ
MacOS
진한 글씨 : 실행한 코드
npm install -g create-react-app
오류:npm WARN deprecated tar@2.2.2
-> tar version이 낮아서 생긴 오류
tar 최신 버전 다운로드
npm install tar@6 -g
근데 해결 안됨. 포기.
1차 블로그의 react 설치하기까지 진행 후 2차 참고 블로그 진행
bootstrap 설치 (css)
npm install bootstrap react-bootstrap --save
react-router-dom 설치
npm install react-router-dom --save
axios 설치
npm install axios --save
build.gradle 수정 (spring 실행시 react도 같이 build되도록)
plugins {
id 'org.springframework.boot' version '2.6.1'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
id 'war'
####################### 추가 #######################
id "com.moowork.node" version "1.3.1"
####################### 추가 #######################
}
####################### 추가 #######################
apply plugin: "com.moowork.node"
####################### 추가 #######################
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
test {
useJUnitPlatform()
}
####################### 추가 #######################
def webappDir = "$projectDir/src/main/frontend"
task appNpmInstall(type: NpmTask) {
workingDir = file("${webappDir}")
args = ["run", "build"]
}
task copyWebApp(type: Copy) {
from 'src/main/frontend/build'
into "build/resources/main/static"
}
copyWebApp.dependsOn(appNpmInstall)
compileJava.dependsOn(copyWebApp)
####################### 추가 #######################
추가 해야하는 코드
id("com.moowork.node") version "1.3.1"
apply(plugin = "com.moowork.node")
tasks {
val webappDir = "$projectDir/src/main/frontend"
register<NpmTask>("appNpmInstall") {
workingDir = file(webappDir)
args = listOf("run", "build")
}
register<Copy>("copyWebApp") {
from(webappDir.resolve("build"))
into("build/resources/main/static")
}
getByName("compileJava") {
dependsOn("copyWebApp")
}
}
NpmTask 객체를 찾지 못함 (moowork에 있는 객체)
의존성에 추가로 삽입
implementation("com.moowork.gradle:gradle-node-plugin:1.3.1")
에러 발생 : Could not find com.moowork.gradle:gradle-node-plugin:1.3.1.
maven (url="https://plugins.gradle.org/m2/")
implementation("com.github.node-gradle:gradle-node-plugin:3.1.0")
subprojects{
apply(plugin= "com.github.node-gradle.node")
}
여전히 Unresolved reference: NpmTask 에러 발생
->Gradle 7.0 이후 버전에서는 NpmTask가 제거
register("appNpmInstall") 코드 수정
register<com.moowork.gradle.node.npm.NpmTask>("appNpmInstall")
버전이 달라져 함수도 달라짐
해결 안됨. 포기.
실패 코드
plugins {
java
id("org.springframework.boot") version "3.0.12"
id("io.spring.dependency-management") version "1.1.3"
id("com.moowork.node") version "1.3.1"
}
apply(plugin = "com.moowork.node")
group = "com.perfume-pedia"
version = "0.0.1-SNAPSHOT"
java {
sourceCompatibility = JavaVersion.VERSION_17
}
configurations {
compileOnly {
extendsFrom(configurations.annotationProcessor.get())
}
}
repositories {
mavenCentral()
maven (url="https://plugins.gradle.org/m2/")
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation("org.springframework.boot:spring-boot-starter-thymeleaf")
implementation("org.springframework.boot:spring-boot-starter-validation")
implementation("org.springframework.boot:spring-boot-starter-web")
testImplementation("org.projectlombok:lombok:1.18.22")
compileOnly("org.projectlombok:lombok")
developmentOnly("org.springframework.boot:spring-boot-devtools")
// runtimeOnly("com.h2database:h2")
annotationProcessor("org.projectlombok:lombok")
testImplementation("org.springframework.boot:spring-boot-starter-test")
implementation ("com.fasterxml.jackson.core:jackson-databind")
runtimeOnly("com.mysql:mysql-connector-j")
// runtimeOnly("mysql:mysql-connector-java:8.0.33")
implementation("com.moowork.gradle:gradle-node-plugin:1.3.1")
implementation("com.github.node-gradle:gradle-node-plugin:3.1.0")
//JUnit4 추가
testImplementation("org.junit.vintage:junit-vintage-engine") {
exclude("org.hamcrest", "hamcrest-core")
}
}
subprojects{
apply(plugin= "com.github.node-gradle.node")
}
tasks.withType<Test> {
useJUnitPlatform()
}
tasks {
val webappDir = "$projectDir/src/main/frontend"
register<com.moowork.gradle.node.npm.NpmTask>("appNpmInstall") {
workingDir = file(webappDir)
args = listOf("run", "build")
}
register<Copy>("copyWebApp") {
from(webappDir.resolve("build"))
into("build/resources/main/static")
}
getByName("compileJava") {
dependsOn("copyWebApp")
}
}
gradle 파일 수정 전으로 돌아간 후 1차 참고 블로그 Proxy 설정
npm install http-proxy-middleware --save
코드 추가
// src/main/frontend/src/setProxy.js
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
app.use(
'/api',
createProxyMiddleware({
target: 'http://localhost:8080', # 서버 URL or localhost:설정한포트번호
changeOrigin: true,
})
);
};
App.js 코드
// 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;
HelloWorldController 코드
// 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
public class HelloWorldController {
@GetMapping("/api/hello")
public String test() {
return "Hello, world!";
}
}
DemoWebApplication 코드
// src/main/java/com.demogroup.demoweb/DemoWebApplication.java
package com.demogroup.demoweb;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoWebApplication {
public static void main(String[] args) {
SpringApplication.run(com.demogroup.demoweb.DemoWebApplication.class, args);
}
}
8080포트 안열림 (H2 DB때문)
build.gradle의 의존성에 코드 추가
implementation ("com.h2database:h2")
implementation ("org.springframework.boot:spring-boot-starter-jdbc")
해결됨
react 포트(localhost:3000)에 값 전달이 안됨
(=연결 안됨) ㅅㅂ
=> CORS 에러
포트 재실행하는데 전에 사용했던 포트가 안닫혀서 또 문제 발생함
터미널에서 아래 코드 입력 후 PID 확인
sudo lsof -i :8080
해당 포트(8080) 강제 종료
sudo kill -9 [PID]
setProxy.js에 코드 추가 (=근데 이거 원래 코드에 있었는데 왜 중간에 없어진거..?)
const { createProxyMiddleware } = require('http-proxy-middleware');
다음 1차 참고 블로그의 빌드하기를 참고함
빌드하기 코드를 kts로 변환했을 때
val frontendDir = "$projectDir/src/main/frontend"
sourceSets {
main {
resources { srcDirs("$projectDir/src/main/resources") }
}
}
tasks.processResources { dependsOn("copyReactBuildFiles") }
tasks.register<Exec>("installReact") {
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")
}
}
tasks.register<Exec>("buildReact") {
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")
}
}
tasks.register<Copy>("copyReactBuildFiles") {
dependsOn("buildReact")
from("$frontendDir/build")
into("$projectDir/src/main/resources/static")
}
이러한 코드가 나오게 되는데
에러 발생 : Unresolved reference: Locale
MacOs 환경에서 사용하는 코드로 변환
val globalFrontendDir = "$projectDir/src/main/frontend"
sourceSets {
main {
resources { srcDirs("$projectDir/src/main/resources") }
}
}
tasks.processResources { dependsOn("copyReactBuildFiles") }
tasks.register<Exec>("installReact") {
workingDir(globalFrontendDir)
inputs.dir(globalFrontendDir)
group = BasePlugin.BUILD_GROUP
commandLine("npm", "audit", "fix")
commandLine("npm", "install")
}
tasks.register<Exec>("buildReact") {
dependsOn("installReact")
workingDir(globalFrontendDir)
inputs.dir(globalFrontendDir)
group = BasePlugin.BUILD_GROUP
commandLine("npm", "run-script", "build")
}
tasks.register<Copy>("copyReactBuildFiles") {
dependsOn("buildReact")
from("$globalFrontendDir/build")
into("$projectDir/src/main/resources/static")
}
...끝!