Upgrade to Pro — share decks privately, control downloads, hide ads and more …

最近の Storybook #vuefes_aftertalk

Avatar for Ryutaro Yako Ryutaro Yako
November 11, 2025
120

最近の Storybook #vuefes_aftertalk

2025年11月11日(火)に開催された「Vue Fes Japan 2025 After Talk」での発表資料です。

https://yappli.connpass.com/event/368396/

Avatar for Ryutaro Yako

Ryutaro Yako

November 11, 2025
Tweet

Transcript

  1. 自己紹介 Profile 名前: Ryutaro Yako 所属: ユニークビジョン株式会社 役割: エンジニア Experience

    チーム: 7 名のエンジニアが所属するチーム プロジェクト: 業務系 Web アプリ開発で Storybook 駆動を実践
  2. Vue Fes でお話したこと Storybook 駆動開発 Story を先に書いてから実装する開発手法 コンポーネントの見た目と振る舞いを事前に定 義 得られた効果

    1. 実装前の共通認識 2. 開発完了時の品質安定 3. 見積り通りの開発遂行 Story で期待値定義 その通りになるように実装
  3. 今日お話しすること Vue Fes で聞こえてきた声: Storybook よさそうだけど、Story 書くのつらそう... 最近 Storybook は実装者の負担を減らす方向に進化しています!

    型定義だけで Controls 生成が可能になった Vitest 統合でテストが書きやすく、実行しやすくなった バンドルサイズ削減で起動が速くなった 今日はこれら最近の改善点を紹介します! ターゲット: 最近あまり Storybook に触れていない人
  4. これまでの課題: Control の定義が大変 以前の Storybook の書き方のイメージ Control を定義したり整合性を合わせるのが手間 「どんな API

    だったっけ…?」ってなる Props の型と argTypes の整合性を保つ必要があ る (二重管理になりがち) const meta = { component: Example, argTypes: { value: { control: { type: 'number' }, }, isEnabled: { control: { type: 'boolean' }, }, size: { control: { type: 'radio' }, options: ['small', 'medium', 'large'], }, }, } satisfies Meta<typeof Example>;
  5. Control の自動生成 Storybook 8.0 多くのケースは自動生成だけで十分! boolean 型: トグルスイッチ Union 型:

    ラジオボタン … コンポーネントの型情報からの Control の自動生成が大幅に改善された ※ vue-docgen-api から vue-component-meta (Volar ベース)への移行により実現されている defineProps<{ value: number; isEnabled: boolean; size: 'small' | 'medium' | 'large'; }>();
  6. 応用: Story のひな型生成 VSCode でスニペット入力 → ほぼ完成!? story と入力 あとは微調整するだけ:

    args を指定する render 関数をカスタマイズする (必要な場合) インタラクションテストを追加する (必要な場合) { "storybook": { "scope": "typescript", "prefix": ["story"], "description": "Story 作成", "body": [ "import type { Meta, StoryObj } from '@storybook/vue3-vite';", "", "import ${TM_FILENAME/(.stories.ts)//} from './${TM_FILENAME/(.sto "", "const meta = {", " component: ${TM_FILENAME/(.stories.ts)//},", " render: (args) => ({", " components: { ${TM_FILENAME/(.stories.ts)//} },", " setup() {", " return { args };", " },", " template: `", " <${TM_FILENAME/(.stories.ts)//}", " v-bind=\"args\"",
  7. これまでの課題: モック作成が大変 コンポーザブル provide/inject でモックを差し込む仕組みを自作 柔軟だが、モック作成の手間がかかる Story ファイル render 関数内で

    provide する export function useDetectBrowser(): DeviceDetectContext { const mock = inject(MOCK_INJECTION_KEY, null) const isChrome = () => { return Bowser.parse(window.navigator.userAgent).browser.name === 'C } return { isChrome: mock?.isChrome ?? isChrome, } } export function provideMockDetectBrowser(mock: Partial<DeviceDetectConte provide(MOCK_INJECTION_KEY, mock) } const meta = { component: BrowserDetect, render: (args) => ({ components: { BrowserDetect }, setup() { provideMockDetectBrowser({ isChrome: () => args.isChrome, }) return { args } }, template: ` <BrowserDetect v-bind="args" /> `, }), } satisfies Meta<PropsAndCustomArgs>
  8. sb.mock API によるモック定義 Storybook 9.0 1. .storybook/preview.ts に事前準備(一度だけ) 2. Story

    ファイルで beforeEach 内にモック定義を書く モックを簡単に定義できる spy: true によって Story ごとにモック化しない選択も可能 Vitest ライクなモック定義が可能になった sb.mock(import('../src/composables/useDetectBrowser.ts'), { spy: true }) const meta = { component: BrowserDetect, beforeEach({ args }) { mocked(useDetectBrowser).mockReturnValue({ isChrome: () => args.isChrome, }) }, } satisfies Meta<PropsAndCustomArgs>
  9. これまでの課題: テスト実行環境 従来の Storybook テスト実行環境の選択肢 ブラウザで Story を開いて確認する ブラウザで 1

    つずつ開かないといけない CI で実行できない Story をサーブし、別プロセスで test-runner を起動する 安定した実行結果を得られないことがあった Chromatic でテストを実行する 従量課金でランニングコストがかかってしまった
  10. Vitest によるテスト実行 Storybook 8.3 CLI から実行できる Story ファイルを直接指定して実行可能 CI でも動かせる

    ※ Playwright のインストールが必要 Storybook の UI でも起動可能 Vitest の Browser Mode で Storybook の Story を直接テスト可能になった ※ experimental な機能として提供されていたが現在は安定化した npm run test:unit src/components/Example.stories.ts - name: Install Playwright run: npx playwright install --with-deps chromium - name: Run Storybook Tests run: npm run test:unit
  11. タグ機能の強化 タグによるフィルタリング UI 上でタグによる絞り込みが可能 テストのスキップ デフォルトでは !test のタグ指定でスキップ スキップ対象のタグを追加指定できる Storybook

    駆動開発では、未実装していないコ ンポーネントの Story をスキップするのに便利! Story のタグでテストのスキップや整理・分類が可能になった // vitest.config.ts plugins: [ storybookTest({ tags: { skip: ['todo'], }, }), ]
  12. Storybook 自体の軽量化 Before いろんな依存関係が含まれている (Reactが依存に含まれていたことも…) After Storybook 8 → 9

    でバンドルサイズ48% 削減 Storybook 10 では ESM-only 化された React 依存もない https://storybook.js.org/blog/storybook-is-going-esm-only/
  13. MCP サーバ(Storybook 公式) LLM が参照できる情報 コンポーネント一覧 Story の URL UI

    構築の標準ガイドライン 今後の発展に期待したいです...! Storybook 公式が提供する MCP サーバにより、LLM と Storybook の連携が少し可能になった
  14. まとめ Story 作成の負担を減らす機能が充実してきている! Control の自動生成 - 型定義だけで Control が生成され、手動設定が不要に モック定義の改善

    - Vitest ライクな sb.mock API で簡潔に記述可能 Vitest によるテスト実行 - CLI/CI で Story を直接テスト実行できるように タグ機能の強化 - Story の整理・分類やテストのスキップが容易に バンドルサイズ削減 - 48% の削減で起動が高速化 MCP によるドキュメント公開 - LLM との連携が可能に Storybook でフロントエンド開発を効率化しよう!