한창 쏘코타이머를 열심히 개발하던 중, 하나의 피드백이 들어왔습니다.
이 Pragma라는 녀석이 매 tsx마다 포함되어있는데, 이걸 babel로 없애버리면 어떠겠냐는 의견이었습니다.
물론 그러면 더 좋죠. 귀찮음도 줄어들고 그만큼 확장성도 늘어날테니까요.
하지만.. 이걸 고민하지 않은 것이 아니었지만... 의식적으로 피하고 있었습니다.
왜냐면 저는 CRA환경에서 개발을 하고 있었기 때문에 babel 설정을 건들기 위해서는 eject를 해야만 했죠.
eject를 하게 된다면 CRA를 쓰는 의미가 없어진다고 생각한 저는 다른 방법을 찾기 시작합니다.
그것이 바로 craco였죠.
목차
0. emotion
emotion는 CSS-in-JS의 대표적인 라이브러리로, JavaScript 안에서 스타일을 작성할 수 있도록 도와주는 요소입니다.
프레임워크를 사용하지 않아도 쓸 수 있고, 저처럼 React 사용 환경에서도 쓸 수 있죠.
아래 emotion 공식 홈페이지를 첨부합니다! (영어의 압박.. 극복해야 합니다..)
다운로드 자체는 아주 쉽습니다. npm이나 yarn으로 아래처럼 설치해주시면 끝입니다!
자세한 사용법이나 장점같은 것들은 StyledComponent와 거의 비슷하기도 하고, 이번 포스팅에서는 사용 설명이 중심이 되는 부분이 아니니 공식 홈페이지에게 임무를 맡기고 생략하도록 하겠습니다.
1. 문제가 뭔데?
Emotion을 사용하기 위해서는 babel preset이나 JSX Pragma가 필요합니다.
이 작업을 통해 컴파일되는 jsx코드가 react.createElement 대신 emotion에서 제공하는 jsx 함수를 사용할 수 있게 됩니다.
해당 가이드가 잘 나와있는 공식 홈페이지의 내용을 첨부합니다!
1.0. babel preset
첫 번째 방법인 babel preset은 babel의 preset을 설정하여 적용하는 방법입니다.
preset에 아래 요소를 넣기만 하면 끝입니다. (물론 버전 상황이나 기타 필요에 따라 추가적인 설정을 더 넣을 수도 있습니다.)
"presets": ["@emotion/babel-preset-css-prop"]
하지만 이 방법은... 아래와 같은 난관에 부딪히게 됩니다.
CRA 혹은 babel 설정을 커스텀할 수 없는 환경에서는 사용할 수 없습니다. JSX Pragma를 사용하세요.
1.1 JSX Pragma
그래서 등장한 두 번째 방법이 바로 JSX Pragma입니다.
Pragma는 컴파일 전처리기로서 jsx 요소들을 컴파일할 때 도와주는 요소입니다.
못믿으시는 분들을 위해 바벨 공식문서도 놓고갑니다. ㅋㅋㅋㅋ
위에서 말했다시피 emotion을 사용하는 각 파일마다 Pragma를 설정함으로써 emotion에서 제공하는 jsx를 사용하겠다는 의미죠.
// React 4버전 미만
/** @jsx jsx */
// React 4버전 이후
/** @jsxImportSource @emotion/react */
2. 해결해보자!
그래서 현재와 같은 JSX Pragma 형태를 babel preset으로 설정하기 위해 babel 설정을 만져야 하는데,
CRA환경에서 babel을 설정할 수 있도록 돕는 요소가 바로 craco입니다.
craco는 Create React App Configuration Override 의 줄임말로 CRA 환경에서 설정을 덮어씌우는 역할을 한다고 보시면 되겠습니다!
이걸 통해 CRA 환경에서도 eslint, babel, postcss등의 설정을 바꿀 수 있습니다!!!
백문이 불여일타라고 우선 설치부터 해봅시다.
npm install @craco/craco
를 이용하면 간단하게 설치할 수 있습니다.
아, 그런데 최신 버전의 리액트를 사용하시는 분들은 오류가 발생할 수 있습니다.
craco의 정식 버전은 아직 CRA 4.* 버전만을 지원하기 때문에 최신 CRA 5.* 버전을 사용하는 경우 위 메시지처럼 설치가 되지 않습니다.
현재 열심히 패치중이라고 하시니.. 저는 알파버전을 사용하도록 하겠습니다.
그리고 이제 우리는 craco의 설정을 사용할 것이기 때문에 package.json의 react-scripts를 craco로 바꿔줍니다.
이제 craco 설정파일을 만들어줍니다.
최상위 폴더에 craco.config.js (혹은 craco.config.ts) 파일을 만들어줍니다.
그리고 그 안에 craco의 기본 양식과 emotion 공식 홈페이지의 양식을 그대로 가져와서 붙여넣기만 하면 됩니다.
저는 굳이 craco.config.ts로 적용해보고 싶어서 eslint 설정까지 바꿔가며 아래처럼 만들었습니다.. ㅋㅋㅋ
// craco.config.js
module.exports = {
babel: {
presets: [
[
"@babel/preset-react",
{ runtime: "automatic", importSource: "@emotion/react" },
],
],
plugins: ["@emotion/babel-plugin"],
},
};
// craco.config.ts
export default {
babel: {
presets: [
[
"@babel/preset-react",
{ runtime: "automatic", importSource: "@emotion/react" },
],
],
plugins: ["@emotion/babel-plugin"],
},
};
필요하다면
npm install @babel/preset-react @emotion/babel-plugin
도 해줍니다. (따로 인스톨한 적이 없으시다면 인스톨 하셔야합니다!)
📢 타입스크립트용 추가설정!!
만약 타입스트립트 환경에서 사용하고 계시다면 tsx파일 최상단(제 경우에는 src/index.tsx), 혹은 d.ts 파일 내부에 아래 컴파일러 지시어를 넣어줍니다.
/// <reference types="@emotion/react/types/css-prop" />
그리고 tsconfig.json에서 compilerOptions내부의 jsx옵션과 jsxImportSource옵션을 바꿔줍니다.
"jsx": "react-jsx",
"jsxImportSource": "@emotion/react",
여기까지 완료하고 pragma를 전부 지우면..?
무사히 동작합니다!! 감동 ㅠㅠㅠ
저는 craco로 설정을 덮은 김에 절대경로까지 추가로 해주었습니다.
그리고 해당 문제를 해결하는 과정에서 eslint와 prettier까지 적용해버렸습니다.
시간이 훌쩍 가버렸네요.. ㅠ
최근댓글