microCMS

Storybookを使ってReactの開発をX倍早くしよう!!便利なアドオンの使い方を紹介

エンジニアリング
2020/03/23 かみむら

こんにちはかみむらです。
プロダクト開発で、デザイナーとフロントエンドエンジニアの円滑なコミュニケーションは必要不可欠です。
しかし、実際に開発を進める上で、円滑化する仕組み作りは悩ましい問題です。
そこでStorybookの紹介です。
これはコンポーネントをカタログ化して、管理できるツールです。カタログ化することで、双方の行き違いを限りなく少なくできます。

そして、FigmaやAdobe XDと連携できるなど、開発者とデザイナーの両方に嬉しい拡張機能もあります。

今回はReactにStorybookの導入と、基本的な使い方から便利なアドオン(拡張)を紹介していきます。

Storybookの公式サイト
https://storybook.js.org/

前提

create-react-appで作成したプロジェクトを想定しています。あらかじめプロジェクトを準備してください。

npx create-react-app my-app

検証時のバージョン

eact 16.13.0
react-dom 16.13.0
Storybook 5.3.17

セットアップ

まずは、プロジェクトで扱うための最低限のセットアップをしていきます。
Storybookが公式で出してるCLIを使えば、簡単に作成することができます。--typeでcreate-react-app用に設定してくれます。

npx -p @storybook/cli sb init --type react_scripts

例えば、Vueで使いたい場合は明示的に指定することもできます。

npx -p @storybook/cli sb init --type vue

実行が完了すると、package.jsonのscriptsにStorybookのコマンドが追加されています。

  • storybook- ローカルで開発サーバーを立ち上げることができます。
  • build-storybook - 作成したストーリーをビルドします。


そして、プロジェクトを見ると.storybookというフォルダが作成されました。その中のmain.jsを見てみます。

//.storybook/main.js
module.exports = {
 stories: ['../src/**/*.stories.js'],
 addons: [
  '@storybook/preset-create-react-app',
  '@storybook/addon-actions',
  '@storybook/addon-links',
 ],
};

storiessrcにあるすべての.stories.jsを対象にしています。
addonsはStorybookを拡張するものです。現在は3つのアドオンが登録されています。

では試しにStorybookの開発サーバーを立ち上げてみましょう。

$ yarn storybook


すると、WelcomeButtonの2つのストーリーが登録されています。ButtonのTextにあるコンポーネントをクリックすると、アドオンのActionsが実行されていることが確認できます。

ストーリーの書き方

ストーリーの書き方はComponent Story Format (CSF)StoriesOf APIで書く方法があります。
CSFはStorybook5.2から追加された比較的新しい書き方です。現在はこちらが推奨されています。
またaddon-docを使えば、MDXとして書くこともできます。

CSF(こちらを推奨)

CSFは、title、component、decorators、parametersでコンポーネントに関するメタデータを定義します。
titleはストーリーのディレクトリ名になります。
そして、ここではReactを返す関数がサブディレクトリ名になります。storiesOf APIに比べてシンプルに書けます。

//例 Button.stories.js
import Button from './Button';

export default {
 title: 'Button Component',
 component: Button,
 decorators: [ ... ],
 parameters: { ... }
}

export const Primary = () => <Button type="primary" />;
export const Secondary = () => <Button type="seconary" />;

Component Story Format (CSF)のドキュメント
https://storybook.js.org/docs/formats/component-story-format/

storiesOf API

将来的にCSFの書き方に統一されます。
しかし、storiesOf APIで紹介されてるケースがあるので説明します。
stories Ofはストーリーを追加するためのAPIです。
storiesOfでコンポーネントのディレクトリを定義、.addの呼び出しでサブディレクトリを定義してレンダリング可能なオブジェクト(ここではReact)を返します。

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

storiesOf('Button', module)
 .add('Primary', () => <Button type="primary" />)

storiesOf API
https://storybook.js.org/docs/formats/storiesof-api/

storiesOf APIからCDF記法に変換

storiesOf APIからCSF記法に変換するコマンドもあります。

npx -p @storybook/cli@next sb migrate <name-of-codemod> --glob="**/*.stories.js"

https://github.com/storybookjs/storybook/tree/next/lib/codemod

コンポーネントカタログを作る

ここからは、簡単なコンポーネントカタログを作ってみましょう。
Atomic Designのatoms(原子)を例にします。
Atomic DesignはReactでプロダクトを作る場合一度は検討を考えると思います。
特にAtomic Designの設計思想はコンポーネント志向のReactと相性がいいと感じます。

