[Tailwind CSS] twin.macro 설치 하기 with react / next

jun gwon·2022년 11월 28일
0

TailwindCSS

목록 보기
3/3

twin.macro

npm 문서

twin.macro는 emotion 또는 styled-componet Lib에 대해 의존성을 가집니다. 그렇기 때문에 설치를 하기 위해선 다른 Lib를 설치할 필요가 있습니다.

또한, 약간의 babel 설정 추가가 필요합니다.
공식문서의 하단을 보면 각각의 환경에 맞는 시작 방법 링크가 적혀있습니다.

CRA환경에서 설치

우선, CRA환경에서 styled-componets를 사용하는 twin.macro 설치 방법을 알아보겠습니다.

  1. 기본적으로 tailwind와 같이 사용되는 Lib 추가와, config 설정 및 import 설정이 되어있어야합니다. (첫번째 글 참조)
  2. npm install twin.macro styled-components 를 통해 twin.macro와 styled-components를 설치하고, babel-plugin-macros를 dev설정으로 설치합니다.
    TS를 사용하는경우, @types/styled-components 도 dev설정으로 같이 설치해주어야 합니다.
  3. babelMacro 설정을 통해 twin.macro가 styled-components 을 사용할 수 있도록 해주어야 합니다. 2가지 방법이 있습니다.
    3-1. 프로젝트 최상단에 babel-plugin-macros.config.js을 생성하여 아래와 같은 코드를 추가합니다.
    ```
      // babel-plugin-macros.config.js
      module.exports = {
      twin: {
       preset: 'styled-components',
      },
      }
    ```
    3-2. pacakge.json 파일에 아래와 같은 코드를 추가합니다.
    // package.json
     "babelMacros": {
       "twin": {
         "preset": "styled-components"
       }
     },

둘다 기본적으로 babel-plugin-macros를 사용하여 내부적으로 twin.macro가 사용할 Lib를 연결해주는 설정입니다.
관련 정보

Styled-components로 생성한 컴포넌트는 unique한 클래스 값을 가진 무작위 네임으로 바뀌어버립니다.
때문에 이전 tailwind-styeld-components를 사용한 dark 모드방식이 작동하지 않습니다.

(이전방식)

  const DarkModeWrapper = tw.div`
      ${(p) => (p.dark ? "dark" : "")}
  `;

이런 상황에서 twin.macro를 사용할경우 해결방법은 두가지로 나뉘게 됩니다.
1. tw.div로 컴포넌트화만 하고, className은 직접 명시하는 방법입니다.

	const DarkModeWrapper = tw.div``;
    사용방법..
    </DarkModeWrapper> className={`${isDark && "dark"}`}>
        ...
    </DarkModeWrapper>

2.document에 직접 접근하여, root의 클래스네임 조작하기

   const root = window.document.documentElement
   제거..
   root.classList.remove("dark")
   추가..
   root.classList.add("dark")

사용방법

twin.macro의 CSS-IN-JS 방식은 크게 2가지 방식이 있습니다,
배열 형식으로 값을 입력하는것과, 기존 styled-componets의 방식과 유사한 백틱 방식인데, 두가지 방식으로 기존 darkmode의 toggle UI를 적용해보겠습니다.

(기존 toggle input)

	    <input
		....
          className={`${
            toggle ? "-translate-x-6 bg-white " : "translate-x-0 bg-blue-400 "
          }focus:outline-none w-6 h-6 rounded-full absolute  ....`}
	....
        />

=> twin.macro 사용

(백틱 사용)

  const ToggleInput = styled.input`
    ${({ toggle }) =>
      toggle ? tw`-translate-x-6 bg-white ` : tw`translate-x-0 bg-blue-400 `};
    ${tw` 
    focus:outline-none 
    w-6 
    h-6 
    rounded-full 
    absolute 
    ...
   `}
  `;

(배열 형식 사용)

  const ToggleInput = styled.input(({ toggle }) => [
    toggle ? tw`-translate-x-6 bg-white ` : tw`translate-x-0 bg-blue-400 `,
    tw`
    focus:outline-none
    w-6
    h-6
    rounded-full
    absolute
    ...
  `,
  ]);

두 방법 모두 기존 styled-componet css 문법도 추가할 수 있습니다.

사용 git repo

방법 자체는 이전에 사용하였던 tailwind-styled-components와 크게 다르지 않습니다.

하지만 백틱(``)을 사용하는 경우 tw을 사용하기위해선 ${}을 해주어야 하고, 배열 형식의 경우에는 바로 사용 해도 된다는 차이가 있습니다.

NextJS(TS) 에서 사용하기

공식문서

Next에서 twin.macro를 사용하는것은 기존의 방법과 크게 다르지는 않습니다. 때문에 CRA에서의 설치법과 유사하게 진행해주시면 됩니다.

하지만 몇가지 추가적인 설치와 설정을 해주어야합니다.

  1. create next app은 babel-plugin-macros이 깔려있지 않습니다. 때문에 추가적으로 dev설정으로 설치해주어야 합니다.
    -> 설치 후, 기존과 같이 babel-plugin-macros.config.js 파일 또는 package.json에 preset 설정을 해주어야 합니다.
  2. TS와 같이 사용하기 위해선 @types/styled-components를 dev 설정으로 설치가 필요합니다.
  3. .babelrc.js 파일을 생성하여 아래와 같은 설정을 추가하여야 합니다.
  // In .babelrc.js
  module.exports = {
    presets: [['next/babel', { 'preset-react': { runtime: 'automatic' } }]],
    plugins: [
      'babel-plugin-macros',
      ['babel-plugin-styled-components', { ssr: true }],
    ],
  }
  1. SSR을 원활하게 진행하기 위해서 pages 폴더 하위에 _document.tsx 파일을 작성하여야 합니다.
    _document.tsx 작성링크

  2. tailwind.config.js에서 환경에 맞게 content를 설정해주어야 합니다.
    view 페이지를 pages에서 사용한다면 ,"./pages/**/*.{js,ts,jsx,tsx}",
    src/pages에서 사용한다면 content: ["./src/**/*.{js,ts,jsx,tsx}"], 와 같이 설정합니다.

위와 같은 설정을 마치면 nextJS에서도 정상적으로 실행이 가능합니다.

TS환경에서의 사용방법

(TS환경에서 아래와 같은 styled를 twin.macro에서 찾을수 없다고 나오는 경우, styled를 styled-components에서 가져와 해결할수있습니다.)

이전 ToggleInput에서 TS를 적용하는것을 예시로 하겠습니다.
기존 toggle의 값을 가져왔는데, toggle의 타입을 지정하여 사용할 수 있습니다. props의 타입을 지정하는것 외에 추가적인 설정은 없습니다.

  const ToggleInput = styled.input(({ toggle }:{ toggle: boolean }) => [
    toggle ? tw`-translate-x-6 bg-white ` : tw`translate-x-0 bg-blue-400 `,
    tw`
    focus:outline-none
    w-6
    h-6
    rounded-full
    absolute
    ...
  `,
  ]);

0개의 댓글