StorybookをReactアプリで使う!導入のメリットとセットアップの手順。

StorybookをReactアプリで使う!導入のメリットとセットアップの手順。

この記事では、フロントエンド開発に新しい波を巻き起こしているライブラリ「Storybook」についてその特徴やセットアップの手順などを説明する。

StorybookはReact・Angularなどのフレームワークで使用できるライブラリで世界中で導入する企業が増えてきている。

Storybookを使うとボタンなどのUIコンポーネントを独立したカタログのように扱うことができる。

それによって今まで煩わしかった開発者とプロダクトオーナーやデザイナーなどとのやり取りがスムーズにそしてより具体的に出来るようになる。

なお、著者は通常の業務ではAngularとともにStorybookを使用している。

Storybookとは?

公式サイト:: https://storybook.js.org
GitHub:: https://github.com/storybookjs/storybook

StorybookはReact・Angularを始めとした様々なフレームワークで使用できるUIコンポーネントのためのライブラリ。

Storybookを使えばインプットフィールドやボタンといったコンポーネントをカタログ化して一覧に表示することができる。

また、このカタログ上では、任意の設定したプロパティの変更により外見を変化させたり、ボタンを押した際のアクションなども確認できる。また、異なるカラーテーマや言語設定を用意して、Storybook上でそれらを切り替えて表示することも可能だ。

Storybook公式サイトより転用

Stortybookはデプロイしてひとつのウェブサイトのように使用できるので、プロドクトマネージャーといった非開発者も開発環境を用意することなく簡単にコンポーネントに内容をチェックできる。

そうした事からフロントエンド開発者とデザイナーの間でコンポーネントのデザインや挙動が意図したものと
なっているか確認するためにStorybookは使われる。

Storybookを使用した開発モデルは最近ではコンポ-ネント駆動型開発(Component-Driven Development)などとも呼ばれる。

Storybookを使うメリット

Storybookを導入するうえでのメリットを整理すると以下のようになる。

  • コンポーネントを素早く確認できる
  • アプリのデザインを統一しやすい
  • コンポーネントのカプセル化により再利用のしやすさ
  • 開発メンバーと非開発者の橋渡しになる
  • うまく設計すれば開発工数の短縮になる

Storybookを使うデメリット

次にStorybookを使うデメリットも知っておきたい。

  • 最初の段階では開発に時間が掛かる
  • ストーリーの管理コストが掛かる
  • 設計がまずいとコンポーネントが重くなる

ReactアプリでStorybookを使う

では、ReactアプリでStorybookを使用する手順を確認していこう。

なお、node.jsをインストールしていない人はあらかじめインストールしておこう。

プロジェクトを用意する

まずはStorybookを使用するReactのプロジェクトを用意する。

ここでは既存のプロジェクトを使用してもいいが、ちょうどいいプロジェクトが無い場合は以下のコマンドで新規に作成しよう。

npx create-react-app storybook-app

作成したらIDEでそのフォルダを開こう。

ここではVSCodeを使用する。

Storybookをインストールする

プロジェクトにStorybookをインストールしよう。

インストールは以下のコマンドを実行するだけだ。

npx -p @storybook/cli sb init

Storybookのインストールには数分掛かることもあるので気長に待つ。

インストールが完了したらStorybookを見てみよう。

以下のコマンドでStorybookを実行する。

npm run storybook

ビルドが完了すると自動でブラウザの新しいウィンドウにStorybookが表示されるはずだ。

コンポーネントを作成する

では、オリジナルのコンポーネントを作成していこう。

ここでは例として「MyButton」と名付けたオリジナルのボタンを作成する。

「src」フォルダの配下に「components」フォルダを作成して、その中に「my-button.js」と「my-button.css」を作成する。

my-button.jsにMyButtonコンポーネントを定義する。

import React from 'react';
import './my-button.css';

const MyButton = (props) => (
  <button onClick={props.onClick} style={props.style}>
    {props.label && <span>{props.label}</span>}
  </button>
);

export default MyButton;

my-button.cssにMyButtonのスタイルを定義する。プロパティは好みに合わせて変更してほしい。

button {
  padding: 10px;
  width: 12em;
  color: white;
  font-size: 14px;
  font-weight: bold;
  cursor: pointer;
  border: 3px solid #3f51b5;
  border-radius: 10px;
  background: #03a9f4;
}

ストーリーズを作成する

コンポーネントの作成が終わったらストーリー(stories)を作成する。

ストーリーとは?

「ストーリー」とはコンポーネントのタイプのようなもので、ひとつのコンポーネントに複数のストーリーを設定することができる。

ストーリーをまとめたTypeScriptファイルはstories.tsという拡張子を持つ。

「stories」の配下にあるファイルは「assets」フォルダを除いてすべて消去しよう。

その中に「my-button.stories.js」 を作成する。

my-button.stories.jsにストーリーを定義する。

ここでは、「Normal」「Abort」「Disabled」という3つのボタンの状態をストーリーとして設定した。

import React from 'react';
import { storiesOf } from '@storybook/react';

import MyButton from '../components/my-button';

storiesOf('MyButton', module)
  .add('Normal', () => <MyButton label="Normal Button" />)
  .add('Abort', () => (
    <MyButton
      label="Abort Button"
      style={{ background: 'red', border: '3px solid #e92c6c' }}
    />
  ))
  .add('Disabled', () => (
    <MyButton
      disabled
      label="Disabled Button"
      style={{
        background: 'lightgray',
        border: '3px solid #bbbbbb',
        cursor: 'not-allowed',
      }}
    />
  ));

ファイルをセーブすれば自動でStorybookが更新され、以下のようにストーリーを確認することができる。

Storybookをデプロイする

Storybookをは静的なウェブサイトとしてデプロイしてみよう。

デプロイをすればReactアプリをIDEからスタートせずとも、ブラウザー上でStorybookを閲覧することが可能となる。

Storybookをデプロイするために以下のコマンドを実行する。

npm run build-storybook

コマンドが終了するとプロジェクトのルートフォルダに「storybook-static」という新しいフォルダが作成される。

そのフォルダの中にあるindex.htmlをGoogle Chromeブラウザなど開けば、Storybookを通常のウェブサイト
のようにIDE無で表示することができる。

このファイルをサーバーなどにアップすればURLからStorybookを閲覧することができる。

Storybookを使ううえでの注意点

最後にStorybookを使ううえでの注意点を挙げておきたい。

Storybookは便利な反面、しっかりと考えて設計したうえである程度経験のある人が監督していないと一貫性が崩れやすい。

  • ボタンやインプットなどの基本コンポーネントはシンプルな状態を保つ
  • コンポーネントを拡張する際はアプリの他の箇所に影響が出ないよう気を付ける
  • CSSをオーバーライドするのが難しい場合はCSS変数を使う
  • プロパティが重複しないように気を付ける