개인 프로젝트를 진행하면서 프론트 부분에서 CSS를 어떻게 꾸밀까 고민을 하던 차에, 최근에 tailwindcss
가 각광받고 있다는 것을 알게 되어 한번 적용해 보려고 했습니다.
tailwindcss
는 간단히 말해서 BootStrap처럼 여러 css 요소들을 모듈화하여 개발자 입장에서 사용하기 편리하게끔 해놓은 프레임워크입니다.
둘의 차이점은 BootStrap은 다년간 발전하며 수 많은 UI 요소들을 사용하게끔 해주지만, 전체 기능에 접근하려면 여러 파일이 필요합니다. 따라서 프로젝트의 크기가 훨씬 커집니다. 하지만 tailwind는 사용하지 않는 클래스는 빌드 시에 제거해주는 PurgeCSS
기능이 있어, 파일 크기가 비교적 작습니다. 이외에도 여러 장단점이 있지만.. 저는 이번 기회에 새로운 기술을 한번 사용해보고자 해서 도입하게 되었습니다.
tailwindcss
를 프로젝트에 적용하는 방법은 여러가지가 있습니다. 자세한 내용은 다음을 참고해 주세요. 공식 사이트입니다.
저는 처음에는 Play CDN 방식을 사용하려고 했습니다. 이름은 생소하지만 친숙한 방식인데, HTML 파일의 head 태그 안에 다음과 같이 script 태그를 삽입하는 것입니다.
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.tailwindcss.com"></script>
</head>
보시다시피 이 방식은 라이브러리 링크를 삽입함으로써 단 한 줄로 간편하게 처리가 가능하다는 장점이 있습니다. 하지만 편리한 만큼 단점도 존재합니다. 만약 링크 주소에 변경이 생기거나 새로운 버전이 릴리즈되는 경우, 예전 주소를 더 이상 사용할 수 없는 상황이 발생할 수도 있습니다. 그렇다면 그때마다 url을 변경해야 는 수고가 들 것입니다. 또한, HTML 파일을 렌더링할 때마다 직접 링크에서 리소스를 받아오기 때문에, 네트워크 환경에 따라 서비스가 불안정해질 가능성도 있습니다.
그렇다면 이를 극복하려면 어떻게 해야할까요? 렌더링할 때마다 라이브러리를 받아오는 게 아닌, 사전에 라이브러리를 받아놓고, 빌드 시에 프로젝트에 추가한다면 배포 이후엔 네트워크 환경과 같은 문제에서 자유로워질 수 있을 것입니다.
이번 포스트의 주 내용은 tailwind
설치가 아닌, SpringBoot에서의 npm 라이브러리의 정적 리소스 적용법입니다!
src/main/resources/static 디렉토리에서 npm을 설치합니다.
npm init
npm install (ex. tailwindcss...)
src/main/resources/static 는 정적 리소스를 제공합니다. 이 디렉토리 아래에서package.json
파일에 등록된 라이브러리를 빌드 시에 다운로드 받고, 서비스 제공 시에는 정적 리소스로서 제공될 것입니다.
위의 두 명령어를 성공적으로 실행시키면 package.json
파일이 생성될 것입니다.
{
"name": "static",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"postcss": "^8.4.16",
"tailwindcss": "^3.1.8"
}
}
build.gradle 파일에 빌드 정보 추가
plugins {
id 'org.springframework.boot' version '2.7.4'
id 'io.spring.dependency-management' version '1.0.14.RELEASE'
id 'java'
id 'com.github.node-gradle.node' version '3.4.0' // 이거 추가
}
// node 정보 추가
node {
version = '17.6.0'
npmVersion = '8.5.1'
download = true
nodeProjectDir = file('${projectDir}/src/main/resources/static')
}
group = ''
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
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'
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'org.mariadb.jdbc:mariadb-java-client'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
task copyFrontLib(type: Copy) {
from "${projectDir}/src/main/resources/static"
into "${projectDir}/build/resources/main/static/."
}
tasks.named('test') {
useJUnitPlatform()
}
위의 코드에서 npm 설정을 위해 추가한 부분은 다음과 같습니다.
plugins {
id 'org.springframework.boot' version '2.7.4'
id 'io.spring.dependency-management' version '1.0.14.RELEASE'
id 'java'
id 'com.github.node-gradle.node' version '3.4.0' // 이거 추가
}
Gradle node 플러그인을 사용하기 위해 plugins
에 추가합니다.
현재 최신 버전은 https://github.com/node-gradle/gradle-node-plugin 에서 확인하실 수 있습니다.
node {
version = '17.6.0'
npmVersion = '8.5.1'
download = true
nodeProjectDir = file('${projectDir}/src/main/resources/static')
}
현재 사용하고 계신 node, npm 버전을 적어주시면 되겠습니다. 각각 node -v
, npm -v
명령어로 확인이 가능합니다. download
는 위에 명시한 버전의 node를 다운받기 위해 true로 설정합니다. nodeProjectDir
또한 static 경로로 설정해주시면 되겠습니다.
task copyFrontLib(type: Copy) {
from "${projectDir}/src/main/resources/static"
into "${projectDir}/build/resources/main/static/."
}
Gradle이 빌드될 때 수행할 task를 명시하는 부분입니다. type: Copy
로 적용하여, 빌드 시에 정적 리소스들을 build/resources/main/static 경로로 복사하여 사용할 수 있게끔 해줍니다.
위 작업들을 성공적으로 끝마쳤다면, build.gradle
을 새로고침하시면
node_modules 패키지가 생성된 것을 확인하실 수 있습니다. 이 패키지에는 저희가 빌드 시에 정적 리소스로 사용할 라이브러리들이 포함되어 있습니다.