Gradle은 Java, Android, Kotlin 등의 개발에 주로 사용되는 오픈소스 빌드 툴입니다. 이전에 Spring Boot 어플리케이션을 개발할 때에는 Maven을 통해 빌드하는 경우가 많았는데, Gradle은 빌드 산출물에 대한 캐싱을 지원하여 성능이 보다 향상되었습니다. 그 뿐만 아니라, 빌드 스크립트 작성 시 Kotlin을 지원하여 중복으로 사용되는 값에 대한 변수처리나 task에 대한 표현을 간략하게 처리할 수 있게 되었습니다.
Spring Boot를 백엔드로 하고 외부에 프론트엔드 앱이 별도로 있는 경우, Tailwind CSS를 Spring Boot에 직접 적용하는 경우는 많지 않습니다. 하지만 Spring Boot 어플리케이션에서 프론트엔드의 역할까지 수행하도록 웹 페이지를 구성해야 하는 경우가 종종 있는데요, 이럴 때는 어떻게 하는 것이 좋을까요? cdn 태그를 html의 head에 추가하여 손쉽게 세팅하는 방법이 있지만 각종 설정과 npm 라이브러리를 적용하는 데에 있어서 약간의 어려움이 있습니다. 게다가 cdn 태그가 동작하지 않으면 전혀 스타일링이 되지 않은 페이지를 볼 수도 있죠. 이번 포스트에서는 Spring Boot 프로젝트 내에서 npm 프로젝트를 초기화하고 html에 적용하는 법을 살펴보겠습니다.
Spring Boot 프로젝트의 루트 디렉토리에서 npm 프로젝트를 초기화합니다.
npm init -y
Tailwind CSS 적용을 위한 패키지를 설치합니다. 이번 포스트에서는 daisyui
라는 Tailwind 컴포넌트 라이브러리를 함께 사용하였습니다.
npm install -D tailwindcss@latest postcss@latest autoprefixer@latest daisyui@latest
Spring Boot 프로젝트의 루트 디렉토리에서 tailwind.config.js
를 생성을 위해 다음의 명령어를 실행합니다.
npx tailwindcss init
content
항목에는 Tailwind CSS를 적용할 대상을 지정합니다. Spring Boot 프로젝트의 정적 요소가 위치한 경로를 알맞게 작성합니다.
이어서 plugins
의 요소로 사용할 외부 라이브러리를 작성합니다. 이는 각 라이브러리에 따라 적용방법이 상이하므로 문서를 참고하여 작성합니다.
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ["./src/main/resources/static/**/*.{html,js}"],
theme: {
extend: {
},
},
plugins: [
require('daisyui'),
],
}
Spring Boot의 정적 요소는 src/main/resources
에 위치합니다. 다음과 같이 필요한 파일을 세팅합니다.
src/main/resources/static/css/input.css
src/main/resources/static/images/<이미지 파일>
src/main/resources/static/index.html
.../
└── resources/
├── static/
│ ├── css/
│ │ └── input.css
│ ├── images/
│ │ ├── spring-boot.svg
│ │ └── tailwind.svg
│ └── index.html
├── templates/
└── application.properties
Tailwind CSS를 컴파일하기 위한 디렉티브를 input.css
에 작성합니다.
@tailwind base;
@tailwind components;
@tailwind utilities;
HTML의 <head>
에 CSS 로드를 위한 태그를 추가합니다.
...
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Cloudtype - Spring Boot</title>
<!-- 빌드 후 컴파일 산출물인 output.css로부터 CSS 로드 -->
<link href="css/output.css" rel="stylesheet" type="text/css" />
</head>
...
package.json
의 scripts
에 다음과 같이 CSS 컴파일을 위한 스크립트를 작성합니다.
{
...
"scripts": {
"build:css": "npx tailwindcss -i ./src/main/resources/static/css/input.css -o ./src/main/resources/static/css/output.css --minify"
},
...
}
npm 패키지를 설치하기 위한 npmInstall
, Tailwind CSS를 컴파일하기 위한 npmBuildCss
등 두 개의 태스크를 등록하겠습니다. 이 때, 각 태스크의 실행 순서를 결정하는 dependsOn()
메서드를 적절히 사용해야 에러를 방지할 수 있습니다.
...
val npmInstall by tasks.register<Exec>("npmInstall") {
workingDir = file("${project.projectDir}")
commandLine("npm", "install")
}
val npmBuildCss by tasks.register<Exec>("npmBuildCss") {
workingDir = file("${project.projectDir}")
commandLine("npm", "run", "build:css")
dependsOn(npmInstall)
}
tasks.named("processResources") {
dependsOn(npmBuildCss)
}
tasks.named("bootJar") {
dependsOn(npmBuildCss)
}
Gradle 명령어를 실행하여 npm 스크립트 및 jar 빌드가 정상적으로 진행되는지 확인합니다.
./gradlew clean build
Gradle 빌드 후 src/main/resources/static/css/output.css
가 정상적으로 생성되었는지 확인합니다.
실습은 아래의 Spring Boot 어플리케이션을 통해 진행됩니다. 저장소를 clone 하거나 fork 해주세요.
클라우드타입의 프로젝트 페이지에서 ➕ 버튼을 누르고 Spring Boot를 선택한 후, 미리 fork 해놓은 springboot-tailwind 를 선택합니다.
배포가 완료되면 접속하기 버튼을 누르고 브라우저에 CSS가 정상적으로 적용되었는지 확인합니다.