[기록] 리액트에서 Emotion이 적용되지 않을 때 해결 방법

JJ·2023년 1월 27일
0
post-thumbnail

서두

간단한 프로젝트에 emotion이라는 styled-component와 같은 css-in-js 라이브러리를 사용하게 되었다.

emotion에선 css라는 함수를 사용하여 css style을 작성한다고 한다. 사용방법은 styled-components와 크게 차이는 없어 작성은 어렵지 않았지만, 에러가 발생하지 않는데도 불구하고, 적용이 되지 않았다. 만일 이 글을 읽고 있다면, 적어도 css나 jsx는 import 했을거라 생각한다.

For Korean

/** @jsxImportSource @emotion/react */

Emotion을 사용한 컴포넌트 파일(source file)의 최상단에 위의 코드를 복붙!

흔적

Emotion에서 리액트의 컴포넌트에 스타일을 설정하는 기본적인 방법은 css prop을 사용한다고 한다.

리액트에 Emotion을 적용하는 방법은 Babel preset과 JSX Pragma가 있다. 나는 이 중에서 비교적 간단해보이는 JSX Pragma를 사용하였다.

공식문서에 따르면, JSX Pragma은 create-react-app이나 codesandbox와 같이 babel configuration을 별도로 하지 않는 경우 사용한다고 하며, 일반적으로는 /** @jsx jsx */를 source file의 최상단에 작성한다고 한다.

물론, 이 글을 읽고 있는 분은 위의 코드를 작성했음에도 Emotion이 적용되지 않을 것이다.

그 이유는 리액트 버전 17에서 지원하는 the New JSX Transform 때문이다.

리액트 공식문서에 따르면, 리액트 버전 17은 이전 버전과 비교하여 새로운 기능의 추가는 없었지만, 새로운 버전의 JSX transform을 제공한다고 한다. 나의 경우, 컴포넌트 생성시 스니펫을 사용하여 기본적인 구조를 작성하기 때문에, 내가 작성한 거의 모든 컴포넌트에는 import React from ‘react’; 가 존재하는데, 버전 17 이후에서는 이것을 삭제해도 코드는 여전히 동작한다고 한다. 물론, 리액트의 Hooks 나 다른 것들을 위해선 여전히 필요하다. (ㅡㅡ;;)

그렇다면 공식문서에 나와있는 예제 코드를 통해 알아보자

// The Old JSX transform
import React from 'react';

function App() {
	return <h1>Hello World</h1>;
}
----------transform----------
import React from 'react';

function App() {
	return React.createElement('h1', null, 'hello world');
}

구버전의 경우 JSX 코드가 React.createElement로 변환되어 React element를 생성한다.

// The New JSX transform
function App() {
	return <h1>Hello World</h1>
}
----------transform----------
// Inserted by a compiler (자동으로 import 구문이 작성된다)
import {jsx as _jsx} from 'react/jsx-runtime';

function App() {
	return _jsx('h1', { children: 'Hello World' });
}

다음과 같이 새로운 JSX Transform은 컴파일 시 자동으로 특별한 함수를 import 하여 구 버전의 JSX transform과 다르게 React.createElement를 사용하지 않고, jsx()로 변환된다.

다시 돌아와서 리액트 버전 17 이후로는 새로운 JSX transform의 적용으로 인하여 기존 사용했던 방법으로 해결이 되지 않고, /** @jsxImportSource @emotion/react */를 사용해야 한다.

결론

공식문서를 주의깊게 읽자!!

profile
한줄 한줄

0개의 댓글