스프링부트에서 Tailwind CSS 사용하기
스프링부트에서 간단하게 프론트 페이지를 개발해야 할 때에는 Thymeleaf나 Mustache + Bootstrap을 이용해서 간단한 페이지들을 만들곤 했는데요. 이번에는 순수 CSS와 Bootstrap, 그 사이 어디쯤 존재하고 있는 Tailwind CSS 를 한 번 사용해보려고 합니다. 스프링부트에서 npm을 사용하는 혼종(?)이 탄생할 예정이니, 부담스러우신 분들은 눈을 감아주시길 바랍니다.
"flex
, pt-4
, text-center
, rotate-90
과 같은 클래스로 구성된 유틸리티 우선 CSS 프레임워크로, 마크업에서 바로 어떤 디자인이든 만들 수 있습니다." - tailwindcss.com
CDN을 이용한 Tailwind CSS 사용하기 (비추천! 넘기셔도 됩니다)
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body>
<h1 class="text-3xl font-bold underline">
Hello world!
</h1>
</body>
</html>
이 방법은 Bootstrap을 사용하시던 분들에게 가장 익숙한 방법이 아닐까 싶습니다. Tailwind CSS를 사용하고 싶은 HTML 파일의 <head>
태그 안에 CDN 링크를 추가함으로써 Tailwind CSS를 사용하는 방법입니다. 하지만 이 방법은 아래와 같은 단점이 있어서 공식 문서에서는 개발 환경에서만 사용하길 권장 하고 있습니다.
단점
사용하지 않는 CSS 클래스들도 같이 로드되기 때문에, 브라우저 로딩 속도가 느려집니다.
Tailwind CSS는 원래 성능에 중점을 두고 있어서, 자신이 HTML 파일에서 사용하는 클래스들만 빌드 해서 사용하길 권장하고 있습니다. CSS 축소 및 네트워크 압축과 결합하면 대규모 프로젝트에서도 10kB 미만의 CSS 파일을 생성할 수 있다고 공식 문서에서는 말하고 있습니다. 예를 들어, 넷플릭스는 Netflix Top 10에 Tailwind CSS를 사용하며 전체 웹사이트는 네트워크를 통해 6.5KB의 CSS만 전송합니다.
CDN을 사용했을때의 브라우저로 로드되는 파일의 크기가 궁금해서 확인해보았는데, 아래와 같이 110kB나 되는 것을 확인할 수 있습니다.
Config를 작성하거나 커스텀 CSS 클래스를 사용하기 불편합니다.
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.tailwindcss.com"></script>
<script>
tailwind.config = {
theme: {
extend: {
colors: {
clifford: '#da373d',
}
}
}
}
</script>
</head>
<body>
<h1 class="text-3xl font-bold underline text-clifford">
Hello world!
</h1>
</body>
</html>
Tailwind CSS는 기본적으로 tailwind.config.js
파일을 통해 색상, 글꼴, 여백 등의 설정을 할 수 있습니다. 하지만 CDN을 이용해서 Tailwind CSS를 사용할 경우, 위와 같이 <script>
태그를 이용해서 설정을 해줘야 합니다. 또한, 커스텀 CSS 클래스를 사용할 경우에도, 위의 방식과 비슷하게 <script>
하단에 <style>
태그를 이용해서 작성해야 합니다.
npm을 이용한 Tailwind CSS 사용하기
1. 프로젝트 생성
자, 이제 제가 진행한 방법을 소개해드리겠습니다. 보통의 스프링부트 프로젝트의 디렉토리 구조는 아래와 같습니다.
src
├── main
│ ├── java
│ │ └── com
│ │ └── example
│ │ └── tailwind
│ │ ├── controller
│ │ │ └── IndexController.java
│ │ └── TailwindApplication.java
│ └── resources
│ ├── static
│ ├── templates
│ └── application.properties
├── test
└── build.gradle
기본 디렉토리 구조에서 새로 추가한 IndexController
에서는 루트 경로로 접속했을 때 index.html
을 반환하도록 설정해두었습니다.
@Controller
public class IndexController {
@GetMapping("/")
public String index() {
return "index.html";
}
}
2. Tailwind CSS 설치
Tailwind CSS는 아래와 같은 명령어를 통해서 output.css
파일을 빌드하는 과정을 거치게 됩니다.
tailwindcss -i ./input.css -o ./output.css
때문에 저희는 output.css
파일을 빌드할 때 필요한 리소스들은 src/main/frontend
디렉토리에 저장해서 따로 분리하고, 빌드된 output.css
파일은 src/main/resources/static
디렉토리에 저장하도록 하겠습니다.
2-1. src/main/frontend
디렉토리 생성
위의 기본 디렉토리 구조에서 src/main/frontend
디렉토리를 생성합니다.
src
├── main
│ ├── frontend # 추가
│ ├── java
│ │ └── com
│ │ └── example
│ │ └── tailwind
│ │ ├── controller
│ │ │ └── IndexController.java
│ │ └── TailwindApplication.java
│ └── resources
│ ├── static
│ ├── templates
│ └── application.properties
├── test
└── build.gradle
2-2. Tailwind CSS 설치
src/main/frontend
디렉토리에 'package.json' 파일을 생성하고, 아래와 같이 작성합니다.
{
"name": "frontend",
"private": true
}
src/main/frontend
디렉토리에서 아래의 명령어를 실행합니다.
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init
2-3. PostCSS 설정에 Tailwind 추가
src/main/frontend
디렉토리에 'postcss.config.js' 파일을 생성하고, 아래와 같이 작성합니다.
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
}
}
3. Tailwind CSS 설정
3-1. tailwind.config.js
파일 설정
Tailwind는 output.css
파일을 빌드하게 될때, 사용자가 작성한 CSS 클래스들만을 탐색해서 빌드 합니다. 때문에, 스프링부트에서 사용하는 .html
, .js
, .mustache
와 같은 정적 리소스들의 경로를 tailwind.config.js
파일에 추가해줘야 합니다. src/main/frontend
디렉토리의 tailwind.config.js
파일에 아래와 같이 작성합니다.
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ["../resources/templates/**/*.{html,js,mustache}"], // mustache는 사용하지 않을 경우 삭제
theme: {
extend: {},
},
plugins: [],
}
3-2. main.css
파일 생성
src/main/frontend
디렉토리에 main.css
파일을 생성하고, 아래와 Tailwind의 각 레이어에 대한 @tailwind
지시문을 기본 CSS 파일에 추가합니다.
@tailwind base;
@tailwind components;
@tailwind utilities;
4. npm 스크립트 추가
package.json
파일에 아래와 같이 스크립트를 추가합니다.
{
"name": "frontend",
"private": true,
"scripts": {
"build": "tailwindcss -i ./main.css -o ../resources/static/main.css"
},
"devDependencies": {
...
}
5. 빌드
자, 그러면 위의 IndexController
에서 index.html
을 반환하도록 하였으니, src/main/resources/static
경로에 index.html
파일을 생성하고, 아래와 같이 작성합니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Title</title>
<!-- Tailwind CSS -->
<link href="/main.css" rel="stylesheet">
</head>
<body class="bg-stone-300">
<div class="mt-5 max-w-md mx-auto bg-white rounded-xl shadow-md overflow-hidden md:max-w-2xl">
<div class="md:flex">
<div class="md:shrink-0">
<img class="h-48 w-full object-cover md:h-full md:w-48" src="/img/logo.png"
alt="Modern building architecture">
</div>
<div class="p-8">
<div class="uppercase tracking-wide text-sm text-indigo-500 font-semibold">Tailwind CSS</div>
<a href="#" class="block mt-1 text-lg leading-tight font-medium text-black hover:underline">스프링부트에서 Tailwind CSS 사용하기</a>
<p class="mt-2 text-slate-500">Tailwind CSS는 유틸리티 우선의 CSS 프레임워크로, 개발자들이 빠르고 효율적으로 사용자 정의 디자인을 적용할 수 있게 해주는 도구입니다. 이 포스트에서는 스프링부트 프로젝트에 Tailwind CSS를 통합하여, 반응형이며 인터랙티브한 UI를 손쉽게 구현할 수 있는 방법을 소개하고자 합니다.</p>
</div>
</div>
</div>
</body>
</html>
이후에 src/main/frontend
디렉토리에서 아래의 명령어를 실행합니다.
npm run build
명령어를 실행하면 위에서 작성하였던 package.json
의 스크립트를 통해 resources/static/main.css
파일이 생성됩니다.
"scripts": {
"build": "tailwindcss -i ./main.css -o ../resources/static/main.css"
},
마지막으로 스프링부트 애플리케이션을 실행하고, http://localhost:8080
에 접속하면 아래와 같이 Tailwind CSS가 적용된 화면을 확인할 수 있습니다.
스프링부트를 실행할 때마다 Tailwind CSS 자동 빌드하기
위에서는 npm run build
명령어를 통해 Tailwind CSS를 빌드하였습니다. 하지만, 스프링부트를 실행할 때마다 매번 npm run build
명령어를 실행하는 것은 번거로운 일입니다. 이를 해결하기 위해, 스프링부트를 실행할 때마다 Tailwind CSS를 자동으로 빌드 하는 방법을 소개해드리겠습니다.
// node_modules 디렉토리가 존재하지 않을 경우 npm install을 실행하는 태스크
task npmInstall(type: Exec) {
workingDir 'src/main/frontend'
commandLine 'npm', 'install'
onlyIf { !new File('src/main/frontend/node_modules').exists() }
}
// npm run build를 실행하는 태스크
task npmRunBuild(type: Exec, dependsOn: npmInstall) {
workingDir 'src/main/frontend'
commandLine 'npm', 'run', 'build'
}
// processResources 태스크가 실행되기 전에 npmRunBuild 태스크를 실행하도록 설정
// processResources 태스크는 리소스 파일을 클래스 디렉토리로 복사하는 태스크입니다.
processResources.dependsOn npmRunBuild
build.gradle
파일에 위와 같이 태스크를 추가합니다. 이후에 스프링부트를 실행하면, processResources
태스크가 실행되기 전에 npmRunBuild
태스크가 실행되어 Tailwind CSS를 자동으로 빌드합니다.
위의 모든 과정을 통해서 스프링부트에서 Tailwind CSS를 사용하는 방법을 알아봤습니다. 이 포스트는 maciejwalkowiak.com의 Spring Boot with Thymeleaf and Tailwind CSS - Complete Guide를 참고하여 작성하였으며, Maven 을 사용하시는 분들은 해당 포스트를 참고하시길 바랍니다.