Tailwind v4로 옮기면서 배운 것들
Article
이 블로그는 처음부터 Tailwind v4로 만들었지만, 회사 프로젝트 하나를 v3에서 v4로 옮기는 작업도 같이 하고 있다. 두 경험을 겹쳐 보니 v4에서 달라진 게 뭔지 선명해져서 정리한다.
설정 파일이 사라졌다
v4의 가장 큰 변화는 CSS-first 설정이다. tailwind.config.js가 없어지고 CSS 파일 안에서 모든 걸 정의한다.
/* v3: tailwind.config.js에서 JS 객체로 정의 */
/* v4: CSS에서 바로 정의 */
@import "tailwindcss";
@theme {
--color-bg: #0a0a0a;
--color-fg: #ffffff;
--color-muted: #b5b5b5;
--color-surface: #171717;
--color-accent: #f87171;
--font-sans: var(--font-noto-sans-kr);
--font-serif: var(--font-gowun-batang);
}
@theme에 선언한 토큰은 자동으로 유틸리티 클래스가 된다. --color-bg를 선언하면 bg-bg, text-bg, border-bg가 전부 생긴다. 처음엔 어색했는데, 써보니 디자인 토큰과 유틸리티가 한 몸이 되는 구조라 오히려 자연스럽다.
CSS 변수라서 얻는 것
v3에서도 CSS 변수 색상을 쓸 수 있었지만, rgb(var(--bg) / <alpha-value>) 같은 우회가 필요했다. v4는 토큰 자체가 CSS 변수라 그냥 쓰면 된다. 불투명도 변형도 바로 된다.
<p class="text-fg/50">보조 텍스트</p>
<div class="border border-fg/15 bg-fg/18">배지</div>
런타임에 변수 값만 바꾸면 테마 전환도 되니까, 다크모드 대응이 클래스 토글이 아니라 변수 교체 문제로 단순해진다.
postcss 설정도 한 줄
빌드 파이프라인도 가벼워졌다. autoprefixer와 postcss-import가 내장돼서 플러그인이 하나만 남는다.
// postcss.config.mjs
export default {
plugins: {
"@tailwindcss/postcss": {},
},
};
v3 프로젝트에서 이 부분 옮길 때 기존 autoprefixer를 지우지 않아서 잠깐 헤맸다. v4는 브라우저 접두사를 알아서 처리하니 남겨두면 중복이다.
마이그레이션에서 걸린 것들
공식 업그레이드 툴(npx @tailwindcss/upgrade)이 대부분을 처리해주지만, 손으로 고친 게 몇 가지 있다.
@layer components에 정의한 커스텀 클래스에서@apply가 참조하는 유틸리티가 바뀐 경우. 특히shadow-sm→shadow-xs처럼 스케일 이름이 밀린 것들theme()함수를 쓰던 곳. v4에서는 그냥var(--color-accent)로 바꾸는 게 맞다- arbitrary value로 색을 박아둔 곳(
bg-[#171717]). 이 참에 전부 토큰으로 회수했다
세 번째가 사실 제일 오래 걸렸는데, 제일 잘한 일이기도 하다. 마이그레이션은 흩어진 하드코딩을 토큰으로 모으는 강제 이벤트로 쓰는 게 남는 장사다.
정리
v4의 방향은 분명하다. 설정을 JS에서 CSS로, 색상을 문자열에서 변수로. CSS의 원래 능력에 가까워지는 쪽이다. 새 프로젝트라면 고민할 이유가 없고, v3 프로젝트도 업그레이드 툴 덕에 부담이 크지 않다. 다만 커스텀 클래스가 많은 프로젝트라면 @apply 주변은 손으로 검수할 각오는 하는 게 좋다.