twin.macro는 emotion 또는 styled-componet Lib에 대해 의존성을 가집니다. 그렇기 때문에 설치를 하기 위해선 다른 Lib를 설치할 필요가 있습니다.
또한, 약간의 babel 설정 추가가 필요합니다.
공식문서의 하단을 보면 각각의 환경에 맞는 시작 방법 링크가 적혀있습니다.
우선, CRA환경에서 styled-componets를 사용하는 twin.macro 설치 방법을 알아보겠습니다.
npm install twin.macro styled-components
를 통해 twin.macro와 styled-components를 설치하고, babel-plugin-macros를 dev설정으로 설치합니다.TS를 사용하는경우, @types/styled-components 도 dev설정으로 같이 설치해주어야 합니다.
```
// 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 문법도 추가할 수 있습니다.
방법 자체는 이전에 사용하였던 tailwind-styled-components와 크게 다르지 않습니다.
하지만 백틱(``)을 사용하는 경우 tw을 사용하기위해선 ${}을 해주어야 하고, 배열 형식의 경우에는 바로 사용 해도 된다는 차이가 있습니다.
Next에서 twin.macro를 사용하는것은 기존의 방법과 크게 다르지는 않습니다. 때문에 CRA에서의 설치법과 유사하게 진행해주시면 됩니다.
하지만 몇가지 추가적인 설치와 설정을 해주어야합니다.
// In .babelrc.js
module.exports = {
presets: [['next/babel', { 'preset-react': { runtime: 'automatic' } }]],
plugins: [
'babel-plugin-macros',
['babel-plugin-styled-components', { ssr: true }],
],
}
SSR을 원활하게 진행하기 위해서 pages 폴더 하위에 _document.tsx 파일을 작성하여야 합니다.
_document.tsx 작성링크
tailwind.config.js에서 환경에 맞게 content를 설정해주어야 합니다.
view 페이지를 pages에서 사용한다면 ,"./pages/**/*.{js,ts,jsx,tsx}",
src/pages에서 사용한다면 content: ["./src/**/*.{js,ts,jsx,tsx}"],
와 같이 설정합니다.
위와 같은 설정을 마치면 nextJS에서도 정상적으로 실행이 가능합니다.
(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
...
`,
]);