Vite + Storybook v6 で props の説明(ArgsTable) を HMR したい

Vite
Viteフロントエンド

Vite + Storybook v6 の環境で Storybook の Docs を使ってコンポーネントの IF の仕様を書く方法です。やり方によってはできなかったので注意です。

バージョン

Storybook と Vite のバージョンは以下。

├── @storybook/addon-actions@6.5.14
├── @storybook/addon-essentials@6.5.14
├── @storybook/addon-interactions@6.5.14
├── @storybook/addon-links@6.5.14
├── @storybook/builder-vite@0.2.5
├── @storybook/react@6.5.14
├── @storybook/testing-library@0.0.13
└── vite@4.0.0

結論

原因まではわかっていませんが、動作としては以下でした。

  • TypeScript の型定義へのコメントだと HMR でも更新されない。
  • Storybook の argTypes に記載すると HMR が効く。

検証

npx storybook init で自動で作られるコンポーネント(Header.tsx / Header.stories.tsx)で確認。

NGパターン:TypeScript の型定義へのコメント

コンポーネントの props に相当する TypeScript の定義に適当なコメントを挿入します。

interface HeaderProps {
  /**
   * コメント。Description に表示される。
   */
  user?: User
  // コメント。この書き方だと表示されない。
  onLogin: () => boolean
  onLogout?: () => void
  onCreateAccount: () => void
}

export function Header({
  user,
  onLogin,
  onLogout,
  onCreateAccount,
  ...props
}: HeaderPropsHogeHoge) {
  return (
...

Storybook を起動すると Description に表示されます。

この状態でコメントの内容を書き換えても反映されません。
反映させるには Storybook の起動し直しが必要でした。

OKパターン:argTypes に記載

export default {
  title: 'Example/Header',
  component: Header,
  parameters: {
    layout: 'fullscreen',
  },
  argTypes: {
    user: {
      description: 'コメント。ここに書くと TypeScript の記述より優先される',
      // 
      // type: { required: true, name: 'other', value: 'User' },
    },
  },
} as ComponentMeta<typeof Header>

...

argTypes の内容が表示されています。

この状態で description を書き換えて保存すると、即時に画面に反映されました。

なお、argTypes は Storybook の公式 の通り、基本的には自動で推論してくれる(例えば、上の例だと user は型定義で ?: になっているので required は false になっている(*がついてない))ので、追加で制御したいところだけ書けばよさそうです。

型定義に test: string を追加し、argTypes は次のように書くと、

 argTypes: {
    ...
    test: {
      description: 'tes props',
      defaultValue: 'default value',
      table: {
        defaultValue: { summary: 'default value2' },
      },
    },
}

こんな感じで、Description と Control に対するデフォルト値、仕様としてのデフォルト値をそれぞれ定義することができ、かつ HMR が効きます。