JeongwooHam / Playground-Storybook

๐Ÿ›Playground for Exploring Storybook๐ŸŽ 

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

โœจ ์Šคํ† ๋ฆฌ๋ถ๊ณผ ๋””์ž์ธ ์‹œ์Šคํ…œ

๐Ÿ’„ ๋””์ž์ธ ์‹œ์Šคํ…œ์ด๋ž€?

  • ์ œํ’ˆ์˜ ๋””์ž์ธ์— ๋Œ€ํ•œ ๊ทœ์น™
    • ์„œ๋น„์Šค UI์— ์ผ๊ด€์„ฑ์„ ๋ถ€์—ฌํ•œ๋‹ค.
    • ์ฝ”๋“œ ๋ฐ ๋””์ž์ธ์˜ ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์œ ๋ฆฌํ•ด์ง„๋‹ค.
    • ๊ธฐํš์ž, ๋””์ž์ด๋„ˆ, ๊ฐœ๋ฐœ์ž ๊ฐ„ ์ปค๋ฎค๋‹ˆ์ผ€์ด์…˜ ๋น„์šฉ์„ ์ ˆ์•ฝํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์ œํ’ˆ์˜ ๋””์ž์ธ๊ณผ ๊ฐœ๋ฐœ์„ ์•ˆ๋‚ดํ•˜๋Š” ๊ด‘๋ฒ”์œ„ํ•œ ์ง€์นจ, ํ‘œ์ค€, ์‹ค์ฒœ ์‚ฌํ•ญ์„ ๋ชจ์•„๋‘” ๊ฒƒ

๐Ÿ“– ์Šคํ† ๋ฆฌ๋ถ์ด๋ž€?

  • UI ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋…๋ฆฝ์ ์œผ๋กœ ๊ฐœ๋ฐœํ•˜๊ณ  ๋ฌธ์„œํ™”ํ•  ์ˆ˜ ์žˆ๋Š” ํ™˜๊ฒฝ์„ ์ œ๊ณตํ•˜๋Š” ๋„๊ตฌ
  • UI ์ปดํฌ๋„ŒํŠธ์— story๋ฅผ ๋ถ€์—ฌํ•˜์—ฌ ๋ Œ๋”๋ง์„ ํ…Œ์ŠคํŠธํ•œ๋‹ค.
    • story: UI ์ปดํฌ๋„ŒํŠธ์˜ ์ƒํƒœ (์˜ˆ: disabled, enabled)
  • ๋””์ž์ธ ์‹œ์Šคํ…œ์„ ๊ตฌ์ถ•ํ•˜๊ณ  ์œ ์ง€ํ•˜๋Š” ๋ฐ ์žˆ์–ด ์ค‘์š”ํ•œ ์—ญํ• ์„ ํ•œ๋‹ค.
    • ๊ฐœ๋ฐœํ•œ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋””์ž์ธ ๊ฐ€์ด๋“œ์— ๋งž๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ์ปดํฌ๋„ŒํŠธ์˜ ๋ ˆ์ด์•„์›ƒ, ์ƒ‰์ƒ, ํƒ€์ดํฌ๊ทธ๋ž˜ํ”ผ ๋“ฑ ๋‹ค์–‘ํ•œ ๋””์ž์ธ ์š”์†Œ๋ฅผ ์ผ๊ด€์„ฑ ์žˆ๊ฒŒ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ๋””์ž์ธ ํ† ํฐ, ์ปดํฌ๋„ŒํŠธ, ํŒจํ„ด ๋“ฑ์„ ๋ฌธ์„œํ™”ํ•˜์—ฌ ํŒ€ ๋‚ด ๊ณต์œ  ๋ฐ ์žฌ์‚ฌ์šฉ์„ ํŽธ๋ฆฌํ•˜๊ฒŒ ํ•œ๋‹ค.

