DEV Community

Takaya Kobayashi
Takaya Kobayashi

Posted on

Storybook Driven Development を試している

前々から気になっていた Storybook を試して、プロダクトでも採用してみたので所感を書く。

ちなみに、Next.js を使っているけれど、.babelrc の設定とかをやっていれば start-storybook-s ./ オプションで問題なく動いた。

動機

ここ数年、React を使って component ベースでウェブページを設計することを何度かやってきているが、未だにパスタコンポーネントが出来上がってしまう。そしてパスタコンポーネント群は往々にして開発がつらくなっていく...。

Storybook について

Storybook は動的にスタイルガイドを生成できるツールで、React だけではなく Vue や Angular にも対応しているよう。

@storybook/react をインストールして CLI から起動するだけでホットロードしてくれる画面が立ち上がって便利だった。

サンプルは https://storybook.js.org/examples/ でみれる。

アトミックデザインについて

(これが全てだろう)

(有名な図)

Storybook を書いていくときにある程度項目立てをしていった方がいいだろう、と考えた。そこで思い出したのが Atomic Design だった。昔、知った時は分類がややこしそうだと思ったが、一旦従ってみることにした。

開発フロー

まずは小物から Atom として Storybook に書いていく。状態によって変化するコンポーネントは状態を列挙して、Storybook 上で確認できるようにしていく。まずは Atom と Molecules たちが仕上がってくる。

各パーツが仕上がったら API とつなぎ込む必要がある Organisms など、動きをつけていく。ここで役に立つのが recompose である。

recompose について

recompose は Lodash ライクな React (特に HoC)向けのユーティリティベルト。

const enhance = withState('counter', 'setCounter', 0)
const Counter = enhance(({ counter, setCounter }) =>
  <div>
    Count: {counter}
    <button onClick={() => setCounter(n => n + 1)}>Increment</button>
    <button onClick={() => setCounter(n => n - 1)}>Decrement</button>
  </div>
)
Enter fullscreen mode Exit fullscreen mode

こんな感じで見た目を司るコンポーネントのみを切り出せるように様々な関数が用意されている。

例えば React の Lifecycle 関数だと

const PostsList = ({ posts }) => (
  <ul>{posts.map(p => <li>{p.title}</li>)}</ul>
)

const PostsListWithData = lifecycle({
  componentDidMount() {
    fetchPosts().then(posts => {
      this.setState({ posts });
    })
  }
})(PostsList);
Enter fullscreen mode Exit fullscreen mode

こんな感じで分離させることができる。

また、これらは compose 関数でこれらを組み合わせることもできる。

const enhance = compose(
  withState('counter', 'setCounter', 0),
  lifecycle({...})
)

enhance(Counter)
Enter fullscreen mode Exit fullscreen mode

ゆくゆくは enzyme を使って Storybook 上で挙動の確認などもできるとよいのだけど、一旦 Storybook ではスタイルガイドに徹することにして

export const Counter = ({...}) => (...)

const enhance = compose(...)

export default enhance(Counter)
Enter fullscreen mode Exit fullscreen mode

として、story では import {Counter} from '...' と読み込み、Pages からは import Counter from '...' と読み込むことで見た目のみのコンポーネントと、動き込みのコンポーネントに分けることができた。

見た目に関しては Storybook 上でパーフェクトに仕上がってるので、バチッと動くロジックを書けばうまいこと動くようになるので心地よかった。

今後の展望など

Storybook のドキュメントにも書いてある visual regression test をやってみたい。あとは、上にも少し書いた enzyme を使っての動きのテストなど。

まとめ

Atomic Design に従ったコンポーネント群を Storybook を使って見た目を仕上げてから、recompose を使って動きを足していく開発フローを導入してみている。

余談だけど、ざざっと Examples を見たら Wix の wix-style-react はものすごい使いやすいようにカスタムされていてすごかった...。オフィシャルに取り込んでほしいレベル。

Top comments (0)