Vue3 × Vite環境で始めるStorybook超入門

## Storybookとは何か？

フロントエンド開発では、デザイン通りにコンポーネントを実装し、それが意図した通りに動作するかどうかを何度も確認しながら開発を進めます。
しかし、実際の開発現場では、次のような課題に直面することが少なくありません。

- 全画面を起動して動作確認するのが面倒
- コンポーネント単位で確認しにくく、バグの発見が遅れる
- デザイナーやQAメンバーとの連携に手間がかかる


このような課題を解決するために登場したのが Storybook です。

Storybookは、コンポーネント単位で開発・テスト・レビューができるオープンソースツールです。
Vue、React、Angularなど様々なフレームワークに対応しており、特にコンポーネント指向開発を行うプロジェクトでは、開発効率と品質を向上させる強力な武器になります。

具体的には、次のようなことができるようになります。

- コンポーネント単位で画面をプレビューできる
- Props（引数）を動的に変更し、動作をリアルタイムで確認できる
- クリックイベントなどをシミュレートして確認できる
- デザイナーやQAメンバーと画面イメージを共有できる
- 自動生成されたドキュメントを通じて、コンポーネントの使い方を周知できる

つまり、Storybookを導入することで、
 **「コンポーネントの開発 → 動作確認 → レビュー」** のサイクルが非常にスムーズになり、
開発とレビューの手戻りも大幅に減らすことができます。

## Storybookの基本構成

Storybookを使い始めるには、まずプロジェクトにインストールし、必要な初期設定を行う必要があります。  
ここでは、Vue3＋Viteプロジェクトを前提に、基本的な導入手順とファイル構成を紹介します。

### 2.1 Storybookのインストール

ターミナルを開き、プロジェクトディレクトリに移動した上で、次のコマンドを実行します。
```
npx storybook init
## npmパッケージをインストールせずにコマンドをその場で実行できるツール
です。
```

このコマンドを実行すると、プロジェクトに必要なStorybook関連ファイルが自動生成されます。  
※Vue3+Viteプロジェクトの場合、後述する追加設定（Vite対応）が必要になります。

インストールが成功すると、次のようなメッセージが表示されます。
```yaml
Storybook installation complete!
You can now run 'npm run storybook' to start Storybook.
```

その後、次のコマンドでStorybookを起動できます。

```
npm run storybook
```

ブラウザが自動的に立ち上がり、ローカルサーバー上でStorybookのUIが表示されます。

### 2.2 ファイル・フォルダ構成

Storybookをインストールすると、プロジェクトにいくつかの設定ファイルとフォルダが追加されます。  
代表的なものを見てみましょう。

| ファイル／フォルダ             | 説明 |
|:-------------------------------|:-----|
| `.storybook/`                  | Storybookの設定ファイルをまとめたフォルダ |
| `.storybook/main.js`            | Storybookのビルド設定・アドオン設定を行うファイル |
| `.storybook/preview.js`         | 全体に適用するグローバル設定（スタイル適用など）を記述するファイル |
| `src/stories/`                  | サンプルのコンポーネントとStoryファイルが配置されるフォルダ |

このうち特に重要なのが、  
**`.storybook/main.js`** と **`.storybook/preview.js`** の2つです。  
これらを適切にカスタマイズすることで、プロジェクトに合わせたStorybook環境を作ることができます。

### 2.3 `stories`ファイルとは？

Storybookでは、 **「コンポーネントを動作確認するためのシナリオ」** を記述するファイルを  
**`stories`** ファイルと呼びます。

例えば、シンプルなボタンコンポーネントに対して、  
「通常状態」「ホバー状態」「無効化状態」といった複数パターンを一括で管理・確認できるのが特徴です。

`stories`ファイルの特徴は以下の通りです。

- `.stories.js` または `.stories.ts` という拡張子で作成する
- コンポーネントをインポートし、表示させたい状態（ストーリー）を定義する
- 1つのコンポーネントに対して、複数のストーリー（パターン）を記述できる