๐Ÿค” ์Šคํ† ๋ฆฌ๋ถ๊ณผ ๋””์ž์ธ ์‹œ์Šคํ…œ, ์™œ ํ•„์š”ํ• ๊นŒ?

  • ์ž‘์€ ์ปดํฌ๋„ŒํŠธ๋“ค์„ ์Œ“์•„์„œ ํฐ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค์—ˆ์„ ๋•Œ UI๊ฐ€ ์–ด๋–ป๊ฒŒ ๋ณด์ผ์ง€๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ํŒ€์›๋“ค ๊ฐ„์˜ ์ปค๋ฎค๋‹ˆ์ผ€์ด์…˜์„ ๊ฐ•ํ™”ํ•˜๋ฉฐ ๋””์ž์ธ๊ณผ ์ฝ”๋“œ๋ฅผ ์ผ๊ด€์„ฑ ์žˆ๊ฒŒ ์œ ์ง€ํ•˜๋„๋ก ๋„์™€์ค€๋‹ค.
  • ์‚ฌ์šฉ์ž๊ฐ€ ๋‚ด๊ฐ€ ๋งŒ๋“  ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋‚ด๊ฐ€ ์˜๋„ํ•œ ๋Œ€๋กœ ์ž˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š”์ง€๋ฅผ ๋ฏธ๋ฆฌ ๋ณด๊ณ  ์ ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ํšŒ์‚ฌ์—์„œ ์ƒˆ๋กœ์šด ํ”„๋กœ์ ํŠธ๋ฅผ ๋Ÿฐ์นญํ•˜๋”๋ผ๋„ ๋ฏธ๋ฆฌ ๋งŒ๋“ค์–ด๋‘” ๋””์ž์ธ ์‹œ์Šคํ…œ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ผ๊ด€๋œ UI ์‹œ์Šคํ…œ ํ†ตํ•ด Brand Identity๋ฅผ ๊ฐ€์ ธ๊ฐˆ ์ˆ˜ ์žˆ๋‹ค.

๐Ÿค– ํ”„๋กœ์ ํŠธ ๊ธฐ๋ณธ ์„ค์ •

  • ์šฐ์„  vite๋กœ ํ”„๋กœ์ ํŠธ๋ฅผ initํ•ฉ๋‹ˆ๋‹ค.
npm create vite@latest

๐Ÿ“– ์Šคํ† ๋ฆฌ๋ถ ํ™˜๊ฒฝ ์„ค์ •ํ•˜๊ธฐ

  1. ์Šคํ† ๋ฆฌ๋ถ์„ init ํ•œ๋‹ค.
npx storybook@latest init
  1. vite์™€ ๊ด€๋ จ๋œ ์ถ”๊ฐ€ ์„ค์ •์„ ์ง„ํ–‰ํ•œ๋‹ค.
npm install @storybook/builder-vite --save-dev
  1. ์Šคํ† ๋ฆฌ๋ถ ํด๋”์˜ main.ts ํŒŒ์ผ์— core ์„ค์ •์„ ์ถ”๊ฐ€ํ•œ๋‹ค.
// .storybook/main.ts
const config: StorybookConfig = {
  // ...
  core: {
    builder: "@storybook/builder-vite",
  },
};

๐ŸŒ€ Tailwind Css ํ™˜๊ฒฝ ์„ค์ •ํ•˜๊ธฐ

  1. Tailwind๋ฅผ ์„ค์น˜ํ•œ๋‹ค.
npm install -D tainwindcss postcss autoprefixer
npx tailwind init -p
  1. tailwind.config.js์—์„œ ๋ฆฌ์•กํŠธ ์ฝ”๋“œ ์Šคํƒ€์ผ์ด ๋ฐ˜์˜๋˜๋„๋ก ์„ค์ •ํ•ด์ค€๋‹ค.
// tailwind.config.js
export default {
  content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
};
  1. tailwind๋ฅผ import ํ•ด์ค€๋‹ค.
