Storybook + MSW を実プロジェクトに導入してわかった「地味に詰まる」ポイント集


お疲れ様です。SJC共同開発推進室の境田です。
今回は社内プロジェクトに StorybookMSW(Mock Service Workers) を導入した際の手順と、遭遇したエラーおよび対処法をまとめました。同様の構成(React 18, TypeScript, MUI, Vite など)で開発している方の参考になれば幸いです。


はじめに

React 18 / Vite / MUI / TypeScript ベースのプロジェクトにて、Storybook + MSW(Mock Service Workers)を導入した際の手順と、実際に遭遇したトラブル・落とし穴を整理しました。

単純に「動く Story を作る」だけでなく、既存システムの構造や型制約との整合を取るうえで重要だったポイントを共有します。


Storybook と MSW とは?

Storybook とは?

Storybook は、React コンポーネントなど UI コンポーネントを独立して開発・検証・ドキュメント化できる開発支援ツールです。アプリ全体を立ち上げなくても、個々の UI を単体で表示・テストできるのが大きなメリットです。

MSW(Mock Service Workers)とは?

MSW は、API 通信をモックするライブラリです。Service Worker を利用して、フロントエンド側からの HTTP リクエストに対して、任意のレスポンスを返せるようになります。実際の API を使わずにフロントエンドを開発・検証できる点が特長です。


なぜ導入したのか?

今回 Storybook と MSW を導入した背景は以下の通りです:

  • 開発中のバックエンド API が未実装でも、UI コンポーネントの動作確認やレビューを可能にしたい
  • 実際の API 仕様に基づいたモックで、UI の挙動・状態変化を事前に検証したい
  • フロントエンドエンジニア間でのデザインレビューや QA の効率化を図りたい

Storybook + MSW を使うことで、API レスポンスの制御が容易になり、さまざまな UI 状態を再現した Story の作成が可能になります。


前提環境

  • React: 18.2.0
  • TypeScript: 5.3.3
  • Vite
  • Material UI: @mui/material(v5)
  • TanStack Query
  • Storybook 7.x
  • WSL2 + Ubuntu(VSCode Remote)

Step 1: Storybook 初期化と依存エラーの対応

初期化コマンドで自動生成される設定には、プロジェクトによって依存関係の衝突や非対応エラーが発生することがあります。

主な依存関係トラブル

ライブラリ 問題 解決策
@material-ui/core@4.x React 18 に非対応 @mui/material(v5)に移行
@testing-library/react-hooks React 18 に非対応 削除し @testing-library/react に統合
react-apexcharts apexcharts バージョン不一致 apexcharts@^4.0.0 を手動指定

Step 2: Storybook + MSW を使って API をモック

以下は、Sample コンポーネントを MSW でモックした Story の一例です。

起動結果


ハマりポイント:data を返してないのに res.data.id に値が入っていた

一見、以下のような JSON を返しているはずの MSW モック:

にもかかわらず、アプリ側では res.data.id を参照していて、値が表示されないという事象に遭遇。

原因:fetcher 側で .data を抽出していた

共通 fetcher の実装に以下のようなロジックが入っており、MSW 側も data プロパティを含む必要があることが原因でした。

本番 API が data: {...} を返す仕様になっていたため、モックでもこの形式に合わせる必要があったのです。


解決策:Storybook 専用の fetcher を導入

MSW のレスポンスを本番に合わせて data を含めるのも一案ですが、Storybook 上だけ独自の fetcher を使うことで対応しました。

mockFetcher の導入例

Provider での切り替え

型との整合を保つためのヒント

Storybook 用の mockFetcher を導入する際、型の整合性を保つために ApiContext の型を以下のように調整しました:


その他の Tips

項目 内容
msw が動かない .storybook/preview.tsinitialize()mswLoader を記述する必要あり
コンフリクトアドオンの混在 @storybook/addon-interactionsexperimental-addon-test は共存不可
ルーターが必要な Storybook MemoryRouterinitialEntries を明示
TanStack Query が再利用できない QueryClient を Storybook 用に別管理し、キャッシュを切る

まとめ

トピック 学び・対応方法
Storybook 導入時の依存エラー MUI v5 への移行、react-hooks ライブラリの削除
MSW のレスポンス構造とアプリの期待の不一致 fetcher の仕様に合わせて data ラップを追加 or Storybook 専用 fetcher を導入
型の制約で data を使えない場合 mockFetcher 側で型の調整・context 経由で切り替え
Storybook アドオン競合 安定版の @storybook/addon-interactions のみ採用
WSL
権限エラー chown -R $(whoami):$(whoami) でプロジェクト所有者を変更

おわりに

Storybook の導入は見た目上はスムーズですが、既存の fetcher や型定義と整合性を取るには注意が必要です
また、MSW はただの「仮データ生成」ではなく、実 API と構造を揃えることで、安心・確実な UI 検証環境を構築できます。

今後、Storybook や MSW を導入する方の一助となれば幸いです!

最後まで閲覧ありがとうございます。
また、エコモットでは、ともに未来の常識を創る仲間を募集しています。
弊社に少しでも興味がある方はぜひ下記の採用ページをご覧ください!