Don't think! Just do it!

종합 IT 기술 정체성 카오스 블로그! 이... 이곳은 어디지?

Next.js/storybook

Next.js에 StoryBook 설정하기!

방피터 2022. 6. 10. 18:16

아니 이게 뭐야! 이것저것 검색하다보니... 현업에서 스토리북이라는 걸 사용하고 있네.. 역시 등신 에휴.. 또 나만 몰랐네.

역시 사람은 다른 사람들이랑 어울려야 해 ㅋㅋ 혼자 이러고 있으니 참.

스토리북!

스토리북은 ui 컴포넌트랑 page 빌드 툴인데 앱(웹)이랑 분리해서 따로 따로 개발할 수 있도록 돕는 아이래. 결국 ui 컴포넌트 빌딩, 테스트, documentaion의 기능을 제공해준다~ 하는 것이지. 홈페이지 슬로건에 다 나와 있는 말!

스토리북 슬로건

컴포넌트 드리븐이 뭐시여!? https://www.componentdriven.org/ 에 설명이 잘 나와 있어. 간단히 설명하자면 버튼이나 아바타 툴팁 같은 매우 작은 컴포넌트들 독립적으로 만들고 그 조합으로 form, header, list, table 같은 조금 더 복잡한 컴포넌트를 만드는 거지. 그리고 그 컴포넌트들로 페이지를 구성하고 로직 붙여서 프로젝트를 완성하는 방식을 말하는 말하는 거야. 개발 품질, 속도나 관리 뭐 여러가지 측면에서 잇점이 있다고 하네. 당연한거 아니겠어? 컴포넌트들도 재사용 가능하고 말이지. 독립적으로 아주 자알 관리되고 있다면 말이지.

component driven

보통 독립적으로 컴포넌트를 개발하고 유지 & 팀원과 공유하면서 바로바로 프로젝트에 적용하고 이런 건 쉽지 않겠지. 그런데 스토리북은 이걸 돕는다 하니 을마나 좋은 툴이야? 게다가 테스트에 documentation까지! 아 짜증나 나만 몰랐어...

 

일단 next.js 프로젝트에 설치해보자구.  👇

npx sb init --builder webpack5

설치하다보면 자기들 eslint-plugin 안쓰고 있다고 자기들은 설치를 추천한다고 막 ㅋㅋ 그래 해라 해! yes 눌러주고 ㅋ

let's install eslint-plug

자~ 끝났으면 실행 👇👇👇

yarn storybook

 

그럼 브라우져 창이 하나 뜨네 localhost:6006으로

storybook 첫 실행!

대충 감 오지? 왼쪽 메뉴 보면 예제가 있는데 거기 버튼이 있고 그 아래 헤더가 있고 그 아래 페이지가 있네 ㅋ 위에서 말했던 그 컴포넌트 드리븐 방식이네 ㅎㅎ

첫 예제

난 처음에 스토리북에서 컴포넌트 개발하고 그걸 프로젝트에 사용하고 그런 줄 알았는데 그게 아니네? ㅋㅋㅋㅋ 프로젝트에서 컴포넌트 만들 때 스토리북으로 export 시켜서 컴포넌트 별로 테스트하고 관리하는 그런 방식이네. 디자이너나 다른 팀원들 간에 의견 교환하고 그럴 때도 좋을 것 같고. 음 그럼 nextjs 기본 index.tsx를 storybook으로 export 시켜봐야겠다. 스토리북 공식 블로그도 그런 내용이고 ㅎㅎ 👇

https://storybook.js.org/blog/get-started-with-storybook-and-next-js/

 

Get started with Storybook and Next.js

Integrate Storybook with Next.js in four simple steps

storybook.js.org

자 그럼 먼저 stories 폴더에 pages 폴더를 새로 하나 만들고 거기에 home.stories.tsx라는 파일을 하나 만들어 주자고

pages/home.stories.tsx

import Home from "../../pages/index";

export default {
  title: "Pages/Home",
  component: Home,
};

export const HomePage = () => <Home />;

그리고 localhost:6006 를 리프레시 시키면 왼쪽 메뉴에 새로 만들 스토리가 보일거야. 클릭해보면 index.tsx가 보이긴 하는데 스타일이 적용이 안되어 있지.