/* index.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
  1. ๋””์ž์ธ ์‹œ์Šคํ…œ์˜ ๊ธฐ๋ณธ ์„ค์ •์„ ๋ฐ˜์˜ํ•œ๋‹ค.
// tailwind.config.js
export default {
  // ...
  theme: {
    colors: {
      // ...
    },
  },
};
  • tailwind.config.js์— ์„ค์ •ํ•œ ๊ฒƒ๋ณด๋‹ค ์ธ๋ผ์ธ์œผ๋กœ ์ง์ ‘ ์„ค์ •ํ•ด์ฃผ๋Š” ๊ฒƒ์ด ์šฐ์„ ๋˜๋ฏ€๋กœ ์Šคํƒ€์ผ์ด ๊ณ ์ •๋  ์šฐ๋ ค๋Š” ํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค.

๐Ÿงจ ์ปดํฌ๋„ŒํŠธ ๊ฐœ๋ฐœ ์‹œ CLS(Cumulative Layout Shift) ๊ณ ๋ คํ•˜๊ธฐ

๐Ÿง CLS๋ž€?

  • ๋ฐฉ๋ฌธ์ž์—๊ฒŒ ์ฝ˜ํ…์ธ ๊ฐ€ ์–ผ๋งˆ๋‚˜ ๋ถˆ์•ˆ์ •ํ•˜๊ฒŒ ๋Š๊ปด์ง€๋Š”์ง€๋ฅผ ์ธก์ •ํ•˜๋Š” ์‚ฌ์šฉ์ž ๊ฒฝํ—˜ ์ธก์ • ํ•ญ๋ชฉ
    • ํŽ˜์ด์ง€์—์„œ ๊ฐ‘์ž๊ธฐ ๋ ˆ์ด์•„์›ƒ์˜ ๋ณ€๊ฒฝ์ด ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์€ ์‚ฌ์šฉ์ž์˜ ์ฃผ์˜๋ฅผ ์‚ฐ๋งŒํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ์ž˜๋ชป๋œ ํด๋ฆญ์„ ์œ ๋„ํ•  ๊ฒฝ์šฐ ํ”ผํ•ด๋ฅผ ์ดˆ๋ž˜ํ•˜๊ฑฐ๋‚˜ ๋ถˆ๋งŒ์กฑ์Šค๋Ÿฌ์šด UX๋ฅผ ์ œ๊ณตํ•˜๊ฒŒ ๋œ๋‹ค.
  • CLS ์ธก์ •์„ ํ†ตํ•ด ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ฐœ์ƒํ•˜๋Š” ๋ ˆ์ด์•„์›ƒ ์ด๋™ ๋นˆ๋„๋ฅผ ํŒŒ์•…ํ•˜์—ฌ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

CLS ์ ์ˆ˜

CLS ์ ์ˆ˜

  • ์ผ์ • ๊ธฐ๊ฐ„ ๋™์•ˆ ๋ ˆ์ด์•„์›ƒ ์ด๋™์ด ์—†๋Š” ์ƒํƒœ์—์„œ ๋ฐœ์ƒํ•˜๋Š” ์˜ˆ์ƒํ•˜์ง€ ์•Š์€ ๋ ˆ์ด์•„์›ƒ ์ด๋™์— ๋Œ€ํ•œ ๋ˆ„์ ๋œ ์ ์ˆ˜
  • ๋ทฐํฌํŠธ์—์„œ ์ด๋™ํ•œ ์ฝ˜ํ…์ธ ์˜ ์–‘๊ณผ ์˜ํ–ฅ์„ ๋ฐ›์€ ์š”์†Œ๊ฐ€ ์ด๋™ํ•œ ๊ฑฐ๋ฆฌ๋ฅผ ๊ณ ๋ คํ•˜์—ฌ ์‚ฐ์ •๋œ๋‹ค.
  • ์ข‹์€ ์‚ฌ์šฉ์ž ํ™˜๊ฒฝ ์ œ๊ณต์„ ์œ„ํ•ด์„œ๋Š” ์‚ฌ์ดํŠธ์˜ CLS ์ ์ˆ˜๊ฐ€ 0.1 ๋ฏธ๋งŒ์ด์–ด์•ผ ํ•œ๋‹ค.

โœจ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

  • errorMessage๋ฅผ absolute๋กœ ๊ณ ์ •ํ•ด์ค€๋‹ค.

  • ์ด๋•Œ, ์žฌ์‚ฌ์šฉ์„ฑ์„ ์œ„ํ•ด errorMessage ์ž์ฒด์— position์„ ๋ถ€์—ฌํ•˜์ง€ ์•Š์œผ๋ ค div ํƒœ๊ทธ๋ฅผ ๊ฒ‰์— ์ถ”๊ฐ€ํ•  ๊ฒฝ์šฐ ๋ถˆํ•„์š”ํ•œ ํƒœ๊ทธ๊ฐ€ ํ•˜๋‚˜ ๋” ์ถ”๊ฐ€๋œ๋‹ค.

    • ์ด๋Š” tree์˜ ๋ชจ๋“  node๋ฅผ ํ›‘๋Š” React์˜ Reconciliation ๊ณผ์ •์— ์†Œ์š”๋˜๋Š” ์‹œ๊ฐ„์„ ๋” ๊ธธ์–ด์ง€๊ฒŒ ํ•˜๋ฏ€๋กœ ๋ Œ๋”๋ง ์‹œ๊ฐ„์ด ์˜ค๋ž˜ ๊ฑธ๋ฆด ์ˆ˜ ์žˆ๋‹ค.
  • CSS์˜ ์ž์‹ ์†์„ฑ์„ ์‚ฌ์šฉํ•˜์ž!

    /*์ผ๋ฐ˜ CSS ์Šคํƒ€์ผ*/
    .relative {
      > p {
        position: absolute;
      }
    }
    
    /*tailwindCSS ์Šคํƒ€์ผ*/
    @layer components {
      .relative > p {
        @apply absolute;
      }
    }
    
    /*ํŠน์ • ์ปดํฌ๋„ŒํŠธ์—๋งŒ ์ ์šฉ๋˜๊ธธ ์›ํ•˜๋Š” ๊ฒฝ์šฐ*/
    @layer components {
      .text-field > p {
        @apply absolute;
      }
    }

