- Published on
React의 새로운 JSX Transform 환경에서 Emotion CSS prop 사용 설정하기
React 16.14.0 이후 도입된 새로운 JSX Transform 환경에서 css-in-js 라이브러리 Emotion
의 css prop을 사용할 수 있도록 설정하는 방법입니다.
새 JSX Transform이 도입된 지 오랜 시간이 지나지 않았기도 하고, 이전 버전 React 기준으로 작성되어 있는 자료가 많아 다소 혼동이 되는 경우가 있었습니다.
Babel 설정을 수정할 수 있는 경우
Babel 설정을 직접 수정할 수 있는 경우는 아래와 같이 설정하면 됩니다.
{
"presets": [
["@babel/preset-react", { "runtime": "automatic", "importSource": "@emotion/react" }]
],
"plugins": ["@emotion/babel-plugin"]
}
Next에서는 아래와 같이 설정해야 합니다.
{
"presets": [
[
"next/babel",
{
"preset-react": {
"runtime": "automatic",
"importSource": "@emotion/react"
}
}
]
],
"plugins": ["@emotion/babel-plugin"]
}
Babel 설정을 수정할 수 없는 경우/하고 싶지 않은 경우
Babel 설정을 수정하지 않고 CSS Prop을 사용하려면 .jsx
/.tsx
파일 최상단에
/** @jsxImportSource @emotion/react */
pragma를 설정하면 됩니다.
참고
- 위처럼
@emotion/react
를 import하면 Emotion 공식 문서나 여러 자료에서 언급되는@emotion/babel-preset-css-prop
은 새 JSX Transform에서는 더 이상 필요가 없습니다. - css prop을 사용하지 않을 예정이라면 위와 같은 설정이 필요 없습니다.
어떻게 작동하는가?
React 블로그에 따르면 새 JSX Transform 런타임은 JSX 코드를 아래와 같이 변환합니다.
import { jsx as _jsx } from "react/jsx-runtime"
function App() {
return _jsx("h1", { children: "Hello world" })
}
위 코드에서는 react/jsx-runtime
이 JSX Transform 런타임의 진입점(Entry point)이 됩니다.
한편, Emotion의 React 전용 라이브러리인 @react/emotion
의 내부 코드를 살펴보면
var ReactJSXRuntime = require("react/jsx-runtime"),
Fragment = ReactJSXRuntime.Fragment
function jsx(type, props, key) {
return emotionElement.hasOwnProperty.call(props, "css")
? ReactJSXRuntime.jsx(
emotionElement.Emotion,
emotionElement.createEmotionProps(type, props),
key
)
: ReactJSXRuntime.jsx(type, props, key)
}
function jsxs(type, props, key) {
return emotionElement.hasOwnProperty.call(props, "css")
? ReactJSXRuntime.jsxs(
emotionElement.Emotion,
emotionElement.createEmotionProps(type, props),
key
)
: ReactJSXRuntime.jsxs(type, props, key)
}
컴포넌트에 css prop이 있을 경우 이를 컴파일 할 수 있도록 기존 ReactJSXRuntime
을 확장하고 있습니다.
상단에 언급한 바벨 설정에서 importSource
의 값을 바꾸는 이유도 결국 React에서 제공하는 JSX 컴파일러를 Emotion의 JSX 컴파일러로 지정하기 위함일 것입니다.
따라서 @emotion/babel-preset-css-prop
없이 css prop을 바로 사용할 수 있게 됩니다.
타입스크립트 설정
tsconfig.json
에 아래와 같은 옵션을 추가해 Emotion의 jsx runtime을 인식할 수 있도록 설정하면 됩니다.
{
"compilerOptions": {
...
"jsxImportSource": "@emotion/react",
...
},
...
}
Next.js 12 이후에서 생기는 작은 문제
Next가 버전 12로 업데이트 되면서 Rust 기반의 자체 컴파일러를 도입했습니다. 이 컴파일러는 Babel을 대체하는 것이므로, 바벨 설정을 위해 .babelrc
를 수정하면 다시 새 컴파일러 대신 Babel을 사용하게 됩니다.
따라서 Emotion 뿐만 아니라 별도의 Babel 설정이 필요한 라이브러리들을 사용하는 데에 이슈가 생기게 되는데, Next 측에서는 이러한 라이브러리들이 Rust 컴파일러에서도 실행될 수 있도록
별도의 작업을 진행 중이라고 합니다.