스타일이 적용 안된 index.tsx

각 컴포넌트나 페이지별로 스타일을 적용해도 되지만 일단 next.js 글로벌 스타일을 storybook에 적용하려면 .storybook 폴더의 preview.js에 globals.css를 import시켜 줘야 해.

// .storybook/preview.js
import "../styles/globals.css";// 여기 추가

export const parameters = {
  actions: { argTypesRegex: "^on[A-Z].*" },
  controls: {
    matchers: {
      color: /(background|color)$/i,
      date: /Date$/,
    },
  },
};

이렇게 하면 전체 스토리에 next.js의 default globals.css가 적용이 되지.

글로벌 스타일 적용됨.

음 다 된 것 같지만 아직 아냐. 스토리 페이지 가장 하단을 보면 이미지가 보이지 않아. 아마 스토리는 public 폴더를 못찾기 때문인 것 같은데... 이걸 해결해주자고!

vercel 이미지가 보이지 않는다.

package.json의 storybook과 build-storybook script option에 각각 -s /public 과 -s public을 추가해주면 돼 👇 static directory를 추가해주는 명령 옵션~

package.json

그리고 storybook을 다시 시작해주면 스토리북에도 vercel 로고를 볼 수 있지.

이제 vercel 로고가 보인다.

여기 까지만 해도 이미지가 잘 보이는데 스토리북 블로그에서는 한 가지를 더 해줘야 한다고 해. 아래처럼 src에서 바로 불러오는 게 아니고 public 경로에서 import해서 가져오면 next.js에서는 잘 보이지만 스토리북에서는 시뻘건 에러를 뿜어내지 ㅎㅎ

//이걸!
<Image src="/vercel.svg" alt="Vercel Logo" width={72} height={16} />


//이렇게 바꾸면!
import vercelImg from "../public/vercel.svg";
...
<Image src={vercelImg} alt="Vercel Logo" width={72} height={16} />
...

 

이런 에러 뿜뿜!

이건 nextjs가 image size optimization을 하기 때문인데 스토리북에서는 이걸 못혀~ 에러가 뿜뿜. 그래서 이 문제를 해결하려고 스토리북에서 사용되는 next/image는 opimization을 꺼버리는 방법을 사용해. 스토리북 공식 블로그에서는 아래 코드를 preview.js에 삽입해서 unoptimized 시킨다고 되어 있는데 개뿔 동작 안함 ㅋ 내가 뭐 잘못했나?

몰라 이거 난 안되더라고~ 이거 안돼~~~~
// .storybook/preview.js
import * as NextImage from "next/image";

const OriginalNextImage = NextImage.default;

Object.defineProperty(NextImage, "default", {
  configurable: true,
  value: (props) => <OriginalNextImage {...props} unoptimized />,
});

 

암튼 개뿔 안됌 ㅋㅋㅋ 그래서 다른 방법을 찾아냈어 ㅋ 바로 아래 코드!

import * as NextImage from "next/image";

NextImage.defaultProps = {
  unoptimized: true,
};

이런식으로 next/image의 기본 옵션에 unoptizimized:true 를 줘서 image optimization을 꺼주면 스토리 북에서도 잘 보이게 되는 거지 ㅎㅎ 다시 말하지만 이건 스토리북에서만 next/image 컴포넌트의 기본 props을 변경하는 거니까 원래 next.js의 image size optimization에는 영향을 미치지 않아~! 걱정마슈!

 

휴 길다~ 이거 좀 자동으로 됐으면 좋겠네 어휴...

이거 보기가 이렇게 힘든가?

이제 스토리북에서 getServerSideProp 적용하는 것도 해야 하는데 ㅎㅎㅎ 너무 길다 한 번 끊어가야지~ 아이고 힘들다~

 

이런식으로 next.js에 이것, 저것 설정하고 나면 next.js 기본 템플릿하나 만들 수 있겠다 ㅎㅎ 해봅시다!

반응형

'Next.js > storybook' 카테고리의 다른 글

Next.JS + Storybook 에서 getServerSideProps() 테스트  (2) 2022.06.11