본문 바로가기
C.W.K.
Stream
Lesson 03 of 08 · published

서버 컴포넌트에서 CSS-in-JS가 어려운 이유

~18 min · CSS-in-JS, styled-components, registry

Level 0호기심
0 XP0/68 lessons0/11 achievements
0/120 XP to next level120 XP to go0% complete

실행 시점 스타일 주입과 서버 기본값이 충돌해

styled-components와 emotion은 JavaScript가 실행되며 스타일을 만들어 문서에 넣는 방식이야. 서버 컴포넌트는 자기 코드를 클라이언트로 보내지 않으므로 이 실행 시점 모델을 그대로 사용할 수 없어. 'use client' 경계가 실제 벽이 되는 지점이지.

방식서버 컴포넌트클라이언트 컴포넌트
CSS Module가능가능
Tailwind CSS가능가능
styled-components불가registry와 함께 가능
emotion불가registry와 함께 가능

기존 CSS-in-JS는 registry로 연결해

계속 써야 한다면 클라이언트 style registry로 앱을 감싸고, 서버 렌더링 중 모은 스타일을 응답에 넣어야 해. 작동은 하지만 수집·주입 코드와 실행 시점 비용을 계속 부담하게 돼.

새 프로젝트는 정적 CSS 경로가 단순해

특별한 요구가 없다면 Tailwind나 CSS Module이 서버·클라이언트 어디서나 작동하고 실행 시점 비용도 없어. 기존 투자 때문에 registry를 유지하는 결정과 새로 그 복잡성을 선택하는 결정은 구분해야 해.

기존 CSS-in-JS를 유지한다면 registry의 서버 삽입, hydration 일치, streaming 순서를 실제 production 빌드에서 시험해. 어느 컴포넌트가 client 경계를 요구하는지 목록을 만들고 새 서버 컴포넌트에는 정적 CSS 방식을 기본으로 써. 이동은 화면 단위로 하며 두 시스템의 토큰을 하나로 공유해. 런타임 비용이 있다는 이유만으로 대규모 제품의 스타일을 한 번에 갈아엎으면 회귀 비용이 더 클 수 있어. 이미 안정된 컴포넌트는 유지하고 새 경계부터 다른 기본값을 적용하는 점진적 전환도 가능해. 목표는 유행 교체가 아니라 클라이언트 실행과 유지 책임을 줄이는 거야.

registry가 있는 CSS-in-JS 페이지와 CSS Module 페이지를 production streaming 환경에서 비교해. 첫 HTML의 style, hydration warning, 클라이언트 chunk, route 이동 뒤 중복 style을 확인하고, 기존 화면 한 개만 점진적으로 옮겨 토큰과 시각 결과가 유지되는지 검증해.

Code

styled-components 레지스트리·tsx
// lib/StyledComponentsRegistry.tsx
'use client';
import { useState } from 'react';
import { useServerInsertedHTML } from 'next/navigation';
import { ServerStyleSheet, StyleSheetManager } from 'styled-components';

export function StyledComponentsRegistry({ children }: { children: React.ReactNode }) {
  const [sheet] = useState(() => new ServerStyleSheet());

  useServerInsertedHTML(() => {
    const styles = sheet.getStyleElement();
    sheet.instance.clearTag();
    return <>{styles}</>;
  });

  return (
    <StyleSheetManager sheet={sheet.instance}>
      {children}
    </StyleSheetManager>
  );
}

External links

Exercise

CSS-in-JS registry 화면과 CSS Module 화면을 production streaming에서 비교해. style 삽입, hydration 경고, 클라이언트 chunk 차이를 기록해.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.