componentsの中にatomsを作ります。そして、ここではButtonコンポーネントを例にします。
propsにはonClickイベントとtextを渡す形になっています。

//components/atoms/Button.js
import React from 'react';

export const Button = ({onClick, text}) => (
  <button onClick={onClick}>{text}</button>
);

Buttonコンポーネントをストーリーに登録してみましょう。
atoms.stories.jsを作成します。

//components/atoms/atoms.stories.js
import React from 'react';
import {Button} from './Button';
import {action} from '@storybook/addon-actions';

export default {
  title: 'atoms'
};

export const Buttons = () => (
  <Button onClick={action('clicked')} text="Button" />
);

Storybookの開発サーバーを立ち上げるとコンポーネントのストーリーが登録されています。

アドオンの紹介

Storybookには豊富なアドオンがあります。これにより、Storybookの機能を拡張することができます。
こちらがアドオンの一部です。実際の開発で使える便利なアドオンをピックアップして紹介します。
https://storybook.js.org/addons/

viewport


これはStorybook上のレイアウトサイズを変更できるアドオンです。
作成したストーリーのレスポンシブサイズを確認したいときに便利です。
https://github.com/storybookjs/storybook/tree/master/addons/viewport
対応するライブラリをインストールします。

$ yarn add -D @storybook/addon-viewport

そして、main.jsのアドオンに追加しましょう。

module.exports = {
  //省略
  '@storybook/addon-viewport/register'
  //省略
 ],
};

previoew.jsを作成して、viewportの設定をします。

//.storybook/preview.js
import { addParameters } from '@storybook/react';
import { INITIAL_VIEWPORTS } from '@storybook/addon-viewport';

addParameters({
 viewport: {
  viewports: INITIAL_VIEWPORTS,
 },
});

これでStorybookを見てみましょう。デバイス毎にレイアウトを変えることができます。

storybook-addon-figma


こちらは、FigmaのデザインカンプをStorybook上で確認できるアドオンです。
Figmaの共有リンクをwithFigmaurlに渡すと、Storybook上でデザインを確認することができます。
そのほかにも、SketchやAdobe XDなどデザインツールに対応したアドオンがあります。
https://github.com/hharnisc/storybook-addon-figma
上記と同じく対応するライブラリをインストールして、アドオンを追加します。
そして、Buttonのストーリーに下記のコードを書きましょう。

//componenst/Button.stories.js
import React from 'react';
import {Button} from './Button';
import {WithFigma} from 'storybook-addon-figma';

export default {
 title: 'button',
 component: Button,
};

export const Primary = () => (
 <WithFigma url={'Figmaの共有リンクのURL'}>
  <Button text="Button" />
 </WithFigma>
);

実際にButtonのストーリーをみてみます。Figmaのデザインカンプと比較しながら開発することができます。

Knobs


最後にKnobsを紹介します。
これはStorybook上でPropsの値を変更できます。試しにButtonのtextのPropsを変更可能にしてみましょう。
https://github.com/storybookjs/storybook/tree/master/addons/knobs

import React from 'react';
import {Button} from './Button';
import {withKnobs, text, boolean, number} from '@storybook/addon-knobs';

export default {
 title: 'button',
 component: Button,
 decorators: [withKnobs],
};

export const Primary = () => <Button text={text('text', 'button')} />;

KnobsからPropsを変えることができます。textを変えてみましょう。

アドオンを3つほど紹介させていただきました。
そのほかにも便利なアドオンが多数あります。ぜひお試しください。

Netlifyで公開

ここまでで、アドオンを導入したストーリーを作成することができました。
実際にデザインシステムを作って共有する場合など、ホスティングサービスにデプロイします。

Netlifyの公式サイト
https://www.netlify.com/

Netlifyの記事はこちらにも書いています。一読してください。
Netlifyでステージング環境を用意する

GitHubにプロジェクトをプッシュ後、Netlifyのダッシュボードからデプロイ設定を行います。
Build commandにyarn build-storybook、Publish directoryにstorybook-staticを指定します。

デプロイが完了するとURLが発行されます。

おわりに

今回はStorybookを紹介しました。
最近はReactが採用されるケースが増えてきました。
コンポーネントを開発していく上で、Storybookは非常に強力です。これを機会にぜひ導入してみてください。

-----
microCMSは日々改善を進めています。
ご意見・ご要望は管理画面右下のチャット、公式Twitterメールからお気軽にご連絡ください!
引き続きmicroCMSをよろしくお願いいたします!

ABOUT ME

かみむら
フロントエンドエンジニア。テックブロガーでもあります。JAMstackアーキテクチャーやSPA(React、Vue)技術が好きです。