これにより、**さまざまな状態のコンポーネントを簡単に切り替えて確認**できるようになります。

## Vite環境での注意点

StorybookはもともとWebpackをベースに動作していましたが、  
現在では**Vite**のようなモダンなビルドツールにも対応しています。  
ただし、Vite環境でStorybookを使う場合はいくつか注意点があります。  
この章では、Vite対応のために必要な設定と、気をつけるべきポイントを紹介します。

### 3.1 Vite用Storybookフレームワークの導入

通常の `npx storybook init` では、Webpackベースで初期化されます。  
Vite環境では、Storybookのフレームワークとして`@storybook/vue3-vite`を使う必要があります。

#### インストール手順

以下のコマンドで必要なパッケージを追加します。

```
npm install --save-dev @storybook/vue3-vite
```

#### 設定変更

`.storybook/main.js` を次のように修正します。

```javascript
/** @type { import('@storybook/vue3-vite').StorybookConfig } */
export default {
  framework: { name: '@storybook/vue3-vite', options: {} },
  stories: ['../src/**/*.stories.@(js|ts)'],
  addons: ['@storybook/addon-controls', '@storybook/addon-actions', '@storybook/addon-docs'],
};
```

ここで、frameworkに **@storybook/vue3-vite** を指定することがポイントです。

### 3.2 よくある問題と注意点

ViteでStorybookを動かすときには、いくつかハマりやすいポイントがあります。

#### モジュール解決エラー（Alias設定）

Viteではvite.config.tsやvite.config.jsにエイリアス（Alias）設定をしていることが多いですが、
Storybook側にはその設定が反映されません。

この場合、Storybook専用のVite設定ファイル（例えばviteFinal）を使って、エイリアスを手動で設定する必要があります。

```javascript
// .storybook/main.js
export default {
  // ...
  viteFinal: (config) => {
    config.resolve.alias = {
      ...config.resolve.alias,
      '@': path.resolve(__dirname, '../src'),
    };
    return config;
  },
};
```

これにより、通常の開発環境と同じエイリアスをStorybookでも使えるようになります。

#### 静的アセット・スタイルの取り扱い

Vite環境では、CSSや画像などの静的ファイルの読み込み方法が本番環境と若干異なることがあります。
たとえば、public/フォルダのパス指定に注意が必要です。

相対パス（/images/sample.png）で参照できるか確認する

Vite特有のインポート方法（例：import sample from '@/assets/sample.png'）をStorybookにも適用する


このあたりを見落とすと、「本番はOKだけどStorybookでは表示されない」という問題が起きやすいので注意しましょう。

### 3.3 まとめ

Vite環境では、必ず@storybook/vue3-viteを導入する

エイリアスやアセットの取り扱いに注意し、Storybook設定を適切にカスタマイズする


Vite対応を正しく行えば、Storybookも本番アプリと同じような動作環境で動かすことができます。
次章では、実際にStoryを書いてコンポーネントをStorybookに登録する方法を見ていきましょう。

## 最初のStoryを書いてみる

ここからは、実際にコンポーネントのStoryを作成して、Storybookに表示する方法を解説します。  
今回はシンプルなボタンコンポーネントを例に、基本的な流れを押さえていきます。

### 4.1 ボタンコンポーネントの作成

まずは、`src/components`フォルダに、シンプルなVue3コンポーネントを作成します。

```vue
<!-- src/components/MyButton.vue -->
<template>
  <button :class="type" @click="onClick">{{ label }}</button>
</template>

<script setup>
defineProps({
  label: {
    type: String,
    required: true,
  },
  type: {
    type: String,
    default: 'primary',
  },
});

const emit = defineEmits(['click']);
const onClick = () => emit('click');
</script>

<style scoped>
.primary {
  background-color: #007bff;
  color: white;
  padding: 8px 16px;
  border: none;
  border-radius: 4px;
}

.secondary {
  background-color: #6c757d;
  color: white;
  padding: 8px 16px;
  border: none;
  border-radius: 4px;
}
</style>
```

