webpack 환경에서 @emotion JSX Pragma 자동으로 적용하기 (+Storybook)

RuLu·2024년 5월 22일
0

Etc.

목록 보기
13/13

@emotion을 사용하다보면 흔히 아래 오류를 볼 수 있다.

You have tried to stringify object returned from css function. It isn't supposed to be used directly (e.g. as value of the className prop), but rather handed to emotion so it can handle it (e.g. as value of css prop).,You have tried to stringify object returned from css function. It isn't supposed to be used directly (e.g. as value of the className prop), but rather handed to emotion so it can handle it (e.g. as value of css prop).,You have tried to stringify object returned from css function. It isn't supposed to be used directly (e.g. as value of the className prop), but rather handed to emotion so it can handle it (e.g. as value of css prop).

JSX Pragma

이 문제는 트랜스파일러가 JSX 코드를 변환할 때 Emotion의 jsx() 함수 대신 react의 jsx()함수를 사용해 발생하는 문제이다. 가장 쉬운 해결 방법은 /** @jsxImportSource @emotion/react */ 혹은 /** @jsx jsx */를 emotion 사용처 파일마다 맨 위 상단에 붙여주는 것이다.

Emotion – The css Prop

그렇지만 솔직히 매번 붙여주는 것 굉장히 번거롭고 귀찮고 빼먹기 쉬운 작업이다. 자동으로 입력하기 위한 방법이 빌드 환경마다 조금씩 다른데 webpack + Typescript를 사용한다면 많이 쉽다.

Webpack + Typescript 에서 JSX Pragma 자동설정

먼저 내 프로젝트는 webpack + typescript + react 로 이루어져있으며 esbuild-loader을 사용한다.

프로젝트 tsconfig 파일에 아래와 같이 추가해주면 된다.🫠

{
  "compilerOptions": {
  ...설정
    "jsxImportSource": "@emotion/react",
	...설정
	}
}

나는 이걸 모르던 시절 preset 설정을 성공하기 위해 여러 방법을 적용했는데 가장 많이 나오는 @emotion/babel-plugin 이나 @emotion/babel-preset-css-prop 을 설치해 babel preset을 사용하는 방법은 CRA환경에서 craco를 이용해 설정하는 방법인 것 같다. 때문에 나처럼 babel loader을 사용하지 않아도 추가적인 설치 없이 적용된다.

문제는 Storybook는 별개로 작동한다는 점… << 이게 내가 그동안 억지로 하나하나 파일마다 JSX Pragma를 붙였던 이유다.

Storybook에서 @emotion JSX변환 자동설정

Storybook은 자체적으로 빌드 설정을 가지고 있다. 그리고 왜인지 tsconfig가 안먹더라. 찾다보니 어떤 스토리북 레포의 issue에서 .storybook 디렉토리 하위에 tsconfig 설정을 두면 적용된다길래 관련해서도 따로 파일도 만들어보고 config를 불러와서 main.ts에서 적용해보기도 하고… 뭔짓을 해도 안되더라.

또한 babel.config를 이용하는 방법도 있어서 도전해봤음. 찾다가 보니까 @emotion/babel 라이브러리 관련된 것들 공식문서에서 storybook이 작동하면서 바벨설정파일이 있으면 읽어서 자동으로 설정해준댔는데 그거도 안됨.. 찾아보면 다 프로젝트 환경설정 관련된 해결방법이고 그나마 스토리북 설정 이슈는 이거였는데 여기에 있는 모든거 해봐도 안되더라.

Can't get emotion's css prop working inside storybook #7540

내가 뭘 놓친게 있나 싶어서 마지막 츄라이로 검색키워드를 변경하던와중 내 눈에 딱 보인 storybook addon… 그것은 바로 @storybook/addon-webpack5-compiler-babel 이다.

알고보니 이걸 설치해야 storybook이 내가 따로 정의한 babel.config 설정을 컴파일할 때 함께 적용해주는 것이었다.😇😇😇😇 (너무 허무해)

설치

npm i -D @storybook/addon-webpack5-compiler-babel

스토리북 main.ts 설정

//storybook의 main.ts
...기타 등등 import 
require('../babel.config'); //이거 작성

const config: StorybookConfig = {
  stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
  addons: [
   ...나머지 에드온, 
    '@storybook/addon-webpack5-compiler-babel',
  ],
  ... 설정
  swc: () => ({
    jsc: {
      transform: {
        react: {
          runtime: 'automatic',
        },
      },
    },
  }),
 ... 나머지 설정
};
export default config;

babel.config 설정

아래 라이브러리중 설치안된게 있으면 -D 설정으로 설치하면 된다.

//babel.config.js
module.exports = {
  presets: ['@babel/preset-typescript'],
  plugins: [
    [
      '@babel/plugin-transform-react-jsx',
      { runtime: 'automatic', importSource: ['@emotion/react'] },
    ],
    'react-require',
  ],
};

후기

아 드디어 성불한다… 왜 항상 내가 겪는 문제는 쉽지않은 문제들일까..? 이 방법보다 더 간단하고 좋은 방법이 있을지도 모르지만 당장은 성공한 나에게 치얼스,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,ㅠㅠ

profile
프론트엔드 개발자 루루

0개의 댓글