๐Ÿ‘ท Chromatic๊ณผ Github Actions๋ฅผ ํ™œ์šฉํ•œ CI/CD

๐Ÿšจ Chromatic ์ด์ „์˜ ๋ฌธ์ œ์ 

  • ์ฝ”๋“œ๋งŒ ๋ณด๊ณ  ์ปดํฌ๋„ŒํŠธ์˜ ํ˜•ํƒœ๋ฅผ ์ƒ์ƒํ•˜๊ธฐ ์–ด๋ ต๋‹ค.
  • PR์„ ์ž‘์„ฑํ•  ๋•Œ ์„ธ๋ถ€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ชจ๋‘ ์ƒ์„ธํ•˜๊ฒŒ ์ž‘์„ฑํ•˜๊ธฐ ์–ด๋ ต๋‹ค.
  • ์ปดํฌ๋„ŒํŠธ์˜ UI์™€ ํ…Œ์ŠคํŠธ๋ฅผ ์ง์ ‘ ์‹คํ–‰ํ•˜๊ธฐ ๋ฒˆ๊ฑฐ๋กญ๋‹ค.

๐Ÿง Chromatic์ด๋ž€?

  • Chromatic์ด๋ž€ ์Šคํ† ๋ฆฌ๋ถ์—์„œ ๋งŒ๋“  ๋ฌด๋ฃŒ ๋ฐฐํฌ ์„œ๋น„์Šค๋กœ, ์Šคํ† ๋ฆฌ๋ถ์„ ๊ฐ„๋‹จํ•˜๊ฒŒ ๋ฐฐํฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค.
  • ์ปดํฌ๋„ŒํŠธ ๋ฏธ๋ฆฌ ๋ณด๊ธฐ, ๋นŒ๋“œ ๊ณผ์ • ๋“ฑ์ด ์Šคํ† ๋ฆฌ๋ถ์— ์ตœ์ ํ™”๋˜์–ด ๋ณด์—ฌ์ง„๋‹ค.
  • verify changes๋ฅผ ํ†ตํ•ด ์ปดํฌ๋„ŒํŠธ์˜ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
  • Chromatic ํŽ˜์ด์ง€์—์„œ ๋˜๋Š” PR ์ž์ฒด์—์„œ ์ปดํฌ๋„ŒํŠธ์— ๋Œ€ํ•œ ๋ฆฌ๋ทฐ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.

Chromatic ์„ค์น˜ํ•˜๊ธฐ

npm install --save-dev chromatic

Chromatic์— ์Šคํ† ๋ฆฌ๋ถ ๋ฐฐํฌํ•˜๊ธฐ

npx chromatic --project-token <your-project-token>