このコンポーネントは、  
- `label`という文字列を受け取り、ボタンに表示
- `type`によってスタイル（primary/secondary）を切り替え
- クリックイベントを親に通知  
というシンプルなものです。

### 4.2 Storyファイルの作成

次に、先ほど作成したボタンコンポーネントに対応するStoryファイルを作成します。  
Storyファイルは通常、コンポーネントと同じディレクトリ、または`src/stories`フォルダに作成します。

```
// src/stories/MyButton.stories.js
import MyButton from '../components/MyButton.vue';

export default {
  title: 'Example/MyButton',
  component: MyButton,
  argTypes: {
    label: { control: 'text' },
    type: { 
      control: { type: 'select' },
      options: ['primary', 'secondary'],
    },
    onClick: { action: 'clicked' },
  },
};

const Template = (args) => ({
  components: { MyButton },
  setup() {
    return { args };
  },
  template: '<MyButton v-bind="args" />',
});

export const Primary = Template.bind({});
Primary.args = {
  label: 'Primary Button',
  type: 'primary',
};

export const Secondary = Template.bind({});
Secondary.args = {
  label: 'Secondary Button',
  type: 'secondary',
};
```

このStoryファイルでは、
- `Primary`と`Secondary`という2つのバリエーション（ストーリー）を定義しています。
- `Controls`を使って、ボタンのラベルやタイプを画面上から動的に変更できるようにしています。
- クリックイベントは`Actions`でキャプチャし、Storybook上で確認できるようにしています。

### 4.3 Storybook上で確認

Storybookを起動してみましょう。

```
npm run storybook
```

ブラウザが立ち上がったら、左側のメニューに  
`Example / MyButton`  
が表示され、ボタンコンポーネントを動かせるようになっているはずです。

- `label`を変更して表示文字列を変える
- `type`を切り替えてスタイルを確認する
- ボタンクリック時にイベントが発火しているか確認する  

このように、Storybookを使うと**コンポーネント単体での動作確認**が非常に簡単になります。


## 便利なアドオン機能

Storybookには、標準機能に加えて開発をさらに効率化する**アドオン**が豊富に用意されています。  
ここでは、特に基本的で便利なアドオンを3つ紹介します。

### 5.1 Controlsアドオン

**Controls**アドオンを使うと、コンポーネントのProps（引数）をブラウザ上のUIから動的に変更できるようになります。

これにより、
- さまざまなパターンの動作確認
- テストケースに合わせた値変更が非常に簡単にできるようになります。

Controlsを使うためには、Storyファイルで`argTypes`を定義し、Propsに対するコントロール方法を指定します。

```
argTypes: {
  label: { control: 'text' },
  type: { 
    control: { type: 'select' },
    options: ['primary', 'secondary'],
  },
}
```

### 5.2 Actionsアドオン

**Actions**アドオンを使うと、コンポーネントが発火するイベント（クリック、変更など）をStorybook上でキャプチャできます。

例えばボタンのクリックイベントを監視して、Storybook上にログとして出力することができます。

```
argTypes: {
  onClick: { action: 'clicked' },
}
```

これにより、実際にイベントが発生しているかを、手軽に目視で確認できます。

### 5.3 Docsアドオン

**Docs**アドオンを使うと、コンポーネントごとのドキュメントを**自動生成**できます。  
たとえば、
- Propsの説明
- 使い方サンプル
- イベント一覧

などをきれいに整った形で表示してくれます。

設定を特に変更しなくても、基本的には`addon-docs`をインストールしておけば、Storyファイルに基づいたドキュメントが自動で生成されます。

