본문 바로가기
목차
[노트장] 적으며 정리해 보는 이론/Style & StoryBook

[Storybook] React(Vite) + tailwind + ui shadcn + storybook + typescript 연결하기

by 졸린부엉이 2024. 7. 10.

최근에 알게 된 ui shadcn을 사용해 보았는데, 너무 좋아서 계속해서 사용하고 있다.
ui를 작은 모듈로 쪼개서 만들어놓은 ui라이브러리이다.
components/ui에 자동으로 만들어져서 들어가진다.

이미지를 보면 button, input처럼 작은 atomic 단위로 쪼개져있는 것을 볼 수가 있다. 이거 정말 편하다.



페이지에 여러 디자인 컴포넌트를 만들어 놓고 협업하는 과정에서 다른 팀원에게 디자인 변경 방식을 계속해서 설명하는 것, 디자인을 확인하기 위해 매번 찾아것 등 비효율적이기에 누구나 보고싶을때 편하게 볼수 있는 ui컴포넌트 개발을 위한 도구인 storybook 라이브러리 를 사용해보려고 한다

 

 


설치 방법은 여기 사이트를 참고하였다! 

[참고자료]
Part 4. Turborepo + Shadcn-ui + Storybook + Dark mode

Part 3. Turborepo에 TailiwindCSS + Shadcn-ui 설정하기

 

 

◼ 설치 전 버전

// package.json
{
  "name": "react-global-nomad",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "tsc -b && vite build",
    "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
    "preview": "vite preview"
  },
  "dependencies": {
    "axios": "^1.7.2",
    "react": "^18.3.1",
    "react-dom": "^18.3.1",
    "react-router-dom": "^6.24.1",
  },
  "devDependencies": {
    "@types/react": "^18.3.3",
    "@types/react-dom": "^18.3.0",
    "@typescript-eslint/eslint-plugin": "^7.13.1",
    "@typescript-eslint/parser": "^7.13.1",
    "@vitejs/plugin-react": "^4.3.1",
    "eslint": "^8.57.0",
    "eslint-plugin-react-hooks": "^4.6.2",
    "eslint-plugin-react-refresh": "^0.4.7",
    "typescript": "^5.2.2",
    "vite": "^5.3.1"
  }
}



 

 

 

 

◼  Vite / tailwind / shadcn/ui / storybook 설치

ui shadcn 사용할 때, next.js 와 vite만 사용해 봐서 다른 것은 알 수 없지만,
라이브러리 사이트가 친절하다 느꼈다.

next.js 와 vite(react)의 기본 설치가 적혀 있어서 바로 같이 설치가 가능하다.

 

 

- Vite

1. vite 설치
npm create vite@latest

2. tailwind, postcss, autoprefixer
npm install -D tailwindcss postcss autoprefixer
- postcss:CSS 후처리기, 
- autoprefixer:postcss의 플러그인(-webkit-, -moz- 등의 접두사를 자동으로 추가 설치)

3. Tailwind CSS와 PostCSS의 설정 파일을 초기화
npx tailwindcss init -p

4. ui 라이브러리 설치
npx shadcn-ui@latest init

5. reat, react-dom 설치 (있으면 안해도 ..)
npm install react react-dom

6. typescript 설치(TS사용하실 생각이시면,)
npm install --save-dev vite typescript

7.스토리북 & 관련 라이브러리 설치
npx storybook@latest init
npm install @storybook/react-webpack5 @storybook/react @storybook/addon-links @storybook/addon-essentials @storybook/addon-interactions

8. vite 플러그인 설치
npm install --save-dev vite-tsconfig-paths @vitejs/plugin-react

9.text용 버튼으로 ui shadcn설치
npx shadcn-ui@latest add button
[+ 자세히 보기]
https://ui.shadcn.com/docs/installation

 

 

 

 

 

 

storybook까지 설치를 하고 나면 자동으로  storybook이 실행된다.

안된다면 아래 코드로 실행하면 된다.

npm run storybook

 

 

 

 

 

 

 

 

◼  설정하기

설치하고 설정하는 파일이 있다.

몇가지 설치 후 생긴 config 들.

 

 

 

 

설치가 끝난 후의 설정은 상단에 참고로 적어 놓았지만. 또 한 번 적어본다.
나는 간단히 설치 코드 부분만 적을 것이라, 자세한 사항은 참고 자료를 봐야 한다.

[참고자료]
Part 4. Turborepo + Shadcn-ui + Storybook + Dark mode

Part 3. Turborepo에 TailiwindCSS + Shadcn-ui 설정하기

 

  • vite.config.ts
  • tsconfig.json
  • tailwind.config.ts
  • .storybook/preview.ts
  • scr/stories/Button.stories.ts: 사용하는 파일

 

 

vite.config.ts 설정

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import tsconfigPaths from 'vite-tsconfig-paths'; // +추가 라이브러리 설치

export default defineConfig({
  plugins: [react(), tsconfigPaths()],
});

 

 

 

tsconfig.json 설정

{
  "compilerOptions": {
	...
    "jsx": "react-jsx",
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"],
    }
  },
  "include": [  // + 추가 storybook
  "**/*.ts",
  "**/*.tsx",
  ".storybook/**/*.ts", // + 추가
  ".storybook/**/*.tsx" // + 추가
],
"exclude": ["node_modules"]
}

 

 

 

tailwind.config.js 설정

