Styling? with Linaria!

asdhugh1·2019년 6월 4일
6
post-thumbnail

🤔 Linaria?

Linaria런타임 오버헤드가 없는 CSS-in-JS 라이브러리입니다. 기본 아이디어는 styled-components나 emotion, glamor 등과 비슷하죠.

❓ 선택의 이유

사실 styled-components 좋죠. 설정도 편하고, 타입스크립트도 잘 지원하고. 근데 마음에 안 드는 구석이 있었어요.

바로 별 거 아닌데 너무 깊어진다는 점이었죠! (styled-components 호환 API를 사용하면 linaria도 마찬가지지만요) 그리고 런타임 오버헤드 없음 같은 거 좋잖아요. SC는 너무 런타임에 흑마술을 부리는 것 같고. 또 linaria의 동적 스타일링 방법론에 묻어나는 느낌도 너무 마음에 들었어요.

🚀 적용하기

저는 React를 주로 사용하기 때문에 React 기반으로 설정을 진행했어요. webpack/babel을 직접 건들 수 있는 상황이라면 공식 설명을 따르는 것이 더 좋아요.

😓 create-react-app과의 불편한 관계

create-react-app으로 만든 앱은 정말 환상적이죠. 그 밖으로 벗어나기가 귀찮다는 점만 빼면요. 그냥 평범하게 eject 할 수도 있지만 eject로 제 프로젝트를 더럽히고 싶지 않았어요.

🔧 1. react-app-rewired

react-app-rewired는 가장 널리 알려진 react-scripts 트위커일 거에요. 처음엔 이걸 쓰려고 했어요. 다만 어떤 레포지토리 때문에 빙빙 돌아서 벗어나게 됩니다... 설정 코드는 다음과 같이 작성했어요.

module.exports = {
  webpack: webpackConfig => {
    // 스크립트 로더를 가져와서
    const loader = webpackConfig.module.rules[2].oneOf[1];

    loader.rules = [
      // 기존 로더에다가
      {
        loader: loader.loader,
        options: {
          presets: [...loader.options.presets]
        }
      },
      // linaria 로더 더하기
      {
        loader: 'linaria/loader',
        options: {
          cacheDirectory: 'src/.linaria_cache',
          sourceMap: process.env.NODE_ENV !== 'production',
          babelOptions: {
            presets: loader.options.presets
          }
        }
      }
    ];

    return webpackConfig;
  }
};

🔧 2. craco

사실 처음엔 react-app-rewired를 쓸 생각이었는데, 에서 다들 linaria-cra를 쓴다길래 저도 저걸 쓰려고 했습니다. 그런데 craco라는 처음 듣는 트위커를 사용하는 거에요. 썩 나빠보이지는 않길래 썼습니다. 그리고 꽤나 괜찮았습니다. linaria-cra를 따라가도 좋지만 코드가 조금 마음에 안 들어서 아래와 같이 쓰고 있습니다 (그리고 이 핵같은 코드 대신 더 좋은 코드를 얻기 위해 하루를 낭비했고, 실패했습니다).

const { loaderByName, getLoader } = require('@craco/craco');

module.exports = {
  webpack: {
    configure: webpackConfig => {
      // 스크립트 로더를 가져와서
      const lm = getLoader(webpackConfig, loaderByName('babel-loader'));
      const loader = lm.match.loader;

      loader.rules = [
        // 기존 로더에다가
        {
          loader: loader.loader,
          options: {
            presets: [...loader.options.presets]
          }
        },
        // linaria 로더 더하기
        {
          loader: 'linaria/loader',
          options: {
            cacheDirectory: 'src/.linaria_cache',
            sourceMap: process.env.NODE_ENV !== 'production',
            babelOptions: {
              presets: loader.options.presets
            }
          }
        }
      ];

      return webpackConfig;
    }
  }
};

🎉 사용하기

HMR 작동이 안 되길래 craco를 쓰다 react-app-rewired를 쓰다 craco로 돌아오고 react-scripts v3를 v2로 내리기도 하고 그러며 우여곡절 끝에 프로젝트를 설정했습니다. TypeScript도 예쁘게 잘 들어갔구요. 다만 코드는 조금 귀찮아졌습니다.

하지만 장풍이 사라진 자리에는 감동 그 자체.

😎 결론

linaria의 셋업은 귀찮았지만 linaria는 우아함 그 자체였고 상당히 만족스럽습니다.

profile
04년생 소프트웨어 개발자 && Rust, Kotlin, TypeScript에 관심을 갖고 있어요 && 가끔 이상한 짓을 해요

3개의 댓글

comment-user-thumbnail
2019년 6월 4일

styled-components 의 대체제로는 emotion 정도만 생각하고 있었는데, 이것도 괜찮아보이네요!
장풍 더 이상은 naver...

그런데, Linaria 에서는 조건부 스타일링 하고 싶다면 우찌해야할까용? 궁금합니다.
그냥 일반 CSS / Sass 쓸 때 처럼 직접 문자열끼리 조합하거나 classnames 같은 유틸을 사용해야 할까요?!

2개의 답글