開発者だけでなく、デザイナーやQAメンバーにもコンポーネント仕様を共有できるため、チーム開発にも非常に有効です。

---

このように、Storybookのアドオンを活用することで、  
**開発・レビュー・テスト**すべての効率をさらに高めることができます。

## Storybook活用のベストプラクティス

Storybookは単なる開発支援ツールにとどまらず、**開発フロー全体の品質向上**にも役立てることができます。  
この章では、実際のプロジェクトでStorybookを効果的に活用するためのベストプラクティスを紹介します。

### 6.1 開発フローにStorybookを組み込む

Storybookは、コンポーネント単体で動作確認できる特性を活かし、  
**開発初期からレビュー、テストに至るまで活用**するのが理想です。

例えば次のような使い方が効果的です。

- 新規コンポーネントを作成したら、必ずStoryも同時に作成する
- Pull Requestのレビュー時に、Storybook上で動作確認を行う
- UI変更が入った場合も、Story単位で比較・確認できるようにする

このように、**コンポーネント＝Storybookの管理対象**とすることで、  
開発スピードを維持しつつ、品質を高く保つことができます。

### 6.2 デザインレビューに活用する

Storybookは、開発者だけでなく、デザイナーやプロダクトオーナーとのコミュニケーションにも役立ちます。

- 実装中のコンポーネントをStorybookで共有し、デザインチェックを受ける
- デザイン仕様書代わりにStorybookを見てもらう
- デザイナーからの修正指示をその場で即確認できる

これにより、**手戻りを減らし、フィードバックサイクルを短縮**することが可能になります。

### 6.3 QA・テストにもStorybookを使う

Storybookは、QA（品質保証）プロセスにも活用できます。

- テストケースごとにStoryを作成しておき、目視確認を簡単にする
- クリックイベントや入力イベントをActionsで確認しながらテストする
- バグ報告の再現性確認にもStorybookを利用する

特に**コンポーネント単体で完結するテスト**はStorybookと非常に相性が良く、  
E2Eテストに比べて準備・確認のコストを大幅に減らすことができます。

---

このように、Storybookは単なる「プレビュー用ツール」ではなく、  
**開発・デザイン・QAすべてをつなぐ共通プラットフォーム**として活用することができます。

## Storybook8系での変更点まとめ

Storybookはバージョン8系に進化し、より使いやすく、より高速なツールへと生まれ変わりました。  
ここでは、7系から8系への主要な変更点を簡単にまとめます。

### 7.1 ビルドと実行速度の大幅な改善

Storybook8系では、ビルドと起動のパフォーマンスが大幅に向上しました。

- Viteベースでの起動が標準的に高速化
- Webpack環境でも最適化が進み、初回ビルド時間が短縮

これにより、開発中の待ち時間が減り、**フィードバックサイクルがさらに短く**なっています。

### 7.2 デフォルトでのモダンフレームワーク対応

Storybook8系では、最初からモダンフレームワーク（Vite、Next.js、SvelteKitなど）への対応がよりスムーズになりました。

- Vite用のStorybookテンプレートが標準サポート
- 新しいプロジェクト作成時に最適なフレームワークを自動検出

これにより、追加設定なしでも最新環境で快適にStorybookを使えるようになっています。

### 7.3 ドキュメントモードの改善

**Docsモード**も8系で大きく改善されました。

- 自動生成されるドキュメントがより見やすく
- 複数コンポーネントをまとめたドキュメント生成も簡単に
- ドキュメント用の独自コンポーネント（MDX2対応）が強化

これにより、**Storybook＝開発ドキュメント**という使い方がますます現実的になっています。

### 7.4 移行時に注意するポイント

7系から8系へ移行する際は、いくつか注意点があります。

- 一部アドオンのバージョン互換性が必要
- `main.js`や`preview.js`の設定オプション名が変わった箇所がある
- 古いプラグインや独自設定を使用している場合は、公式マイグレーションガイドの確認が必須

