nextjs 12에서 emotion과 함께하는 tailwindcss
Nextjs 12 is coming...
nextjs 12에서 놀라운 소식이 전해졌습니다. 컴파일러로 swc를 채택했다는 것을요! 여러가지 이유가 있겠지만 가장 중요한 건 기존에 사용하던 babel보다 빌드가 최대 5배나 빨라졌다는 겁니다. 참고로 fast refresh는 최대 3배나 빨라졌다네요!
좋은 소식입니다. 하지만 변화에는 언제나 문제가 발생하기 마련입니다. swc를 활성화하기 위해서는 .babelrc
와 같은 바벨 설정 파일을 완전히 제거해야 합니다. 이런, 그럼 무조건 바벨을 설정해야 하는 경우는요?
그렇습니다. 문제의 발생입니다! 특히 twin.macro
을 아끼는 저는 그만 눈물을 닦아낼 수 밖에 없었습니다. 어떤 분께서 이를 대체하는 stailwc
를 만들었지만 아직은 이르다는 느낌이 어렴풋이 들고 맙니다. 그렇다면, twin.macro
를 포기할 수 밖에 없는 걸까요? 아닙니다!
emotion
yarn add @emotion/react @emotion/styled
or
npm install @emotion/react @emotaion/styled
emotion
을 설치합니다.
tailwindcss
yarn add tailwindcss
or
npm install tailwindcss
tailwindcss
만 설치하면 됩니다.
twin.macro
packages
yarn add twin.macro babel-loader babel-plugin-macros @babel/plugin-syntax-typescript @babel/preset-react
or
npm install twin.macro babel-loader babel-plugin-macros @babel/plugin-syntax-typescript @babel/preset-react
twin.macro
와 함께 설정에 필요한 babel 관련 패키지를 설치합니다. 상황에 따라 더 늘어날 수도 있습니다.
configuration
withTwin.js
const path = require("path");
const includedDirs = [
path.resolve(__dirname, "components"),
path.resolve(__dirname, "pages"),
path.resolve(__dirname, "styles"),
];
module.exports = function withTwin(nextConfig) {
return {
...nextConfig,
webpack(config, options) {
const { dev, isServer } = options;
config.module = config.module || {};
config.module.rules = config.module.rules || [];
config.module.rules.push({
test: /\.(tsx|ts)$/,
include: includedDirs,
use: [
options.defaultLoaders.babel,
{
loader: "babel-loader",
options: {
sourceMaps: dev,
presets: [
[
"@babel/preset-react",
{ runtime: "automatic", importSource: "@emotion/react" },
],
],
plugins: [
require.resolve("babel-plugin-macros"),
require.resolve("@emotion/babel-plugin"),
[
require.resolve("@babel/plugin-syntax-typescript"),
{ isTSX: true },
],
],
},
},
],
});
if (!isServer) {
config.resolve.fallback = {
...(config.resolve.fallback || {}),
fs: false,
module: false,
path: false,
os: false,
crypto: false,
};
}
if (typeof nextConfig.webpack === "function") {
return nextConfig.webpack(config, options);
} else {
return config;
}
},
};
};
babel 설정 파일을 대신해 babel을 설정합니다.
next.config.js
const withTwin = require("./withTwin");
const nextConfig = withTwin({ // <<- `withTwin` 함수 적용
reactStrictMode: true,
swcMinify: true,
});
module.exports = nextConfig;
작성한 withTwin
함수를 적용해 nextjs를 설정합니다.
types
tsconfig.json
{
...,
"types": [
"@types"
]
}
타입을 인식할 디렉토리를 설정합니다.
@types/twin.d.ts
import "twin.macro";
import { css as cssImport } from "@emotion/react";
import styledImport from "@emotion/styled";
import { CSSInterpolation } from "@emotion/serialize";
// `twin.macro`에 다음 타입을 넣음
declare module "twin.macro" {
const styled: typeof styledImport;
const css: typeof cssImport;
}
// DOM의 attribute에 다음 타입을 넣음
declare module "react" {
interface DOMAttributes<T> {
tw?: string;
css?: CSSInterpolation;
}
}
twin.macro
와 관련된 타입을 설정합니다.
TMI
사용하고 있는 tailwindcss에 적용할 수 있나요?
네, class로 tailwindcss를 사용하고 있더라도 설치, 설정을 통해 twin.macro
를 사용할 수 있습니다.
왜 css 관련 설정을 하지 않나요?
twin.macro
는 입력받은 클래스들을 독립적으로 사용 가능한 css로 변환합니다. 따로 정의된 css의 도움을 받지 않고서요.
이 때 변환은 twin.macro
로 이뤄집니다. class로도 tailwindcss를 사용해야 한다면 css 설정을 거쳐야 합니다.
도움이 됐나요?
됐다구요? 다행입니다!
즐거운 개발이 되길 바랄게요!
reference
[GitHub - ben-rogerson/twin.macro: 🦹♂️ Twin blends the magic of Tailwind with the flexibility of css-in-js (emotion, styled-components, stitches and goober) at build time.](https://github.com/ben-rogerson/twin.macro)
[Enable SWC on next examples · ben-rogerson/twin.examples@36ac8c6 · GitHub](https://github.com/ben-rogerson/twin.examples/commit/36ac8c6dcfa80fcf9cfd65b5c4835b8f3aa79c00#diff-8e7430aee7d110ee12e0366c43b2e8328e0eae8fe870a88eae4bbb7532ec26e1)
[Support SWC · Discussion #516 · ben-rogerson/twin.macro · GitHub](https://github.com/ben-rogerson/twin.macro/discussions/516)
[How to config Nextjs for Babel Plugin Macros like twin.macro without disabling swc complier](https://blog.mrcatdev.com/how-to-config-nextjs-for-babel-plugin-macros-like-twinmacro-without-disabling-swc-compiler)
댓글을 작성해보세요.
덕분에 프로젝트에 손쉽게 tw.macro 세팅 마쳤습니다. 감사해요!