๐Ÿ”€ Github Actions๋ฅผ ํ™œ์šฉํ•œ CI/CD

  • ์ด ๊ณผ์ •์ด ์—†๋‹ค๋ฉด ์ปดํฌ๋„ŒํŠธ์˜ UI์™€ ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•ด์„œ๋Š” ์ฝ”๋“œ๋ฅผ Pull ๋ฐ›๊ณ  ์Šคํ† ๋ฆฌ๋ถ์„ ๋กœ์ปฌ์—์„œ ์‹คํ–‰ํ•˜์—ฌ ํ™•์ธํ•ด์•ผ ํ•œ๋‹ค.

Chromatic ํ† ํฐ ์„ค์ •ํ•˜๊ธฐ

  • ํ† ํฐ์€ Chromatic์˜ Manage ํƒญ > Configure ํƒญ > Setup Chromatic with this project token์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

Github Actions workflow ํŒŒ์ผ ์ƒ์„ฑํ•˜๊ธฐ

  • .github/workflows/chromatic.yml์— ์•„๋ž˜์™€ ๊ฐ™์ด ์ž‘์„ฑํ•ด์ฃผ์—ˆ๋‹ค.
  • ํด๋”๋ช…๋งŒ ๋™์ผํ•˜๋‹ค๋ฉด ํŒŒ์ผ๋ช…์€ ์ž„์˜๋กœ ์„ค์ • ๊ฐ€๋Šฅํ•˜๋‹ค.
# .github/workflows/chromatic.yml

name: "Chromatic"

# push ์ด๋ฒคํŠธ ๋ฐœ์ƒ ์‹œ
on: push

jobs:
  chromatic:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Install dependencies
        # ์‚ฌ์šฉํ•˜๋Š” package manager์— ๋งž์ถฐ์„œ ์„ค์ •ํ•˜๊ธฐ
        run: npm ci

      - name: Run Chromatic
        uses: chromaui/action@latest
        with:
          # Github Secret์— ๋„ฃ์€ key ๊ฐ’๊ณผ ๋™์ผํ•ด์•ผ ํ•œ๋‹ค.
          projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
  • ์ •์ƒ์ ์œผ๋กœ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

๐ŸŒ ์Šคํ† ๋ฆฌ๋ถ์„ ํ™œ์šฉํ•œ ์ ‘๊ทผ์„ฑ ํ…Œ์ŠคํŠธ

๐Ÿง ์›น ์ ‘๊ทผ์„ฑ์ด๋ž€?

  • ๋””์ง€ํ„ธ ๋ถ„์•ผ์—์„œ ์œ ๋‹ˆ๋ฒ„์„ค ๋””์ž์ธ(๋‚˜์ด๋‚˜ ๋Šฅ๋ ฅ์— ์ƒ๊ด€ ์—†์ด ์ œํ’ˆ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.)์˜ ๋ฉ”์‹œ์ง€๋ฅผ ๋‚ดํฌํ•˜๋Š” ๊ฐœ๋…
  • ์›น์‚ฌ์ดํŠธ, ๋„๊ตฌ, ๊ธฐ์ˆ ์„ ์žฅ์• ๋ฅผ ๊ฐ€์ง„ ์‚ฌ์šฉ์ž๋“ค๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“œ๋Š” ๊ฒƒ
    • ์—ฌ๊ธฐ์„œ์˜ ์žฅ์• ๋Š” ์‹ ์ฒด์ , ์ธ์ง€์  ์žฅ์•  ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์›น์— ์ ‘๊ทผํ•˜๋Š” ๋ฐ ์˜ํ–ฅ์„ ์ฃผ๋Š” ์ผ์‹œ์ ์ธ ์žฅ์•  ์ƒํƒœ, ํ™˜๊ฒฝ์  ์ œ์•ฝ์„ ํฌํ•จํ•œ๋‹ค.