公式の[Migration Guide](https://storybook.js.org/migration-guides/8.0/)を参考にしながら、慎重にバージョンアップを進めましょう。

---

このように、Storybook8系は、  
**パフォーマンス・使い勝手・モダン環境対応**すべてが進化したバージョンです。  
これから新規導入する場合は、8系ベースで始めるのがおすすめです。

## Vite＋Storybookで失敗しやすい落とし穴集

Vite環境は高速かつシンプルな設定で人気ですが、  
Storybookと組み合わせる場合、いくつか**ハマりやすい落とし穴**があります。  
この章では、実際に起きやすいトラブルとその対策をまとめます。

### 8.1 モジュール解決エラーが発生する

#### 問題例
Storybook起動時に、次のようなエラーが出ることがあります。

```
Cannot find module '@/components/MyButton.vue'
```

これは、Viteのエイリアス設定（`@`など）がStorybook側に伝わっていないために起こる問題です。

#### 対策
`.storybook/main.js`に、`viteFinal`設定を追加してエイリアスを明示的に指定しましょう。

```
// .storybook/main.js
import { resolve } from 'path';

export default {
  framework: { name: '@storybook/vue3-vite' },
  stories: ['../src/**/*.stories.@(js|ts)'],
  addons: ['@storybook/addon-controls', '@storybook/addon-actions', '@storybook/addon-docs'],
  viteFinal: (config) => {
    config.resolve.alias = {
      ...config.resolve.alias,
      '@': resolve(__dirname, '../src'),
    };
    return config;
  },
};
```

### 8.2 静的アセットのパス問題

#### 問題例
- `public`フォルダの画像が表示されない
- CSSやフォントファイルの読み込みに失敗する

Viteでは、静的ファイルのパス解決が通常のビルドと異なる場合があります。

#### 対策
- 画像やフォントを読み込む場合は、絶対パス（例：`/images/sample.png`）を使う
- 必要に応じて、Vite側の設定をStorybookにも合わせる（静的ファイルコピー設定）

### 8.3 本番とは異なる挙動を見落とす

Storybookは開発モードの動作確認に最適ですが、  
本番環境のビルド結果と完全には一致しない場合があります。

たとえば、
- Tree Shakingによるコード削除
- 環境変数（`process.env.NODE_ENV`）による分岐
などはStorybook環境では適切に再現されない可能性があります。

#### 対策
- 本番ビルド時に動作確認するフローも別途用意しておく
- Storybookはあくまで開発補助ツールと位置づける

---

これらの落とし穴を事前に把握しておけば、  
**Vite＋Storybook環境でもストレスなく開発を進める**ことができます！

## まとめ

本記事では、Storybookの基本から、Vite環境への対応、便利なアドオン活用法、そして実践的なベストプラクティスまで幅広く紹介してきました。

改めてStorybookを導入するメリットをまとめると、次のようになります。

- コンポーネント単位での動作確認・レビューが圧倒的に簡単になる
- デザイナーやQAチームとの連携がスムーズになる
- 開発フローの効率化と品質向上が同時に実現できる
- Vite環境にも正しく対応すれば、ストレスなく開発を進められる

Storybookは、開発チームの「開発効率」と「成果物の品質」の両方を底上げしてくれる非常に強力なツールです。  
特にVue3＋Viteというモダンな構成との相性も良いので、ぜひ積極的に取り入れてみてください。

---

本記事では紹介できませんでしたが、続編として下記の投稿を検討中です。
- Storybookのアドオン機能をさらに使いこなす
- Visual Regression Test（ビジュアル差分テスト）と連携する
- Storybookでアクセシビリティチェック（a11y）を取り入れる

ここまで読んでいただきありがとうございました。
本記事が皆さまの理解の一助となれば幸いです。今後も引き続き、技術や知見を共有していきますので、ぜひ参考にしていただければと思います。