作りっぱなしになっていたReactのコンポーネントをこの年末年始にStorybookの導入してCIも回した。
導入したコンポーネントライブラリはこちら
https://github.com/airtoxin/react-hex
https://github.com/airtoxin/react-triangle
導入
npm i -g getstorybook
getstorybook
以上。
プロジェクトのトップでgetstorybookコマンドを実行するとdependencyが追加されたりnpm scriptsが書き足されたりしてボイラープレートが追加されるので、その後
npm run storybook
してstoryを書き足してゆくだけ。
DecoratorとInfo addon
decorator addonはデフォルトで入っているstorybookのアドオンで、各storyで返すReact componentを包むみたいな事が出来る。
今回導入した2つのリポジトリはどちらもsvgの要素自体を返すので、表示するためにはsvgタグで包んでやる必要がありdecoratorを使って
storiesOf('Hex', module)
.addDecorator(story => (
<svg width="500" height="500">
{story()}
</svg>
))
.add(...)
みたいな事が出来ると、毎回storyの定義にsvgタグを書かずに済んでハッピーかなと思った。
一方のInfo addonはkadira公式が出している追加のアドオンで、それぞれのstory毎に注釈を追加したり、どのように描画されているのかコードを表示したり、PropTypesを見てそれをサマリー表示してくれたりする。
簡易APIリファレンスとして使えるようなやつ。
どちらも導入したかったが食合せが悪く、storyで開発者が返したコンポーネントにInfoが色々追加した後にデコレートが行われるようで、svgの中に不正なタグが含まれたりしてしまい上手く動かなかった。
現在githubにissueが立っているのでそのうち解決されるかもしれないが、直近でいじろうとしているなら注意したほうが良い。
スナップショットテスト
storybookはコンポーネントのショーケースなので、そのままスナップショットテストに使うことも出来る。
@kadira/storyshots
をインストールして
storyshots
コマンドを実行すると初回に現在のstorybookの状態をスナップショットとして保存し、2回目以降はそのスナップショットと現在のstorybookの状態とで差分が有るかをテストしてくれる。
真面目にやるならE2Eみたいなテストが必要なところだが、コンポーネントライブラリ程度でそれをやるのは大掛かり感が否めないのでこれくらいが手軽でちょうどよかった。
ただあくまで見た目のテストなのでイベントハンドリングが出来るかみたいな動作テストはenzymeなどでやる必要がある。
またCIで回すにあたって、storyのうちランダム性のあるものは seedrandom
ライブラリを使ってランダム値の生成をし、シード値には process.env.NODE_ENV
を使ってやるようにした。
テスト実行時に NODE_ENV=test storyshots
などとすればスナップショットテストの際はシード値が固定され毎回同じ結果が得られるので毎回差分に悩まされたりしない。
ちなみに実行自体はnodeで行われるのでbabelやwebpackなどで環境変数を埋め込んでやる必要はない。
Storybook Hub
ここまでテストが出来たらあとはCIで回すだけ。
せっかくstorybookがあるのでプルリクエストがあった時に現在のstorybookの状態をプレビュー出来ると嬉しい。
それが出来るのが Storybook Hub で、サインアップ後に言われるがままに設定するといつの間にかプルリクエストがある度にstorybookをビルドしてプレビューを公開してくれるようになる。 例
個人で公開リポジトリで使う分には無料で使えるらしいので設定しておいても損はない。
Github Pagesで公開
作ったstorybookはgithub pagesとして公開したい。
そんな時には @kadira/storybook-deployer
をインストールして
storybook-to-ghpages
を実行するだけ。
因みに現在のstorybookでは左上のロゴマークををライブラリのgithubへのリンクに変更するみたいな事はできないので、
https://github.com/Personare/react-storybook-decorator-github-corner
を導入してgithubへのリンクを追加するのが親切。
まとめ
storybookに関して、現状ではaddon apiの種類が少ないので好き勝手に拡張するみたいな自由性は無いが、動くサンプルとして公開する事や簡易APIリファレンスとして公開する事などはほぼ流れ作業で出来るようになっている。
内部で色々やっている感じはするがそんな事は意識せずに、開発者はただコンポーネントを返すようにstoryを書くだけで良いのが本当に楽。
導入のコストが低い割には得られる効果が高く、かなりよく出来ていると感じた。