Vue3 + Vite + Vuetify環境にStorybook8を導入

GMO メイクショップ コアグループでエンジニアをしている池田です。 今回はVue3 + Vite + Vuetifyという構成のプロジェクトにStorybook8を導入したので、そのことを記事にまとめてみました。

対象

  • Vue + Viteを使用していて、Storybookを新たに導入したい
  • Storybookがどんな感じか動かしてみたい

セットアップ

前提

対応しているバージョンは以下の通りです。

  • Vue ≥ 3
  • Vite ≥ 4.0

Storybookのセットアップ

npx storybook@latest init

こちらを実行するだけで大体の設定は完了しています。
いくつかのサンプルも作成されているので、使い方などもすぐに覚えることができます。

Storybookはコンポーネントプレビュー用のVueアプリケーションを作成します。
Vuetify, Vue Router, Pinia, i18nなどの利用している場合は以下のようにsetupを使用して、それらの設定を行う必要があります。
また、グローバルに読み込んでいるCSSがある場合はimportする必要があります。

+ import { setup } from '@storybook/vue3'

import type { Preview } from '@storybook/vue3'

+ import i18n from '../src/plugins/i18n'
+ import pinia from '../src/plugins/pinia'
+ import router from '../src/plugins/router'
+ import vuetify from '../src/plugins/vuetify'

+ import '../src/assets/scss/main.scss'

+ setup((app) => {
+   app.use(vuetify)
+  app.use(router)
+   app.use(pinia)
+   app.use(i18n)
+ })

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

export default preview

Storyファイル作成

1つStoryファイルを作成してみましょう。

import type { Meta, StoryObj } from '@storybook/vue3'

import PButton from '@/components/button/PButton.vue'

const meta = {
  title: 'components/button/PButton',
  component: PButton,
  tags: ['autodocs'],
  args: {
    label: 'Button',
  },
} satisfies Meta<typeof PButton>

export default meta
type Story = StoryObj<typeof meta>

export const Default: Story = {
  args: {
    label: 'Button',
  },
}

storybookを起動し、ブラウザで開いてみると、props, emit(events), slotの情報が表示されます。 これらの情報はtagにautodocsを付けるだけである程度自動生成可能です。

下記の画像を見ると分かるかと思いますが、iconというpropsには型定義上は決められた値しか入らないです。なので、セレクトボックスでiconを選択出来る方が良いです。

セレクトボックスを作成するコードを記述すると、セレクトボックスからpropsとして渡す値を選択可能になります。

// ...
+ import { customIcons } from '@/plugins/vuetify/customIcons'

const meta = {
  title: 'components/button/PButton',
  component: PButton,
  tags: ['autodocs'],
  args: {
    label: 'Button',
  },
+ argTypes: {
+   icon: {
+     options: Object.keys(customIcons.aliases || {}).map((icon) => `$${icon}`),
+   },
+ },
} satisfies Meta<typeof PButton>

// ...

こういったことを全てのコンポーネントで行うのは大変です。。。
ですが、vue-component-metaというプラグインを利用すれば解決します!

vue-component-metaでDocsの自動生成

まずは必要なライブラリをインストール

yarn add -D vue-component-meta

.storybook/main.tsでvue-component-metaをプラグインとして使用するように設定します。

import type { StorybookConfig } from '@storybook/vue3-vite'

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

ちなみにdocgenにはデフォルトでvue-docgen-apiが設定されているようです。

vue-component-meta is a tool maintained by the Vue team that extracts metadata from Vue components. Storybook can use it to generate the controls for your stories and documentation. It's a more full-featured alternative to vue-docgen-api and is recommended for most projects.

公式ドキュメントの方でも、vue-docgen-apiよりvue-component-metaの方が機能が充実しているのでおすすめと書いてあります。

storybook.js.org

// ...
- import { customIcons } from '@/plugins/vuetify/customIcons'

const meta = {
  title: 'components/button/PButton',
  component: PButton,
  tags: ['autodocs'],
  args: {
    label: 'Button',
  },
- argTypes: {
-   icon: {
-     options: Object.keys(customIcons.aliases || {}).map((icon) => `$${icon}`),
-   },
- },
} satisfies Meta<typeof PButton>

// ...

追加したセレクトボックス描画用のコードを削除し、再度起動してみると、このようにiconが選択可能になっているかつ、Descriptionの内容も変わっているし、colorもセレクトボックスになっています!

さらにpropsにJSDocとして記述した内容も自動で反映してれるのもvue-component-metaの恩恵です。

まとめ

Storybookを使うとコンポーネントの見た目をすぐに確認することが出来るし、propsの変化でどのように見た目が変化するかも簡単に確認可能となります。 Storybook8になり、Vite環境での導入がとても簡単になったので、まだ使っていないのであれば導入してみることをおすすめします!

補足:Storybook8の変更点

Storybook8は2024年3月13日に正式リリースされました。アップデート内容を少しだけ紹介します。

  • ビルトインのビジュアルテスト
  • ビルドが2〜4倍高速化
  • Vite5のサポート
  • 非ReactプロジェクトのReact依存性を削除

一番の目玉はビルトインのビジュアルテストで、@chromatic-com/storybook というアドオンが追加されました。

At the click of a button, you can test all your stories simultaneously, compare each one to previous versions, and pinpoint any visual changes. Then, filter your Storybook sidebar to only see stories containing visual differences and verify those changes one by one.

ワンクリックで全てのストーリーをテストして、視覚的な差分を検出できるということでかなり強力な機能ですね。

参考

storybook.js.org storybook.js.org