[build.gradle.kts] Spring Build 파일 실행시 ReactJS도 같이 실행하는 방법(2)
이 전 글에서 Spring Module과 Root Project 모두 설정을 진행했으니, 이제 Build Script만 작성하면 끝난다.
Build Script는 Core(Spring Module)과, Client(React Module)에 작성할 것이다.
먼저 Script 작성 전 Client에 build.gradle.kts 파일을 추가해주도록 하자.
그리고, 이 전 글에서 Root Project에서 Spring Module을 참조했던 방법과 똑같이 Client도 참조해주도록 하자.
생성하는 방법은, 그냥 client directory 안에다가 New File로 만들면 된다.
추가 한 이후의 프로젝트 구조는 아래와 같이 생성되었을 것이다.
여기서 먼저 client의 build.gradle.kts 파일을 수정해주도록 하자.
(아무 내용도 없을텐데 사실 수정이 아니라 추가해주면 된다.)
1
2
3
|
plugins {
id("com.github.node-gradle.node") version "3.1.1"
}
|
cs |
이 plugin이 뭐냐면, Node Task를 사용할 수 있게 해주는 plugin이다.
Node Task가 필요한 이유는, Node를 이용해 React를 Build 시킬 것 이기 때문에 필요하다.
저 plugin을 추가해주고 ReImport를 통해 plugin을 제대로 불러올 수 있는지 확인하면 된다.
plugin을 제대로 불러왔다면, 이제 이어서 아래와 같이 작성해주도록 하자.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
import com.github.gradle.node.yarn.task.YarnTask
plugins {
id("com.github.node-gradle.node") version "3.1.1"
}
node {
version.value("14.17.6")
yarnVersion.value("1.22.11")
npmVersion.value("6.14.15")
distBaseUrl.value("https://nodejs.org/dist")
download.value(true)
}
task("yarnBuild", YarnTask::class) {
dependsOn("yarnInstall")
args.empty()
args.add("build")
}
task("yarnInstall", YarnTask::class) {
args.empty()
args.add("install")
}
|
cs |
나는 Node.js의 패키지 설치 모듈로 Npm 대신 Yarn을 사용할 것이기 때문에, Yarn Task를 참조했다.
만약 Npm을 쓰고 싶다면 NpmTask를 참조하면된다.
7번째 Line의 node Block은 com.github.node-gradle.node의 plugin을 만든 회사? 사람?이 저런식으로 기본적인 value를 정해주라고 하길래 정해준 것이다.
내가 사용하고 있는 Node의 버전, yarn의 버전, npm의 버전. 그리고 npm/yarn이 없을 때 다운로드 받을 주소에 대해 설정하는 것이다.
자세한 내용은 아래를 참고하자.
(com.github.node-gradle.node GitHub)
그 다음 15번째 Line, 20번째 Line에서 새로운 Gradle Task를 만들어준 것이다.
task의 이름을 정의하고, 이 task는 어떤 Class를 상속받을 것인지에 대해 작성해주면 된다.
현재 15~19번째 Line은 YarnTask를 상속받고, args에 build라는 내용을 추가하는 Task임을 알 수 있다.
(YarnTask Class에 내부로 들어가게 되면 @TaskAction Annotation이 달려있는 함수를 볼 수 있는데, 여기서 args를 실행하고 있기 때문에 추가해준 것이다.)
그리고 dependsOn은 특정 Task를 실행하라는 명령이다.
즉 Gradle Task중 yarnBuild를 실행하게 되면, yarnInstall Task를 실행한 후 'build' 라는 내용을 args에 추가해주고 있음을 알 수 있다.
(yarnBuild Task에 yarnInstall Task를 실행하게 한 이유는 yarn Build를 했을 때 다른 개발자가 library를 추가했거나 했을 때 yarnInstall을 client 폴더에서 진행하고 스크립트를 실행시켜야 하는데, 이 부분이 귀찮아서 자동화한 것이다.)
여기까지 일단 문제가 없는지 확인하고, 문제가 없으면 넘어가자.
다음, Core Module에 build.gradle.kts에 아래 내용을 추가해주도록 하자.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
val webappDir = "$projectDir/../client"
val coreDir = "$projectDir"
sourceSets {
main {
resources {
setSrcDirs(listOf("$webappDir/build", "$coreDir/src/main/resources"))
}
}
}
(getTasksByName("processResources", true) as Set<ProcessResources>).forEach {
it.dependsOn("copyWebApp")
}
task("copyWebApp", Copy::class) {
dependsOn("buildReact")
from("$webappDir/build")
into("$coreDir/src/main/resources/static")
}
task("buildReact") {
dependsOn(":client:yarnBuild")
}
tasks.getByName<org.springframework.boot.gradle.tasks.bundling.BootJar>("bootJar") {
enabled = true
mainClass.value("prv.y0ngha.core.CoreApplicationKt")
}
|
cs |
1번째 ~ 2번째 Line은 변수를 선언한 것이고, $projectDir은 Core Module에 Absolute Path가 나온다.
webappDir은 React Module의 Path를 가져온 것이고, coreDir은 본인 Path를 가져온 것이다.
4~9번째 Line은 sourceSets을 수정해준 것인데, 여기서 sourceSets은 프로젝트가 Build될 때 소스와 리소스의 논리적 그룹을 뜻한다.
하나 이상의 소스를 지정할 때 반드시 이 작업을 진행해줘야 하는데, 여기서는 webAppDir의 build 폴더와 coreDir의 리소스 파일을 추가해준 것이다.
(webAppDir은 React의 Build파일이고, coreDir의 resources를 추가해준 이유는 후에 React Build File을 resources로 옮기기 때문에 추가해준 것이다.. 아마?)
(참고 자료 : https://goateedev.tistory.com/73)
12~14번째 Line은 특정 Task가 실행될 때 특정 Task를 실행시키기 위해서 추가하였다.
여기서 processResources Task는 무엇이냐면, Build시 나오는 기본 Task중 하나다.
(참고 자료 : Gradle의-중요한-프로세스-익히기)
copyWebApp 이라는 Task를 실행시키고 있으며, copyWebApp은 16~20번째 Line에 선언이 되어있다.
Copy Class를 상속받고 있으며, Action을 진행하기 전 buildReact라는 Class를 실행시키고 있다.
(buildReact는 22~24번째 Line에 선언되어 있으며 client 모듈에 있는 yarnBuild를 실행시키고 있다. - 초반에 정의한 Task)
yarnBuild를 실행시키게 되면 React가 Build되어 나오게 되는데, 해당 파일들을 from ~ into로 옮겨주고 잇는 작업이다.
26~29번째 Line은 bootJar이라는 Task에 대해 추가적으로 Append한 것이다.
bootJar은 Spring Boot의 packaging이 Jar일 때 사용할 수 있는데, Spring Boot를 실행가능한 Jar 파일을 생성할 때 사용된다.
enabled라는건 기본적으로 이 bootJar은 비활성화 되어있는데, 그걸 활성화 시켜준 것이고, 실행시킬 Class를 정의해준 것이다.
여기까지 했으면 build Script 작성도 끝이 났다.
이제 Spring을 실행시켜보자.
(실행을 시킬때는 bootJar을 이용해서 Jar 파일로 실행을 해야한다. 만약에 개발 환경에서 실행을 시키고 싶을 때에는 Spring 따로, React 따로 실행 시켜야한다.)
Root Project에서 Terminal을 열고 아래와 같이 입력해보자.
.\gradlew core:bootJar
그러면 Core Module에 build 폴더가 생기고, 안에 lib 폴더가 생겼을 것이다.
여기에 있는 Jar을 실행시켜주면 된다.
아래 명령어를 통해 실행하면 된다.
java -jar core-0.0.1-SNAPSHOT.jar
실행을 하면, 아래처럼 Spring이 실행되었다는 로그가 나오고, http://localhost:8080으로 접속해보면 React App이 나오는 것을 확인할 수 있다.
java -jar core-0.0.1-SNAPSHOT.jar
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.5.6)
2021-10-27 19:09:15.675 INFO 10520 --- [ main] prv.y0ngha.core.CoreApplicationKt : Starting CoreApplicationKt using Java 11.0.11 on yhShin.local with PID 10520
2021-10-27 19:09:15.678 INFO 10520 --- [ main] prv.y0ngha.core.CoreApplicationKt : No active profile set, falling back to default profiles: default
2021-10-27 19:09:16.584 INFO 10520 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2021-10-27 19:09:16.598 INFO 10520 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2021-10-27 19:09:16.599 INFO 10520 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.54]
2021-10-27 19:09:16.665 INFO 10520 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2021-10-27 19:09:16.665 INFO 10520 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 910 ms
2021-10-27 19:09:16.904 INFO 10520 --- [ main] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page: class path resource [static/index.html]
2021-10-27 19:09:16.998 INFO 10520 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2021-10-27 19:09:17.008 INFO 10520 --- [ main] prv.y0ngha.core.CoreApplicationKt : Started CoreApplicationKt in 1.774 seconds (JVM running for 2.269)