The power of the Web is in its universality

  • ์›น ์ ‘๊ทผ์„ฑ์„ ์ค€์ˆ˜ํ•˜๋Š” ๊ฒƒ์€ ์›น์˜ ๊ธฐ๋ณธ ์ •์‹ ์„ ์ง€ํ‚ค๋Š” ๊ฒƒ์ด๋ฉฐ, ์žฅ์• ์ธ์ฐจ๋ณ„๊ธˆ์ง€๋ฒ•๊ณผ ์ง€๋Šฅ ์ •๋ณดํ™” ๊ธฐ๋ณธ๋ฒ•์— ์˜ํ•œ ๋ฒ•์ • ์˜๋ฌด์‚ฌํ•ญ์ด๊ธฐ๋„ ํ•˜๋‹ค.
  • ์›น ์ ‘๊ทผ์„ฑ์„ ์ค€์ˆ˜ํ•  ๊ฒฝ์šฐ ์ƒ‰์•ฝ, ์ฒญ๊ฐ์žฅ์• , ์šด๋™์žฅ์•  ๋“ฑ ์‹ ์ฒด์  ๋ถˆํŽธํ•จ์„ ๊ฐ€์ง„ ์‚ฌ๋žŒ๋“ค๋„ ์›น์‚ฌ์ดํŠธ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ํŒ”์ด ๋ถ€๋Ÿฌ์ง€๊ฑฐ๋‚˜ ์•ˆ๊ฒฝ์„ ์žƒ์–ด๋ฒ„๋ ค ์ผ์‹œ์  ๋ถˆํŽธํ•จ์„ ๊ฒช๊ฑฐ๋‚˜ ๋ฐ์€ ํ–‡๋น›์ด๋‚˜ ์†Œ๋ฆฌ๋ฅผ ๋“ฃ๊ธฐ ํž˜๋“  ์ƒํ™ฉ์— ์ฒ˜ํ•˜๋Š” ๋“ฑ ํ™˜๊ฒฝ์  ์ œ์•ฝ์„ ๋ฐ›๋Š” ์‚ฌ๋žŒ, ์ธ์ง€์ /์‹ ์ฒด์  ๋Šฅ๋ ฅ์˜ ์ €ํ•˜๋ฅผ ๊ฒช๋Š” ๋…ธ์ธ ๋“ฑ ์žฅ์• ๋ฅผ ๊ฐ–์ง€ ์•Š๋Š” ์‚ฌ๋žŒ์—๊ฒŒ๋„ ๋„์›€์„ ์ค„ ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ‘“Test Runner๋ฅผ ํ™œ์šฉํ•œ ์›น ์ ‘๊ทผ์„ฑ ํ…Œ์ŠคํŠธ

a11y addon ์„ค์น˜ํ•˜๊ธฐ

npm install @storybook/addon-a11y --save-dev

.storybook/main.ts์— addon ์ถ”๊ฐ€ํ•˜๊ธฐ

addons: [
    // Other Storybook addons
    '@storybook/addon-a11y', //๐Ÿ‘ˆ The a11y addon goes here
  ],

Test Runner๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์›น ์ ‘๊ทผ์„ฑ ํ…Œ์ŠคํŠธ ์‹คํ–‰ํ•˜๊ธฐ

  • playwright๋ฅผ ์„ค์น˜ํ•ด์ค€๋‹ค.
npx playwright install
  • test runner addon์„ ์„ค์น˜ํ•ด์ค€๋‹ค.
npm install @storybook/test-runner --save-dev
  • package.json์— ์•„๋ž˜์™€ ๊ฐ™์ด scripts๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.
{
  "scripts": {
    "test-storybook": "test-storybook"
  }
}
  • test-runner์— ์›น ์ ‘๊ทผ์„ฑ ํ…Œ์ŠคํŠธ๋ฅผ ์„ค์ •ํ•ด์ค€๋‹ค.
npm install axe-playwright --save-dev
import type { TestRunnerConfig } from "@storybook/test-runner";
import { injectAxe, checkA11y } from "axe-playwright";

const config: TestRunnerConfig = {
  async preVisit(page) {
    await injectAxe(page);
  },
  async postVisit(page) {
    await checkA11y(page, "#storybook-root", {
      detailedReport: true,
      detailedReportOptions: {
        html: true,
      },
    });
  },
};

export default config;
  • ์ œ๋Œ€๋กœ ์ ์šฉ๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

image

