Next.js 13 에서 Storybook 도입 방법과 svg를 쉽게 사용하기 위해 SVGR 라이브러리를 적용하는 과정에서 발생한 이슈 사항과 해결방법에 대해 정리해보려고 합니다. 저 같은 삽질하는 사람이 없길 바라면서...
먼저 Next.js 13 에서 Storybook을 도입하는 방법에 대해 찾아봤습니다. 기존 방식대로 하기는 좀 옛날거 같아서요. Storybook도 버전 7이 나온거 같더라고요.
공식 문서 : https://storybook.js.org/releases/7.0?ref=storybookblog.ghost.io
2023년 3월 발표되었군요? 정말 최근이네요. 7 버전에서는 뭐가 바뀌었을까요?
참고 : https://storybook.js.org/blog/integrate-nextjs-and-storybook-automatically/
그리고 Next.js와 Storybook 에 대한 자세한 글은 위 사이트에서 확인해볼 수 있습니다. 한번 사용해볼까요?
npx storybook@next init
이렇게만 해주면 평소처럼 .storybook 폴더가 생기고 stories가 샘플로 생깁니다. 실행해보면 체감상 속도가 이전보다 더 빨라진거 같습니다.
import type { StorybookConfig } from "@storybook/nextjs";
const config: StorybookConfig = {
stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
addons: [
"@storybook/addon-links",
"@storybook/addon-essentials",
"@storybook/addon-interactions",
],
framework: {
name: "@storybook/nextjs", // nextjs가 들어가 있군
options: {},
},
docs: {
autodocs: "tag",
},
};
export default config;
설정을 보면 단순히 framework에 "@storybook/nextjs"가 추가된거 같습니다. 찾아보니 해당 설정은 "NextJS와 웹팩 및 Babel 종속성과 함께 작동하도록 Storybook을 설정합니다. 추가 구성이나 보일러 플레이트가 필요하지 않습니다." 라고 합니다. 즉, zero-config가 이 뜻인거 같습니다. 정말 편한거 같네요.
참고 : https://blog.logrocket.com/building-next-js-app-tailwind-storybook/
storybook에서 tailwindcss를 쓰려면 globals.css를 import해줘야 합니다. preview.ts에다가 추가해주면 됩니다.
import "../src/app/globals.css";
참고 : https://react-svgr.com/docs/next/
SVGR 라이브러리를 사용하면 SVG를 React 구성 요소로 가져오도록 Next.js 프로젝트를 구성해줍니다. 예시를 보면 쉽게 이해가 갑니다. svg를 사용하기 쉽게 만들어주는거 같아서 적용해보려고 합니다.
import Star from './star.svg'
const Example = () => (
<div>
<Star />
</div>
)
근데 설치만 한다고 바로 되는 것이 아니라 next.config.js에서 설정을 해줘야 합니다. 앞으로 svg 파일은 @svgr/webpack 을 적용해서 사용하겠다는 의미입니다.
/** @type {import('next').NextConfig} */
const nextConfig = {
experimental: {
appDir: true,
},
webpack(config) {
config.module.rules.push({
test: /\.svg$/i,
issuer: /\.[jt]sx?$/,
use: ["@svgr/webpack"],
});
return config;
},
...
}
svg 타입스크립트 적용을 위해서 global.d.ts를 만들어주는 것을 추천합니다.
declare module "*.svg" {
const content: React.FunctionComponent<React.SVGAttributes<SVGElement>>;
export default content;
}
굿. Next.js에서 이제 svg 아이콘을 잘 불러와서 사용할 수 있게 되었습니다.
Storybook에서도 SVGR 설정이 필요합니다.
참고 : https://github.com/storybookjs/storybook/issues/18557#issuecomment-1426150038
해당 이슈에 댓글을 참고해서 이런식으로 작성하면 됩니다. 마찬가지로 svg를 찾아서 @svgr/webpack으로 적용되도록 설정을 바꿔주는 거 같습니다.
webpackFinal: async (config) => {
const imageRule = config.module?.rules?.find((rule) => {
const test = (rule as { test: RegExp }).test;
if (!test) {
return false;
}
return test.test(".svg");
}) as { [key: string]: any };
imageRule.exclude = /\.svg$/;
config.module?.rules?.push({
test: /\.svg$/,
use: ["@svgr/webpack"],
});
return config;
},
svg 아이콘이 잘 적용된 것을 볼 수 있습니다.
처음에는 이게 왜 안 되는지 잘 몰라서 찾아보고 삽질도 해보면서 되는 걸 찾아서 성공했습니다... 설정이 조금 까다로운 면이 있었는데 저 같은 삽질이 없길 바라면서..ㅎㅎ
next.js app router를 storybook에 적용시키는 것도 성공하셨나요?