티스토리 뷰
프론트엔드 react, 백엔드 Spring boot에 gradle 사용하는 개발 프로젝트에서 빌드시 npm까지 빌드해서 war파일로 한큐에 만들기
먼저 스프링부트 폴더 내에 frontend 폴더를 만들고 그 안에 react 프로젝트를 넣는다.
프론트엔드 index가 인덱스로 나오려면 src/main/resources/static 폴더 내에 들어가야 한다.
build.gradle 파일 안에 다음 스크립트를 추가한다.
def webappDir = "$projectDir/frontend"
sourceSets {
main {
resources {
srcDirs = ["$webappDir/build", "$projectDir/src/main/resources"]
}
}
}
processResources {
dependsOn "copyWebApp"
}
task copyWebApp(type: Copy) {
dependsOn "buildReact"
from "$webappDir/build"
into "$projectDir/src/main/resources/static"
}
task buildReact(type: Exec) {
dependsOn "installReact"
workingDir "$webappDir"
inputs.dir "$webappDir"
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 installReact(type: Exec) {
workingDir "$webappDir"
inputs.dir "$webappDir"
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'
}
}
webapp 경로를 프로젝트 경로 내 frontend 폴더로 지정하고,
processResources에 지정되어 있는 copyWebApp 태스크부터 찾아가서, dependsOn을 따라
copyWebApp > buildReact > installReact로 넘어가서 여기서부터 역순서로 실행된다.
installReact는 frontend 폴더에서 npm install을,
buildReact는 frontend 폴더에서 npm run-script build를,
copyWebapp은 frontend/build 폴더에 생긴 빌드 파일을 src/main/resources/static 내에 복사해준다.
vs코드에서 gradle task 익스텐션을 설치하면 gradle build가 가능하다.
build 실행 후 build/libs에 생긴 war 파일을
해당 경로에서 cmd로 java -jar 파일명.war 로 실행시키면 react index가 출력된다.
+ gradle에 nodejs 의존 추가할 경우
gradle 프로젝트를 spring initializer로 생성하면 plugins로 되어 있는데
classpath 사용을 위해 buildscripts와 add plugin으로 바꾼다.
plugins {
id 'org.springframework.boot' version '2.3.8.BUILD-SNAPSHOT'
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id 'java'
id 'war'
}
를
buildscript {
ext {
springBootVersion = '2.3.8.BUILD-SNAPSHOT'
}
repositories {
mavenCentral()
maven { url 'https://repo.spring.io/milestone' }
maven { url 'https://repo.spring.io/snapshot' }
maven { url 'https://plugins.gradle.org/m2/' }
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
이렇게 바꿀 수 있다.
여기에 node 플러그인을 추가하면 되는데,
com.moowork.gradle의 gradle-node-plugin의 경우
Could not find org.nodejs:node:8.4.0 when GRADLE_METADATA feature is enabled
같은 에러가 난다.
gradle build 시 node module 찾을 수 없어서 생기는 에러.
com.moowork.node > com.github.node-gradle.node로 변경해준다.
github.com/spitty/yet-another-life-game/commit/233cbdaa49719fbc185af565d996baf09098621b
ext에는 광역변수로 쓸 버전을, dependencies에는 classpath를, apply plugin으로 node-gradle 플러그인을 추가해준다.
buildscript {
ext {
springBootVersion = '2.3.8.BUILD-SNAPSHOT'
gradle_node_version='2.2.3'
}
repositories {
mavenCentral()
maven { url 'https://repo.spring.io/milestone' }
maven { url 'https://repo.spring.io/snapshot' }
maven { url 'https://plugins.gradle.org/m2/' }
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
classpath("com.github.node-gradle:gradle-node-plugin:${gradle_node_version}")
}
}
apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'com.github.node-gradle.node'
.