Storybookに入門したのでまとめた

はじめに

Storybookがどのようなものか知りたかったので触ってみました。コンポーネントの見た目の確認が楽なので、UIのボトムアップな開発には有益そうと感じました。

github.com

想定読者はReact何となくわかるくらいの方です*1

Storybook

Storybookとはコンポーネントの開発をサポートするツールです。コンポーネントごとに見た目の確認ができます。ReactやReact Native, Vue, Angular and Svelteなどに対応しています。

The Storybook Story

2016年の4月にKadiraというスリランカのスタートアップにより1.0がリリースされました。その後一度メンテがされなった期間を経てコミュニティ主導に復活したという面白いストーリーがあるようです(The Storybook Story)。

導入

npx -p @storybook/cli sb initで必要なパッケージやデフォルトの設定がされてStoryboxがアプリケーションに追加されます。yarn storybookで起動します。見た目は↓のような感じです。

f:id:gkuga:20200615001121p:plain

コンポーネント

コンポーネントは再利用できるGUIの部品です。Storybookではコンポーネントを作ったそばから見た目が確認できます。見た目の確認はVisual Testingというそうです*2

f:id:gkuga:20200615001211p:plain

コード例

例としてタスクリストのタスクのコードを載せます。

アプリケーション用コード

src/components/Task.js

import React from 'react';

export default function Task({ task: { id, title, state }, onArchiveTask, onPinTask }) {
  return (
    <div className="list-item">
      <input type="text" value={title} readOnly={true} />
    </div>
  );
}

Storybook用コード

Taskコンポーネントを読み込み、別々のモックデータを与えてexportしています。ここではデフォルト状態とピン状態とアーカイブ状態のTaskコンポーネントをexportしています。これらはStoryと呼ばれます。この仕組によりStorybookで状態が違うコンポーネントの見た目が確認ができます。

src/components/Task.stories.js

import React from 'react';
import { action } from '@storybook/addon-actions';

import Task from './Task';

export default {
  component: Task,
  title: 'Task',
  excludeStories: /.*Data$/,
};

export const taskData = {
  id: '1',
  title: 'Test Task',
  state: 'TASK_INBOX',
  updatedAt: new Date(2018, 0, 1, 9, 0),
};

export const actionsData = {
  onPinTask: action('onPinTask'),
  onArchiveTask: action('onArchiveTask'),
};

export const Default = () => <Task task={{ ...taskData }} {...actionsData} />;

export const Pinned = () => <Task task={{ ...taskData, state: 'TASK_PINNED' }} {...actionsData} />;

export const Archived = () => (
  <Task task={{ ...taskData, state: 'TASK_ARCHIVED' }} {...actionsData} />
);

Storybook

Storybookでみると、exportした状態の違うTaskコンポーネントが左側のバーで選択でき、見た目の違いがわかります。

デフォルト状態:

f:id:gkuga:20200615001317p:plain

ピン(星マークがついている)状態:

f:id:gkuga:20200615053410p:plain

アーカイブ状態:

f:id:gkuga:20200615053257p:plain

拡張 (Addon)

Storybookは拡張できるようになっています。公式の拡張をいくつか紹介します。

Actionsアドオン

クリックするとイベントが見れます。

f:id:gkuga:20200615001420p:plain

Knobsアドオン

モックデータをGUIから変更できます。

f:id:gkuga:20200615001440p:plain

StoryShotsアドオン

Snapshot Testingをするアドオンです。ストーリーごとにスナップショットが作られます。スナップショットとはコンポーネントに与えたインプットに対するアウトプット(レンダリングされたもの)です。画像を取るわけではなくレンダリング結果のHTMLを記録する感じです。Snapshot Testingは記録されている状態から変更があると自動で検知して表示します。例えばTaskコンポーネントの変更でアウトプットが変わると、元のスナップショットと比較されて変更部分が出力されます。Visual Testingでは目視でデグレを確認しますが、StoryShotsで変更部分が出力されるのでその部分だけ確認すれば効率的に確認ができます。

ユニットテスト

Storybookのモックデータを与えてexportするという形式はユニットテストと相性が良いです。ただ変更に脆くメンテナンスが大変なため、可能な限りVisual Test、Snapshot Test、Visual regression testを使うようにすると良いようです。

コンポーネント駆動開発

コンポーネント(部分)→ページへ(全体)という流れで開発する手法です。Storybookでよりやりやすいと思います。

Visual regression testing

Storybookでコンポーネントごとの見た目がわかるので、例えばプルリクエストを出した時に、PR前後の見た目の差分を見てデグレが起きてないかを確認できます。これをVisual regression testingと言います。この時の流れは次のようになります。

  • Storybookを立ち上げる
  • ヘッドレスブラウザでスクリーンショットを撮る
  • PR前後を画像で比較し差分を表示
  • レビュワーが確認

これをやってくれるツールにはreg-suitなどがあります。SaaS型にはChromaticがあります。

Storybookのデメリット

メンテナンスコストがかかることが大きそうです。

参考

この記事はLearn StorybookのIntro to Storybookをやってみたまとめでした。Storybookメンテナーの方が作っているようでわかりやすくありがたいです。

www.learnstorybook.com

おわりに

メンテナンスコストはかかりますが、継続的に改善するようなサイトでは信頼性を保てるし、Storybookでデザイナやプランナーともコミュニケーションできそうなので良いのではと思いました*3

*1:私です

*2:まんまですが

*3:フロントエンドを分離しているほとんどの企業ではだいたいもう既に使われているのでしょうか