storybook에 global scss 세팅하기

Tony·2023년 3월 3일
0

react

목록 보기
68/86

storybook을 세팅하는 것은 간단하다

npx storybook init 을 하면 설치 및 예제까지 세팅이 된다

그런데 사내 UI 라이브러리에서 scss를 global로 사용하고 있는 경우에 scss 관련 설정이 약간 필요하다
그리고 그 scss에서 font, image를 사용하고 있다면 에러가 발생할 수 있는데 오늘 해결했던 이슈를 정리해보자

모듈에서 js 확장자

ui 라이브러리는 보통 package.json에서 type을 module로 설정해서
npx storybook init으로 설치된 .storybook 폴더 안에 js확장자는 cjs로 바꿔줘야 한다

만약 preview.cjs에서 emotion이나 mui 같은 라이브러리의 global css를 위한 컴포넌트를 추가해야 한다면 확장자를 jsx로 바꿔줘야 한다

story 에 global scss 추가하기

사실 개인적으론 scss를 잘 사용하지 않는다
css in js를 선호하는 편이지만 회사의 퍼블리싱을 주로 하시는 분이 scss를 즐겨 사용하기 때문에 세팅을 해야했다

공통으로 무언가 적용해야되는 것은 preview.jsx에 import하면된다

하지만 scss를 기본적으로 지원하진 않기 때문에 추가로 플러그인을 설치해줘야한다

회사에서 sasss transpiler로 Dart sass를 사용하고 있기 때문에

storybook-addon-sass-postcss 을 설치하고 dart sass에 맞게 설정해주었다

공식문서에 있는 대로 해도 해결되지 않고 어떤 에러메시지(스크린샷을 찍어놓지 않아 기억나지 않음)가 나와서 아래와 같이 webpack 설정을 해주었다

// {packages}/.storybook/webpack.config.cjs

// Export a function. Accept the base config as the only param.
module.exports = async ({ config, mode }) => {
  // `mode` has a value of 'DEVELOPMENT' or 'PRODUCTION'
  // You can change the configuration based on that.
  // 'PRODUCTION' is used when building the static version of storybook.
 
  config.module.rules = config.module.rules.filter(
    (rule) => !rule.test.test(".scss"),
  );

  // Make whatever fine-grained changes you need
  config.module.rules.push({
    test: /\.scss$/,
    loaders: ["style-loader", "css-loader", "sass-loader"],
    include: path.resolve(__dirname, "../"),
  });

  config.resolve.roots = [path.resolve(__dirname, "../public"), "node_modules"];

  // Return the altered config
  return config;
};
  • 구글링하다 찾음

sass loader가 필요해서
"style-loader", "css-loader", "sass-loader"를 설치했는데 웹팩에서 최신 버전은 지원이 되지 않는다고 해서 버전을 낮추었다

  • "css-loader": "5.2.6",
  • "sass-loader": "10.1.1",
  • "style-loader": "2.0.0"

scss에서 사용하는 font 및 image 경로 변경하기

이게 가장 리스크있는 작업이었다

왜냐하면 공통 이미지는 scss 뿐만 아니라 다른 ui컴포넌트에서도 사용했기 때문이다
(이것 때문에 lint에서 걸린 수많은 컴포넌트에서 경로를 일일이 다 바꾸어주었다)

global.scss에서 아래와 같이 경로를 사용하고 있었다

@font-face {
  font-family: "noto";
  font-weight: 600;
  src: url("./fonts/NotoSansKR-Bold.woff2") format("woff2"),
    url("./fonts/NotoSansKR-Bold.woff") format("woff"),
    url("./fonts/NotoSansKR-Bold.otf") format("opentype"),
    url("./fonts/NotoSansKR-Bold.otf") format("truetype");
}

이 경로는 rollup에서 빌드할 때 scss도 컴파일 되면서 dist의 루트에 생긴 것을 기준으로 작성된 경로라서 기존에 styles, fonts, images가 같은 depth에 존재했었던 것이 문제가 되었다
sass-loader에선 현재 scss를 기준으로 경로를 파악하기 때문에
global.scss가 assets에 존재하고 fonts -> assets/fonts, images -> assets/images로 이동해서 경로를 맞춰 주었다

추가로 rollup에서 빌드 후 scss로 부터 생성되는 globalStyle.css 생성 경로를 assets/globalStyle.css로 변경하는 것까지 해서 완전히 맞춰주었다

// rollup.config.js
import scss from "rollup-plugin-scss";

export default {
  input: ["src/index.ts"],
  // ...
  plugins: [
    scss({
      fileName: "assets/globalStyle.css",
      failOnError: true,
      watch: "src/assets",
    }),
  	// ...
  ]
  // ...
}

흥미로운 점

  • 공통 ui 라이브러리는 rollup으로 번들링을 하고 있었지만
  • storybook을 띄울 땐 storybook이 웹팩을 사용하고 있기 때문에 웹팩으로 띄웠다
    • 그래서 .storybook/webpack.config.cjs 파일에서 스토리북 웹팩 설정을 할 수 있다

정리

이렇게 적고보니 별거 아니었지만 각 단계별로 에러를 마주하면서 구글링을 통해 답을 찾아갈 땐 상당히 번거로웠다
그리고 이미지 경로 변경으로 인해 각 컴포넌트에서 사용중인 이미지 경로를 조정해주는 것도 일이었다

이번 계기로 assets이란 디렉토리 개념을 앞으로도 가져가고 assets엔 global.css를 위치시켜야겠다

  • assets
    • images
    • fonts
    • css 또는 styles
    • global.css 또는 global.ts 또는 global.scss

이런 폴더 구조를 가져갈 것 같다

profile
움직이는 만큼 행복해진다

0개의 댓글