/** @type {import('tailwindcss').Config} */
module.exports = {
  darkMode: ['selector'],
  content: [
  './pages/**/*.{ts,tsx}', 
  './components/**/*.{ts,tsx}', 
  './app/**/*.{ts,tsx}',
  './src/**/*.{ts,tsx}', 
  './.storybook/**/*.{js,jsx,ts,tsx}' // + 추가
  ],
  prefix: '',
...
}

 

 

 

.storybook/preview.ts설정

import type { Preview } from "@storybook/react";
import '../src/styles/globals.css'; // + 추가 : tailwind globals스타일을 import 해줍니다.

const preview: Preview = {
  parameters: {
    controls: {
      matchers: {
        color: /(background|color)$/i,
        date: /Date$/i,
      },
    },
  },
};

export default preview;

 

 

 

src/stories/Button.stories.ts 에 ui  shadcn Button 기본값 연결하기 방법

첨부자료에서 가져온 자료입니다.

import { Button } from '@/components/ui/button';
import type { Meta, StoryObj } from "@storybook/react";

// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction
const meta: Meta<typeof Button> = {
  title: "Example/Button",
  component: Button,
  tags: ["autodocs"],
  argTypes: {
    children: { control: "text", defaultValue: "Button" },
    variant: {
      control: "select",
      options: [
        "primary",
        "destructive",
        "outline",
        "secondary",
        "ghost",
        "link",
      ],
    },
    size: { control: "radio", options: ["sm", "md", "lg", "icon"] },
    asChild: { control: "boolean" },
    onClick: { action: "clicked", type: "function" },
  },
};

export default meta;
type Story = StoryObj<typeof Button>;

// More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args
export const Default: Story = {
  args: {
    variant: "default",
    children: "Button",
  },
};

export const Destructive: Story = {
  args: {
    variant: "destructive",
    children: "Destructive Button",
  },
};

export const Outline: Story = {
  args: {
    variant: "outline",
    children: "Outline Button",
  },
};

export const Secondary: Story = {
  args: {
    variant: "secondary",
    children: "Secondary Button",
  },
};

export const Ghost: Story = {
  args: {
    variant: "ghost",
    children: "Ghost Button",
  },
};

export const Link: Story = {
  args: {
    variant: "link",
    children: "Link Button",
  },
};



 

 

 


 

 

 



 

 

◼  기타 파일

 

.storybook/main.ts설정

// 기본 설정
import type { StorybookConfig } from '@storybook/react-vite';

const config: StorybookConfig = {
  stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
  addons: ['@storybook/addon-onboarding', '@storybook/addon-links', '@storybook/addon-essentials', '@chromatic-com/storybook', '@storybook/addon-interactions'],
  framework: {
    name: '@storybook/react-vite',
    options: {},
  },
};
export default config;

 

 

 

postcss.config.json 설정

// 기본설정
export default {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  },
}

 

 

package.json 설정

{
  "name": "react-global-nomad",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "tsc -b && vite build",
    "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
    "preview": "vite preview",
    "sb": "storybook dev -p 6006", // storybook
    "build-storybook": "storybook build",
    "storybook": "storybook dev -p 6006"
  },
  "overrides": { // @storybook\react-webpack5\preset error시에 추가
    "webpack": "^5.52.0"
  },
  "dependencies": {
    "@radix-ui/react-slot": "^1.1.0",
    "@tanstack/react-query": "^5.50.1",
    "@tanstack/react-query-devtools": "^5.50.1",
    "axios": "^1.7.2",
    "class-variance-authority": "^0.7.0",
    "clsx": "^2.1.1",
    "lucide-react": "^0.407.0",
    "react": "^18.3.1",
    "react-dom": "^18.3.1",
    "react-loading-skeleton": "^3.4.0",
    "react-router-dom": "^6.24.1",
    "sonner": "^1.5.0",
    "tailwind-merge": "^2.4.0",
    "tailwindcss-animate": "^1.0.7"
  },
  "devDependencies": {
    "@chromatic-com/storybook": "^1.6.1",
    "@storybook/addon-actions": "^8.1.11",
    "@storybook/addon-essentials": "^8.1.11",
    "@storybook/addon-interactions": "^8.1.11",
    "@storybook/addon-links": "^8.1.11",
    "@storybook/addon-onboarding": "^8.1.11",
    "@storybook/blocks": "^8.1.11",
    "@storybook/react": "^8.1.11",
    "@storybook/react-vite": "^8.1.11",
    "@storybook/test": "^8.1.11",
    "@types/react": "^18.3.3",
    "@types/react-dom": "^18.3.0",
    "@typescript-eslint/eslint-plugin": "^7.13.1",
    "@typescript-eslint/parser": "^7.13.1",
    "@vitejs/plugin-react": "^4.3.1",
    "autoprefixer": "^10.4.19",
    "eslint": "^8.57.0",
    "eslint-plugin-react-hooks": "^4.6.2",
    "eslint-plugin-react-refresh": "^0.4.7",
    "eslint-plugin-storybook": "^0.8.0",
    "postcss": "^8.4.39",
    "sass": "^1.77.6",
    "storybook": "^8.1.11",
    "tailwindcss": "^3.4.4",
    "typescript": "^5.2.2",
    "vite": "^5.3.1",
    "vite-tsconfig-paths": "^4.3.2"
  }
}

 

 

이런 에러가 난다면. 
아래코드를 추가하면 된다.

  "overrides": {
    "webpack": "^5.52.0"
  }

[참고자료] https://github.com/storybookjs/storybook/issues/18571