Vanila-extract

Vanila-extract


1. 스타일링 종류

  1. CSS-in-CSS(tailwind,scss...) - 개별 스타일 단위의 stylesheet
  • 별도의 자바스크립트 전환이 필요없어서 속도가 빠름
  • 클래스들은 다른 컴포넌트를 스타일링할 때 재사용 가능
  • 모듈성이 좋지 않다
  • 너무 많은 스타일 코드를 작성하거나 스타일 클래스가 혼용되면 오타를 필터링하기 까다롭다
  1. CSS-in-JS(styled-components, emotion…) - 컴포넌트 별 스타일 단위의 stylesheet
  • 스타일링을 JavaScript 내에서 처리할 수 있다
  • 조건부 스타일링이나 동적 스타일 변경이 쉽다
  • 캡슐화하여 재사용성과 유지보수성이 높다
  • CSS-in-CSS에 비해 느림 (예시로 타입추론을 위해 추가적으로 타입 정의를 해줘야한다, d.ts 파일을 별도로 작성해야될 일이 생김 (styled를 명시적으로 다른 타입으로 강제로 변환)
  • 별도 라이브러리 설치로 번들 크기가 증가함 , d.ts와 같은 별도의 파일도 추가로 필요해짐

요약

  • 빠른 속도 , 랜더링 속도 , 인터렉티브한 프로젝트 ⇒ CSS-in-CSS
  • 개발 효율성 , 컴포넌트 기반의 프로젝트 ⇒ CSS-in-JS

2. Vanila-extract 적합

  • CSS-in-CSS - 지금 컴포넌트 기반의 프로젝트 개발이 필요하다. tailwind는 가독성이 너무 안좋음

  • Styled-components , Emotion js 등 - Next13 버전 이후 부터 SSR에서 페이지의 스타일시트 정보가 로드 시점에 포함이 안되서 스타일 적용이 안되는 이슈가 있음

    • Next13 버전 부터 app 디렉토리에 _app.tsx , _documents.tsx를 안쓰기 때문에 이 코드를 사용하지 못함
    // _document.tsx
    export default class MyDocument extends Document {
      static async getInitialProps(ctx: DocumentContext) {
        const sheet = new ServerStyleSheet();
        const originalRenderPage = ctx.renderPage;
     
        try {
          ctx.renderPage = () =>
            originalRenderPage({
              enhanceApp: (App) => (props) =>
                sheet.collectStyles(<App {...props} />),
            });
     
          const initialProps = await Document.getInitialProps(ctx);
          return {
            ...initialProps,
            styles: [initialProps.styles, sheet.getStyleElement()],
          };
        } finally {
          sheet.seal();
        }
      }
    }
    • 대안으로 아래와 같은 별도의 코드가 필요함
    // /app/page.tsx
    import styled from "styled-components";
     
    function HomePage() {
      return <Container>Client Components</Container>;
    }
    export default HomePage;
    const Container = styled.div`
      padding: 0 2rem;
    `;
    import React from "react";
    import { ServerStyleSheet, StyleSheetManager } from "styled-components";
     
    export function useStyledComponentsRegistry() {
      const [styledComponentsStyleSheet] = React.useState(
        () => new ServerStyleSheet()
      );
     
      const styledComponentsFlushEffect = () => {
        const styles = styledComponentsStyleSheet.getStyleElement();
        styledComponentsStyleSheet.instance.clearTag();
        return <>{styles}</>;
      };
     
      const StyledComponentsRegistry = ({
        children,
      }: {
        children: React.ReactNode;
      }) => (
        <StyleSheetManager sheet={styledComponentsStyleSheet.instance}>
          {children as React.ReactElement}
        </StyleSheetManager>
      );
     
      return [StyledComponentsRegistry, styledComponentsFlushEffect] as const;
    }

(1) Vanila-extract 장점

  • 첫번째로 CSS-in-TS
  • All the styling APIs in Vanilla Extract take a style object as input.
    • style object 사용
  • Zero-runtime in TypeScript
    • TypeScript에서 스타일시트를 작성하고 사용할 때, 런타임에 추가적인 처리나 계산 없이 작동
    • styles.css.ts나 .css.ts와 같은 postfix 파일에 작성하기 때문에 작성하는 모든 스타일에 대한 타입 추론이 가능
  • Use TypeScript as your preprocessor
    • TypeScript를 전처리기 처럼 사용 가능함
  • Zero-runtime in TypeScript
    • TypeScript에서 스타일시트를 작성하고 사용할 때, 런타임에 추가적인 처리나 계산 없이 작동
    • CSS-in-JS 라이브러리를 사용하면 런타임에 스타일을 동적으로 생성하고 적용하는 과정이 필요함

(2) Vanila-extract 곧 마주하게 될 단점

-써보면서 장단점 정리