Github Actions๋กœ ์ ‘๊ทผ์„ฑ ํ…Œ์ŠคํŠธ ์ž๋™ํ™”ํ•˜๊ธฐ

  • ์•„๋ž˜์™€ ๊ฐ™์ด workflow๋ฅผ ์ถ”๊ฐ€ํ•ด์ค€๋‹ค.
storybook-accessibility-test:
  timeout-minutes: 60
  runs-on: ubuntu-latest
  steps:
    - uses: actions/checkout@v3
    - uses: actions/setup-node@v3
      with:
        node-version-file: ".nvmrc"
    - name: Install dependencies
      run: yarn
    - name: Install Playwright
      run: npx playwright install --with-deps
    - name: Build Storybook
      run: yarn build-storybook --quiet
    - name: Serve Storybook and run tests
      run: |
        npx concurrently -k -s first -n "SB,TEST" -c "magenta,blue" \
          "npx http-server storybook-static --port 6006 --silent" \
          "npx wait-on tcp:127.0.0.1:6006 && yarn test-storybook"
  • "npx wait-on tcp:127.0.0.1:6006 && yarn test-storybook" ๋ถ€๋ถ„์—์„œ IP ์ฃผ์†Œ์ธ 127.0.0.1์„ ๋ช…์‹œํ•ด์ฃผ์ง€ ์•Š์œผ๋ฉด CI ๊ณผ์ •์—์„œ Storybook Server ๋ถ€๋ถ„์ด ์ œ๋Œ€๋กœ ๊ตฌ๋™๋˜์ง€ ์•Š๊ณ  ๋ฌดํ•œํ•˜๊ฒŒ ๋กœ๋”ฉ๋˜๋Š” timeout ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋ฏ€๋กœ ์ฃผ์˜ํ•˜์ž!

๐Ÿ‘ฅ ์Šคํ† ๋ฆฌ๋ถ์„ ์‚ฌ์šฉํ•œ ์‚ฌ์šฉ์ž ์ƒํ˜ธ์ž‘์šฉ ํ…Œ์ŠคํŠธ

  • ํŽ˜์ด์ง€์™€ ๊ฐ™์ด ๋” ๋ณต์žกํ•œ UI๋ฅผ ๊ตฌ์ถ•ํ•˜๋ฉด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ  ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๋“ฑ UI ๋ Œ๋”๋ง ์ด์ƒ์˜ ์—ญํ• ์„ ๋งก๊ฒŒ ๋œ๋‹ค.
  • Jest๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์œ ๋‹› ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ, ์Šคํ† ๋ฆฌ๋ถ์„ ์‚ฌ์šฉํ•ด์„œ๋„ ์ปดํฌ๋„ŒํŠธ ๋‹จ์œ„์˜ ํ…Œ์ŠคํŠธ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.
  • API ํ˜ธ์ถœ ๋กœ์ง์„ Cypress ๋“ฑ์„ ํ™œ์šฉํ•œ e2e ํ…Œ์ŠคํŠธ์—์„œ ์ง„ํ–‰ํ•œ๋‹ค๋ฉด, ์ปดํฌ๋„ŒํŠธ์— ๋Œ€ํ•œ ํ…Œ์ŠคํŠธ๋Š” ์Šคํ† ๋ฆฌ๋ถ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ง„ํ–‰ํ•˜๋Š” ๊ฒƒ๋„ ํŽธ๋ฆฌํ•ด ๋ณด์ธ๋‹ค.

Interaction Test ๊ด€๋ จ addon ์ถ”๊ฐ€ํ•˜๊ธฐ

npm install @storybook/test @storybook/addon-interactions --save-dev

.storybook/main.ts์— addon ์„ค์ • ์ถ”๊ฐ€ํ•˜๊ธฐ

addons: [
    // Other Storybook addons
    '@storybook/addon-interactions',
  ],
  • ๋‹ค์Œ ํŒŒ์ผ๊ณผ ๊ฐ™์ด ํ…Œ์ŠคํŠธ ๋กœ์ง์„ ์ž‘์„ฑํ•ด๋ณด๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ํ…Œ์ŠคํŠธ๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ์ ์šฉ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

image

About

๐Ÿ›Playground for Exploring Storybook๐ŸŽ 


Languages

Language:TypeScript 88.2%Language:JavaScript 6.8%Language:CSS 3.6%Language:HTML 1.4%