DEV Community

Cover image for How to set up Storybook for Tailwind CSS + Next.Js 12 (existing project)
soom
soom

Posted on • Edited on

4 3

How to set up Storybook for Tailwind CSS + Next.Js 12 (existing project)

Abstract

Introducing how to apply Storybook for Tailwindcss component on Next.js framework.

UI Component Documentation 하면 떠오르는 가장 대표적인 도구는 바로 Storybook 이다.
이번에 포스팅할 내용은 Utility-first CSS framework인 Tailwind CSS를 적용한 Next.Js 기반 Storybook 을 작성하는 방법이다.

기존 Storybook에 올라온 Next.Js 12 적용 방법은 하기의 명령어를 이용해storybook cli 기능을 이용해서 프로젝트를 setup 하는 방식이다.
하지만 이 방법은 시간이 오래 걸리는데다 실패율도 높다는 단점이 있다.

npx sb init --builder webpack5
Enter fullscreen mode Exit fullscreen mode

따라서 본 포스팅에서는 기존 프로젝트에 직접 Storybook을 적용하는 방법을 소개하고자 한다.

기존 방법은 하기 관련 링크를 참조:
https://storybook.js.org/blog/get-started-with-storybook-and-next-js/


Getting Started

Setting up Next.js Application

원하는 프로젝트를 폴더에 Next.Js TypeScript + Tailwind CSS 프로젝트 생성

Terminal
# Next.Js 프로젝트 생성
pnpm create next-app . --typescript

# Tailwind CSS 설치
pnpm add -D tailwindcss postcss autoprefixer

pnpm dlx tailwindcss init -p
Enter fullscreen mode Exit fullscreen mode
tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
    content: ['./pages/**/*.{js,ts,jsx,tsx}', './components/**/*.{js,ts,jsx,tsx}'],
    theme: {
        extend: {},
    },
    plugins: [],
};
Enter fullscreen mode Exit fullscreen mode
styles/globals.css
@tailwind base;
@tailwind components;
@tailwind utilities;
Enter fullscreen mode Exit fullscreen mode

Tailwind CSS을 이용한 버튼 컴포넌트 Button.tsx을 생성

components/Button.tsx
import type { FC } from 'react';

interface ButtonProps {
    name: string;
    className: string;
}

const Button: FC<ButtonProps> = ({ name, className }) => {
    return (
        <button className={`p-2 rounded-lg shadow-lg hover:shadow font-bold ${className}`}>
            {name}
        </button>
    );
};

export default Button;
Enter fullscreen mode Exit fullscreen mode

index.tsx 다음과 같이 작성

pages/index.tsx
import type { NextPage } from 'next';
import Button from '../components/Button';

const Home: NextPage = () => {
    return (
        <main className='w-[100vw] h-[100vh] flex justify-center items-center'>
            <div className='text-center'>
                <header className='mb-5'>
                    <h1 className='text-4xl font-bold text-pink-500'>Storybook</h1>
                    <h3 className='text-sm text-gray-400'>Next.JS, Tailwind CSS</h3>
                </header>
                <Button name={'Hello Tailwind CSS'} className={'bg-teal-400 text-white'} />
            </div>
        </main>
    );
};

export default Home;
Enter fullscreen mode Exit fullscreen mode

Storybook 관련 패키지 설치

Terminal
# Storybook Core
pnpm add -D @storybook/addon-actions @storybook/addon-essentials @storybook/addon-links @storybook/builder-webpack5 @storybook/manager-webpack5 @storybook/react

# Storybook Addons
pnpm add -D @storybook/preset-scss css-loader sass sass-loader style-loader postcss-loader

# For Next.JS Public Serve
pnpm add -D serve
Enter fullscreen mode Exit fullscreen mode

Setting up Storybook for Next.js

.storybook 폴더 생성 후 main.js, preview.js 생성

Note

  • 따로 dedicated한 폴더를 만들어 관리하지 않고 직접 컴포넌트 폴더에서 [filename].stories.ts 방식으로 관리할 예정이기에 다음과 같이 적용 범위 설정
stories: [
      '../components/**/*.stories.@(js|jsx|ts|tsx)',
      '../pages/**/*.stories.@(js|jsx|ts|tsx)',
  ],
  • 필수 요소를 제외한 addon 들은 Sass 관련, Next.Js 12 관련 addon
.storybook/main.js
module.exports = {
    stories: [
        '../components/**/*.stories.@(js|jsx|ts|tsx)',
        '../pages/**/*.stories.@(js|jsx|ts|tsx)',
    ],
    addons: [
        '@storybook/addon-links',
        '@storybook/addon-actions',
        '@storybook/addon-essentials',
        {
            name: '@storybook/preset-scss',
            options: {
                cssLoaderOptions: {
                    modules: { localIdentName: '[name]__[local]--[hash:base64:5]' },
                },
            },
        },
        'storybook-addon-next',
    ],
    framework: '@storybook/react',
    core: {
        builder: 'webpack5',
    },
};
Enter fullscreen mode Exit fullscreen mode
.storybook/preview.js
import '../styles/globals.css';

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

tsconfig.jsonbaseUrl 추가

tsconfig.json
{
    "compilerOptions": {
        ...
        "baseUrl": "."
        ...
    },
    ...
}
Enter fullscreen mode Exit fullscreen mode

package.jsonscript 추가

package.json
{
    ...
    "scripts": {
        ...
        "storybook:dev": "start-storybook -p 6006 -s public",
        "storybook:prod": "serve storybook-static",
        "storybook:build": "build-storybook -s public"
    },
    ...
}
Enter fullscreen mode Exit fullscreen mode

components 폴더에 Button.tsx 대응하는 Button.stories.tsx 생성

components/Button.stories.tsx
import Button from './Button';
import { ComponentMeta, ComponentStory } from '@storybook/react';

export default {
    title: 'Button',
    component: Button,
    argTypes: {
        name: {
            control: 'text',
        },
        className: {
            control: 'text',
        },
    },
} as ComponentMeta<typeof Button>;

const Template: ComponentStory<typeof Button> = (args) => <Button {...args} />;

export const Default = Template.bind({});

Default.args = {
    name: 'Hello Tailwind CSS',
    className: 'bg-teal-400 text-white',
};
Enter fullscreen mode Exit fullscreen mode

storybook 구동 후 Storybook Dashboard 확인

Terminal
pnpm storybook:dev
Enter fullscreen mode Exit fullscreen mode

Result

👉 CodeSandBox Sample Link

result
sb result


Conclusion

본 포스팅에서는 Next.Js 12 를 기준으로 Tailwind CSS 와 함께 StoryBook을 적용하는 방법을 알아보았다.
현재 기준 (2022/08) StoryBookNext.Js 12에 다소 안정화되지 않은 모습이 아쉽지만 Component 별로 UI Documentation 기능을 제공하는 StoryBook 자체의 장점만으로도 충분히 매력적인 선택지라고 생각한다.

StoryBook에는 위에 언급된 addon 외 에도 Tailwind CSS 다크 모드를 지원하는 Tailwind dark mode를 포함한 다양한 addon을 지원하고 있다.

하기 링크에서 더 많은 addon을 확인할 수 있다.
SB Addons Link: https://storybook.js.org/addons/

Sentry image

Hands-on debugging session: instrument, monitor, and fix

Join Lazar for a hands-on session where you’ll build it, break it, debug it, and fix it. You’ll set up Sentry, track errors, use Session Replay and Tracing, and leverage some good ol’ AI to find and fix issues fast.

RSVP here →

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay